-
Notifications
You must be signed in to change notification settings - Fork 860
feat: 给大部分直角图标变为圆角图标 #5554
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: 给大部分直角图标变为圆角图标 #5554
Changes from all commits
0595c10
bcf5eff
0c96b65
d23977b
e623510
7778ec3
cd0a834
ea4e9f4
92fbad3
4532a4e
228f221
66ec799
da5ab31
1429efb
e1a0248
aefdfc3
6a9289b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,163 @@ | ||||||||||||||||||||||||
| /* | ||||||||||||||||||||||||
| * Hello Minecraft! Launcher | ||||||||||||||||||||||||
| * Copyright (C) 2026 huangyuhui <huanghongxun2008@126.com> 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 <https://www.gnu.org/licenses/>. | ||||||||||||||||||||||||
| */ | ||||||||||||||||||||||||
| package org.jackhuang.hmcl.ui.construct; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| import javafx.beans.property.BooleanProperty; | ||||||||||||||||||||||||
| import javafx.beans.property.ObjectProperty; | ||||||||||||||||||||||||
| import javafx.css.CssMetaData; | ||||||||||||||||||||||||
| import javafx.css.Styleable; | ||||||||||||||||||||||||
| import javafx.css.StyleableDoubleProperty; | ||||||||||||||||||||||||
| import javafx.css.StyleableProperty; | ||||||||||||||||||||||||
| import javafx.css.converter.SizeConverter; | ||||||||||||||||||||||||
| import javafx.geometry.Pos; | ||||||||||||||||||||||||
| import javafx.scene.image.Image; | ||||||||||||||||||||||||
| import javafx.scene.image.ImageView; | ||||||||||||||||||||||||
| import javafx.scene.layout.StackPane; | ||||||||||||||||||||||||
| import javafx.scene.shape.Rectangle; | ||||||||||||||||||||||||
| import org.jackhuang.hmcl.ui.FXUtils; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| import java.util.ArrayList; | ||||||||||||||||||||||||
| import java.util.List; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| /// A custom ImageView with fixed size and corner radius support. | ||||||||||||||||||||||||
| public class ImageContainer extends StackPane { | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| private static final String DEFAULT_STYLE_CLASS = "image-container"; | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| private final ImageView imageView = new ImageView(); | ||||||||||||||||||||||||
| private final Rectangle clip = new Rectangle(); | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| public ImageContainer(double size) { | ||||||||||||||||||||||||
| this(size, size); | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| public ImageContainer(double width, double height) { | ||||||||||||||||||||||||
| this.getStyleClass().add(DEFAULT_STYLE_CLASS); | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| FXUtils.setLimitWidth(this, width); | ||||||||||||||||||||||||
| FXUtils.setLimitHeight(this, height); | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| imageView.setPreserveRatio(true); | ||||||||||||||||||||||||
| FXUtils.limitSize(imageView, width, height); | ||||||||||||||||||||||||
| StackPane.setAlignment(imageView, Pos.CENTER); | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| clip.setWidth(width); | ||||||||||||||||||||||||
| clip.setHeight(height); | ||||||||||||||||||||||||
| updateCornerRadius(getCornerRadius()); | ||||||||||||||||||||||||
| this.setClip(clip); | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| this.getChildren().setAll(imageView); | ||||||||||||||||||||||||
| } | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| private void updateCornerRadius(double radius) { | ||||||||||||||||||||||||
| clip.setArcWidth(radius); | ||||||||||||||||||||||||
| clip.setArcHeight(radius); | ||||||||||||||||||||||||
|
Comment on lines
+68
to
+69
|
||||||||||||||||||||||||
| clip.setArcWidth(radius); | |
| clip.setArcHeight(radius); | |
| clip.setArcWidth(radius * 2); | |
| clip.setArcHeight(radius * 2); |
Copilot
AI
Feb 23, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The naming of the "cornerRadius" property is misleading. In JavaFX's Rectangle, setArcWidth and setArcHeight set the full diameter of the arc used for rounded corners, not the radius. The property should be renamed to "cornerArcSize" or "cornerDiameter", or alternatively, the implementation should multiply the radius value by 2 when setting the arc width/height. Currently, a cornerRadius value of 6.0 creates a corner with an arc diameter of 6 pixels (radius 3 pixels), not a radius of 6 pixels.
| clip.setArcWidth(radius); | |
| clip.setArcHeight(radius); | |
| // JavaFX Rectangle#setArcWidth/Height expect the full diameter of the arc. | |
| // Interpret the cornerRadius value as a true radius by doubling it here. | |
| double diameter = radius * 2; | |
| clip.setArcWidth(diameter); | |
| clip.setArcHeight(diameter); |
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -28,7 +28,6 @@ | |||||||||||||||||||||||||||||
| import javafx.geometry.Pos; | ||||||||||||||||||||||||||||||
| import javafx.scene.control.Label; | ||||||||||||||||||||||||||||||
| import javafx.scene.image.Image; | ||||||||||||||||||||||||||||||
| import javafx.scene.image.ImageView; | ||||||||||||||||||||||||||||||
| import javafx.scene.layout.BorderPane; | ||||||||||||||||||||||||||||||
| import javafx.scene.layout.HBox; | ||||||||||||||||||||||||||||||
| import javafx.scene.layout.VBox; | ||||||||||||||||||||||||||||||
|
|
@@ -40,17 +39,16 @@ | |||||||||||||||||||||||||||||
| @DefaultProperty("image") | ||||||||||||||||||||||||||||||
| public final class ImagePickerItem extends BorderPane { | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| private final ImageView imageView; | ||||||||||||||||||||||||||||||
| private final ImageContainer imageContainer; | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| private final StringProperty title = new SimpleStringProperty(this, "title"); | ||||||||||||||||||||||||||||||
| private final ObjectProperty<EventHandler<ActionEvent>> onSelectButtonClicked = new SimpleObjectProperty<>(this, "onSelectButtonClicked"); | ||||||||||||||||||||||||||||||
| private final ObjectProperty<EventHandler<ActionEvent>> onDeleteButtonClicked = new SimpleObjectProperty<>(this, "onDeleteButtonClicked"); | ||||||||||||||||||||||||||||||
| private final ObjectProperty<Image> image = new SimpleObjectProperty<>(this, "image"); | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| public ImagePickerItem() { | ||||||||||||||||||||||||||||||
| imageView = new ImageView(); | ||||||||||||||||||||||||||||||
| imageView.setSmooth(false); | ||||||||||||||||||||||||||||||
| imageView.setPreserveRatio(true); | ||||||||||||||||||||||||||||||
| imageContainer = new ImageContainer(32); | ||||||||||||||||||||||||||||||
| imageContainer.setSmooth(false); | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| JFXButton selectButton = new JFXButton(); | ||||||||||||||||||||||||||||||
| selectButton.setGraphic(SVG.EDIT.createIcon(20)); | ||||||||||||||||||||||||||||||
|
|
@@ -66,7 +64,7 @@ public ImagePickerItem() { | |||||||||||||||||||||||||||||
| FXUtils.installFastTooltip(deleteButton, i18n("button.reset")); | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| HBox hBox = new HBox(); | ||||||||||||||||||||||||||||||
| hBox.getChildren().setAll(imageView, selectButton, deleteButton); | ||||||||||||||||||||||||||||||
| hBox.getChildren().setAll(imageContainer, selectButton, deleteButton); | ||||||||||||||||||||||||||||||
| hBox.setAlignment(Pos.CENTER_RIGHT); | ||||||||||||||||||||||||||||||
| hBox.setSpacing(8); | ||||||||||||||||||||||||||||||
| setRight(hBox); | ||||||||||||||||||||||||||||||
|
|
@@ -78,7 +76,7 @@ public ImagePickerItem() { | |||||||||||||||||||||||||||||
| vBox.setAlignment(Pos.CENTER_LEFT); | ||||||||||||||||||||||||||||||
| setLeft(vBox); | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| imageView.imageProperty().bind(image); | ||||||||||||||||||||||||||||||
| imageContainer.imageProperty().bind(image); | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||
| public String getTitle() { | ||||||||||||||||||||||||||||||
|
|
@@ -128,8 +126,4 @@ public ObjectProperty<Image> imageProperty() { | |||||||||||||||||||||||||||||
| public void setImage(Image image) { | ||||||||||||||||||||||||||||||
| this.image.set(image); | ||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
| } | |
| } | |
| /** | |
| * Returns the underlying image view/control. | |
| * | |
| * @deprecated This method exposes internal implementation details and will be removed | |
| * in a future release. Use {@link #imageProperty()}, {@link #getImage()}, | |
| * or {@link #setImage(Image)} instead. | |
| */ | |
| @Deprecated | |
| public ImageContainer getImageView() { | |
| return imageContainer; | |
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The public static method limitingSize(Node, double, double) has been removed from FXUtils. This is a breaking change for any external code or plugins that may have been using this utility method. The functionality has been replaced by the new ImageContainer class which provides better encapsulation and rounded corner support. Consider adding a deprecation notice in a previous release for smooth migration, or providing a migration guide.