Skip to content

Commit 552a13d

Browse files
committed
# Conflicts:
# HMCL/src/main/java/org/jackhuang/hmcl/ui/versions/ModUpdatesPage.java
1 parent c9c7ea5 commit 552a13d

File tree

73 files changed

+2379
-864
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

73 files changed

+2379
-864
lines changed

.github/workflows/check-update.yml

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,16 @@ jobs:
2323
runs-on: ubuntu-latest
2424
name: check-update-${{ matrix.channel }}
2525
steps:
26-
- uses: actions/checkout@v5
26+
- name: Checkout
27+
uses: actions/checkout@v6
28+
with:
29+
fetch-depth: 0
30+
fetch-tags: true
2731
- name: Set up JDK
2832
uses: actions/setup-java@v5
2933
with:
3034
distribution: 'temurin'
3135
java-version: '25'
32-
- name: Fetch tags
33-
run: git fetch --all --tags
3436
- name: Fetch last version
3537
run: ./gradlew ${{ matrix.task }} --no-daemon --info --stacktrace
3638
- name: Check for existing tags
@@ -44,8 +46,6 @@ jobs:
4446
wget "$HMCL_CI_DOWNLOAD_BASE_URI/HMCL-$HMCL_VERSION.jar.sha256"
4547
wget "$HMCL_CI_DOWNLOAD_BASE_URI/HMCL-$HMCL_VERSION.sh"
4648
wget "$HMCL_CI_DOWNLOAD_BASE_URI/HMCL-$HMCL_VERSION.sh.sha256"
47-
env:
48-
GH_DOWNLOAD_BASE_URL: https://github.com/HMCL-dev/HMCL/releases/download
4949
- name: Generate release note
5050
if: ${{ env.continue == 'true' }}
5151
run: |
@@ -63,17 +63,17 @@ jobs:
6363
echo "| [HMCL-$HMCL_VERSION.jar]($GH_DOWNLOAD_BASE_URL/v$HMCL_VERSION/HMCL-$HMCL_VERSION.jar) | \`$(cat HMCL-$HMCL_VERSION.jar.sha256)\` |" >> RELEASE_NOTE
6464
echo "| [HMCL-$HMCL_VERSION.sh]($GH_DOWNLOAD_BASE_URL/v$HMCL_VERSION/HMCL-$HMCL_VERSION.sh) | \`$(cat HMCL-$HMCL_VERSION.sh.sha256)\` |" >> RELEASE_NOTE
6565
env:
66-
GH_DOWNLOAD_BASE_URL: https://github.com/HMCL-dev/HMCL/releases/download
66+
GH_DOWNLOAD_BASE_URL: https://github.com/${{ github.repository }}/releases/download
6767
- name: Create release
6868
if: ${{ env.continue == 'true' }}
69-
uses: softprops/action-gh-release@v2
70-
with:
71-
body_path: RELEASE_NOTE
72-
files: |
73-
HMCL-${{ env.HMCL_VERSION }}.exe
74-
HMCL-${{ env.HMCL_VERSION }}.jar
75-
HMCL-${{ env.HMCL_VERSION }}.sh
76-
target_commitish: ${{ env.HMCL_COMMIT_SHA }}
77-
name: ${{ env.HMCL_TAG_NAME }}
78-
tag_name: ${{ env.HMCL_TAG_NAME }}
79-
prerelease: true
69+
run: |
70+
gh release create "${{ env.HMCL_TAG_NAME }}" \
71+
"HMCL-${{ env.HMCL_VERSION }}.exe" \
72+
"HMCL-${{ env.HMCL_VERSION }}.jar" \
73+
"HMCL-${{ env.HMCL_VERSION }}.sh" \
74+
--target "${{ env.HMCL_COMMIT_SHA }}" \
75+
--title "${{ env.HMCL_TAG_NAME }}" \
76+
--notes-file RELEASE_NOTE \
77+
--prerelease
78+
env:
79+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}

HMCL/build.gradle.kts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,11 +128,13 @@ val addOpens = listOf(
128128
"javafx.base/javafx.beans.property",
129129
"javafx.graphics/javafx.css",
130130
"javafx.graphics/javafx.stage",
131+
"javafx.graphics/com.sun.glass.ui",
131132
"javafx.graphics/com.sun.javafx.stage",
132133
"javafx.graphics/com.sun.javafx.util",
133134
"javafx.graphics/com.sun.prism",
134135
"javafx.controls/com.sun.javafx.scene.control",
135136
"javafx.controls/com.sun.javafx.scene.control.behavior",
137+
"javafx.graphics/com.sun.javafx.tk.quantum",
136138
"javafx.controls/javafx.scene.control.skin",
137139
"jdk.attach/sun.tools.attach",
138140
)

HMCL/src/main/java/com/jfoenix/skins/JFXColorPickerSkin.java

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@
2828
import javafx.animation.KeyFrame;
2929
import javafx.animation.KeyValue;
3030
import javafx.animation.Timeline;
31+
import javafx.beans.property.ObjectProperty;
32+
import javafx.beans.property.SimpleObjectProperty;
3133
import javafx.css.*;
3234
import javafx.css.converter.BooleanConverter;
3335
import javafx.geometry.Insets;
@@ -60,21 +62,26 @@ public final class JFXColorPickerSkin extends JFXGenericPickerSkin<Color> {
6062
"colorLabelVisible",
6163
true);
6264

65+
private final ObjectProperty<Color> textFill = new SimpleObjectProperty<>(Color.BLACK);
66+
private final ObjectProperty<Background> colorBoxBackground = new SimpleObjectProperty<>(null);
67+
6368
public JFXColorPickerSkin(final ColorPicker colorPicker) {
6469
super(colorPicker);
6570

6671
// create displayNode
6772
displayNode = new Label("");
6873
displayNode.getStyleClass().add("color-label");
6974
displayNode.setMouseTransparent(true);
75+
displayNode.textFillProperty().bind(textFill);
7076

7177
// label graphic
7278
colorBox = new JFXClippedPane(displayNode);
7379
colorBox.getStyleClass().add("color-box");
7480
colorBox.setManaged(false);
81+
colorBox.backgroundProperty().bind(colorBoxBackground);
7582
initColor();
7683
final JFXRippler rippler = new JFXRippler(colorBox, JFXRippler.RipplerMask.FIT);
77-
rippler.ripplerFillProperty().bind(displayNode.textFillProperty());
84+
rippler.ripplerFillProperty().bind(textFill);
7885
getChildren().setAll(rippler);
7986
JFXDepthManager.setDepth(getSkinnable(), 1);
8087
getSkinnable().setPickOnBounds(false);
@@ -168,13 +175,13 @@ private void updateColor() {
168175
200,
169176
Interpolator.EASE_BOTH)));
170177
animateColor.setOnFinished((finish) -> {
171-
JFXNodeUtils.updateBackground(colorBox.getBackground(), colorBox, colorCircle.getFill());
178+
colorBoxBackground.set(new Background(new BackgroundFill(colorCircle.getFill(), new CornerRadii(3), Insets.EMPTY)));
172179
colorBox.getChildren().remove(colorCircle);
173180
});
174181
animateColor.play();
175182
}
176183
// update label color
177-
displayNode.setTextFill(circleColor.grayscale().getRed() < 0.5 ? Color.valueOf(
184+
textFill.set(circleColor.grayscale().getRed() < 0.5 ? Color.valueOf(
178185
"rgba(255, 255, 255, 0.87)") : Color.valueOf("rgba(0, 0, 0, 0.87)"));
179186
if (colorLabelVisible.get()) {
180187
displayNode.setText(JFXNodeUtils.colorToHex(circleColor));
@@ -188,9 +195,9 @@ private void initColor() {
188195
Color color = colorPicker.getValue();
189196
Color circleColor = color == null ? Color.WHITE : color;
190197
// update picker box color
191-
colorBox.setBackground(new Background(new BackgroundFill(circleColor, new CornerRadii(3), Insets.EMPTY)));
198+
colorBoxBackground.set(new Background(new BackgroundFill(circleColor, new CornerRadii(3), Insets.EMPTY)));
192199
// update label color
193-
displayNode.setTextFill(circleColor.grayscale().getRed() < 0.5 ? Color.valueOf(
200+
textFill.set(circleColor.grayscale().getRed() < 0.5 ? Color.valueOf(
194201
"rgba(255, 255, 255, 0.87)") : Color.valueOf("rgba(0, 0, 0, 0.87)"));
195202
if (colorLabelVisible.get()) {
196203
displayNode.setText(JFXNodeUtils.colorToHex(circleColor));

HMCL/src/main/java/com/jfoenix/skins/JFXCustomColorPickerDialog.java

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,7 @@
3232
import javafx.event.EventHandler;
3333
import javafx.geometry.Insets;
3434
import javafx.geometry.Rectangle2D;
35-
import javafx.scene.Node;
3635
import javafx.scene.Scene;
37-
import javafx.scene.control.Label;
3836
import javafx.scene.control.Tab;
3937
import javafx.scene.input.KeyEvent;
4038
import javafx.scene.layout.*;
@@ -156,15 +154,15 @@ public JFXCustomColorPickerDialog(Window owner) {
156154
Color fontColor = ((Color) newVal.getFills().get(0).getFill()).grayscale()
157155
.getRed() > 0.5 ? Color.valueOf(
158156
"rgba(40, 40, 40, 0.87)") : Color.valueOf("rgba(255, 255, 255, 0.87)");
159-
for (Node tabNode : tabs.lookupAll(".tab")) {
160-
for (Node node : tabNode.lookupAll(".tab-label")) {
161-
((Label) node).setTextFill(fontColor);
162-
}
163-
for (Node node : tabNode.lookupAll(".jfx-rippler")) {
164-
((JFXRippler) node).setRipplerFill(fontColor);
165-
}
166-
}
167-
((Pane) tabs.lookup(".tab-selected-line")).setBackground(new Background(new BackgroundFill(fontColor, CornerRadii.EMPTY, Insets.EMPTY)));
157+
// for (Node tabNode : tabs.lookupAll(".tab")) {
158+
// for (Node node : tabNode.lookupAll(".tab-label")) {
159+
// ((Label) node).setTextFill(fontColor);
160+
// }
161+
// for (Node node : tabNode.lookupAll(".jfx-rippler")) {
162+
// ((JFXRippler) node).setRipplerFill(fontColor);
163+
// }
164+
// }
165+
// ((Pane) tabs.lookup(".tab-selected-line")).setBackground(new Background(new BackgroundFill(fontColor, CornerRadii.EMPTY, Insets.EMPTY)));
168166
pickerDecorator.lookupAll(".jfx-decorator-button").forEach(button -> {
169167
((JFXButton) button).setRipplerFill(fontColor);
170168
((SVGGlyph) ((JFXButton) button).getGraphic()).setFill(fontColor);

HMCL/src/main/java/org/jackhuang/hmcl/Launcher.java

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,13 @@
2020
import javafx.application.Application;
2121
import javafx.application.Platform;
2222
import javafx.beans.value.ObservableBooleanValue;
23+
import javafx.geometry.Rectangle2D;
2324
import javafx.scene.control.Alert;
2425
import javafx.scene.control.Alert.AlertType;
2526
import javafx.scene.control.ButtonType;
2627
import javafx.scene.input.Clipboard;
2728
import javafx.scene.input.DataFormat;
29+
import javafx.stage.Screen;
2830
import javafx.stage.Stage;
2931
import org.jackhuang.hmcl.setting.ConfigHolder;
3032
import org.jackhuang.hmcl.setting.SambaException;
@@ -54,6 +56,7 @@
5456
import java.nio.file.Files;
5557
import java.nio.file.Path;
5658
import java.nio.file.Paths;
59+
import java.text.DecimalFormat;
5760
import java.util.ArrayList;
5861
import java.util.Collections;
5962
import java.util.Objects;
@@ -79,6 +82,18 @@ public void start(Stage primaryStage) {
7982
LOG.info("Dark Mode: " + Optional.ofNullable(FXUtils.DARK_MODE).map(ObservableBooleanValue::get).orElse(false));
8083
LOG.info("Reduced Motion: " + Objects.requireNonNullElse(FXUtils.REDUCED_MOTION, false));
8184

85+
if (Screen.getScreens().isEmpty()) {
86+
LOG.info("No screen");
87+
} else {
88+
StringBuilder builder = new StringBuilder("Screens:");
89+
int count = 0;
90+
for (Screen screen : Screen.getScreens()) {
91+
builder.append("\n - Screen ").append(++count).append(": ");
92+
appendScreen(builder, screen);
93+
}
94+
LOG.info(builder.toString());
95+
}
96+
8297
try {
8398
try {
8499
ConfigHolder.init();
@@ -131,6 +146,38 @@ public void start(Stage primaryStage) {
131146
}
132147
}
133148

149+
private static void appendScreen(StringBuilder builder, Screen screen) {
150+
Rectangle2D bounds = screen.getBounds();
151+
double scale = screen.getOutputScaleX();
152+
153+
builder.append(Math.round(bounds.getWidth() * scale));
154+
builder.append('x');
155+
builder.append(Math.round(bounds.getHeight() * scale));
156+
157+
DecimalFormat decimalFormat = new DecimalFormat("#.##");
158+
159+
if (scale != 1.0) {
160+
builder.append(" @ ");
161+
builder.append(decimalFormat.format(scale));
162+
builder.append('x');
163+
}
164+
165+
double dpi = screen.getDpi();
166+
builder.append(' ');
167+
builder.append(decimalFormat.format(dpi));
168+
builder.append("dpi");
169+
170+
builder.append(" in ")
171+
.append(Math.round(Math.sqrt(bounds.getWidth() * bounds.getWidth() + bounds.getHeight() * bounds.getHeight()) / dpi))
172+
.append('"');
173+
174+
builder.append(" (").append(decimalFormat.format(bounds.getMinX()))
175+
.append(", ").append(decimalFormat.format(bounds.getMinY()))
176+
.append(", ").append(decimalFormat.format(bounds.getMaxX()))
177+
.append(", ").append(decimalFormat.format(bounds.getMaxY()))
178+
.append(")");
179+
}
180+
134181
private static ButtonType showAlert(AlertType alertType, String contentText, ButtonType... buttons) {
135182
return new Alert(alertType, contentText, buttons).showAndWait().orElse(null);
136183
}

HMCL/src/main/java/org/jackhuang/hmcl/game/HMCLGameRepository.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -338,7 +338,7 @@ else if (libraryAnalyzer.has(LibraryAnalyzer.LibraryType.OPTIFINE))
338338
GameVersionNumber versionNumber = GameVersionNumber.asGameVersion(gameVersion);
339339
if (versionNumber.isAprilFools()) {
340340
return VersionIconType.APRIL_FOOLS.getIcon();
341-
} else if (versionNumber instanceof GameVersionNumber.Snapshot) {
341+
} else if (versionNumber instanceof GameVersionNumber.LegacySnapshot) {
342342
return VersionIconType.COMMAND.getIcon();
343343
} else if (versionNumber instanceof GameVersionNumber.Old) {
344344
return VersionIconType.CRAFT_TABLE.getIcon();

HMCL/src/main/java/org/jackhuang/hmcl/setting/StyleSheets.java

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -47,19 +47,24 @@
4747
public final class StyleSheets {
4848
private static final int FONT_STYLE_SHEET_INDEX = 0;
4949
private static final int THEME_STYLE_SHEET_INDEX = 1;
50+
private static final int BRIGHTNESS_SHEET_INDEX = 2;
5051

5152
private static final ObservableList<String> stylesheets;
5253

5354
static {
5455
String[] array = new String[]{
5556
getFontStyleSheet(),
5657
getThemeStyleSheet(),
58+
getBrightnessStyleSheet(),
5759
"/assets/css/root.css"
5860
};
5961
stylesheets = FXCollections.observableList(Arrays.asList(array));
6062

6163
FontManager.fontProperty().addListener(o -> stylesheets.set(FONT_STYLE_SHEET_INDEX, getFontStyleSheet()));
62-
Themes.colorSchemeProperty().addListener(o -> stylesheets.set(THEME_STYLE_SHEET_INDEX, getThemeStyleSheet()));
64+
Themes.colorSchemeProperty().addListener(o -> {
65+
stylesheets.set(THEME_STYLE_SHEET_INDEX, getThemeStyleSheet());
66+
stylesheets.set(BRIGHTNESS_SHEET_INDEX, getBrightnessStyleSheet());
67+
});
6368
}
6469

6570
private static String toStyleSheetUri(String styleSheet, String fallback) {
@@ -131,6 +136,12 @@ else if (style.contains("bold"))
131136
return toStyleSheetUri(builder.toString(), defaultCss);
132137
}
133138

139+
private static String getBrightnessStyleSheet() {
140+
return Themes.getColorScheme().getBrightness() == Brightness.LIGHT
141+
? "/assets/css/brightness-light.css"
142+
: "/assets/css/brightness-dark.css";
143+
}
144+
134145
private static void addColor(StringBuilder builder, String name, Color color) {
135146
builder.append(" ").append(name)
136147
.append(": ").append(ThemeColor.getColorDisplayName(color)).append(";\n");
@@ -142,7 +153,7 @@ private static void addColor(StringBuilder builder, String name, Color color, do
142153
}
143154

144155
private static void addColor(StringBuilder builder, ColorScheme scheme, ColorRole role, double opacity) {
145-
builder.append(" ").append(role.getVariableName()).append("-transparent-").append((int) (100 * opacity))
156+
builder.append(" ").append(role.getVariableName()).append("-transparent-%02d".formatted((int) (100 * opacity)))
146157
.append(": ").append(ThemeColor.getColorDisplayNameWithOpacity(scheme.getColor(role), opacity))
147158
.append(";\n");
148159
}
@@ -170,13 +181,7 @@ private static String getThemeStyleSheet() {
170181
addColor(builder, scheme, ColorRole.ON_SURFACE_VARIANT, 0.38);
171182
addColor(builder, scheme, ColorRole.SURFACE_CONTAINER_LOW, 0.8);
172183
addColor(builder, scheme, ColorRole.SECONDARY_CONTAINER, 0.8);
173-
174-
// If we use -monet-error-container as the tag color, there may be a conflict between the tag and background colors on the mod management page
175-
if (scheme.getBrightness() == Brightness.LIGHT) {
176-
addColor(builder, "-warning-tag-background", Color.web("#f1aeb5"));
177-
} else {
178-
addColor(builder, "-warning-tag-background", Color.web("#2c0b0e"));
179-
}
184+
addColor(builder, scheme, ColorRole.INVERSE_SURFACE, 0.8);
180185

181186
builder.append("}\n");
182187
return toStyleSheetUri(builder.toString(), blueCss);

HMCL/src/main/java/org/jackhuang/hmcl/theme/Themes.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,16 @@ public static ColorScheme getColorScheme() {
113113
return colorScheme.get();
114114
}
115115

116+
private static final ObjectBinding<Color> titleFill = Bindings.createObjectBinding(
117+
() -> config().isTitleTransparent()
118+
? getColorScheme().getOnSurface()
119+
: getColorScheme().getOnPrimaryContainer(),
120+
colorSchemeProperty(),
121+
config().titleTransparentProperty()
122+
);
123+
116124
public static ObservableValue<Color> titleFillProperty() {
117-
return colorSchemeProperty().getOnPrimaryContainer();
125+
return titleFill;
118126
}
119127

120128
public static BooleanBinding darkModeProperty() {

HMCL/src/main/java/org/jackhuang/hmcl/ui/FXUtils.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1188,7 +1188,14 @@ public static Image newBuiltinImage(String url, double requestedWidth, double re
11881188

11891189
public static Task<Image> getRemoteImageTask(String url, int requestedWidth, int requestedHeight, boolean preserveRatio, boolean smooth) {
11901190
return new CacheFileTask(url)
1191-
.thenApplyAsync(file -> loadImage(file, requestedWidth, requestedHeight, preserveRatio, smooth));
1191+
.thenApplyAsync(file -> loadImage(file, requestedWidth, requestedHeight, preserveRatio, smooth))
1192+
.setSignificance(Task.TaskSignificance.MINOR);
1193+
}
1194+
1195+
public static Task<Image> getRemoteImageTask(URI uri, int requestedWidth, int requestedHeight, boolean preserveRatio, boolean smooth) {
1196+
return new CacheFileTask(uri)
1197+
.thenApplyAsync(file -> loadImage(file, requestedWidth, requestedHeight, preserveRatio, smooth))
1198+
.setSignificance(Task.TaskSignificance.MINOR);
11921199
}
11931200

11941201
public static ObservableValue<Image> newRemoteImage(String url, int requestedWidth, int requestedHeight, boolean preserveRatio, boolean smooth) {
@@ -1468,7 +1475,6 @@ public static List<Node> parseSegment(String segment, Consumer<String> hyperlink
14681475
hyperlinkAction.accept(link);
14691476
});
14701477
text.setCursor(Cursor.HAND);
1471-
text.setFill(Color.web("#0070E0"));
14721478
text.setUnderline(true);
14731479
texts.add(text);
14741480
} else if ("b".equals(element.getTagName())) {

HMCL/src/main/java/org/jackhuang/hmcl/ui/GameCrashWindow.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -292,7 +292,7 @@ private void exportGameCrashInfo() {
292292
private final class View extends VBox {
293293

294294
View() {
295-
setStyle("-fx-background-color: white");
295+
this.getStyleClass().add("game-crash-window");
296296

297297
HBox titlePane = new HBox();
298298
{
@@ -395,6 +395,7 @@ private final class View extends VBox {
395395
reasonTitle.getStyleClass().add("two-line-item-second-large-title");
396396

397397
ScrollPane reasonPane = new ScrollPane(reasonTextFlow);
398+
reasonTextFlow.getStyleClass().add("crash-reason-text-flow");
398399
reasonPane.setFitToWidth(true);
399400
reasonPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
400401
reasonPane.setVbarPolicy(ScrollPane.ScrollBarPolicy.AS_NEEDED);
@@ -411,6 +412,7 @@ private final class View extends VBox {
411412
}
412413

413414
HBox toolBar = new HBox();
415+
VBox.setMargin(toolBar, new Insets(0, 0, 4, 0));
414416
{
415417
JFXButton exportGameCrashInfoButton = FXUtils.newRaisedButton(i18n("logwindow.export_game_crash_logs"));
416418
exportGameCrashInfoButton.setOnAction(e -> exportGameCrashInfo());
@@ -422,7 +424,6 @@ private final class View extends VBox {
422424
helpButton.setOnAction(e -> FXUtils.openLink(Metadata.CONTACT_URL));
423425
FXUtils.installFastTooltip(helpButton, i18n("logwindow.help"));
424426

425-
426427
toolBar.setPadding(new Insets(8));
427428
toolBar.setSpacing(8);
428429
toolBar.getStyleClass().add("jfx-tool-bar");

0 commit comments

Comments
 (0)