Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
9dfd5b5
feat: 优化世界信息页面
Mine-diamond Jan 12, 2026
1bd1e6c
feat: 添加饱食度信息项
Mine-diamond Jan 13, 2026
2271457
feat: 添加世界出生点信息项
Mine-diamond Jan 13, 2026
4efe86b
feat: 添加WorldRefreshable 接口
Mine-diamond Jan 13, 2026
7472ac9
Apply suggestions from code review
Mine-diamond Jan 13, 2026
3a10ccf
feat: 优化代码
Mine-diamond Jan 13, 2026
a7a62ca
feat: 优化代码
Mine-diamond Jan 13, 2026
0815175
feat: 优化代码,将生成启动脚本按钮移至管理菜单
Mine-diamond Jan 13, 2026
b110a16
feat: 优化代码,将添加Skin类
Mine-diamond Jan 14, 2026
df1df9a
feat: 优化代码
Mine-diamond Jan 14, 2026
46abde1
fix: 修复未正确解析玩家位置的bug
Mine-diamond Jan 14, 2026
bac1157
fix: 优化isReadOnly实现
Mine-diamond Jan 14, 2026
a9fc603
Merge branch 'main' into world-info
Mine-diamond Jan 14, 2026
9d52698
fix: 将WorldManagePage中的版本判断移动到World和ChunkBaseApp类中
Mine-diamond Jan 14, 2026
3961d49
fix: 修复bug
Mine-diamond Jan 14, 2026
6ce5c29
Merge branch 'main' into world-info
Mine-diamond Jan 14, 2026
210108b
fix: 修复主线的修改逻辑冲突
Mine-diamond Jan 14, 2026
0c14b1a
feat: 优化代码
Mine-diamond Jan 14, 2026
5cfccb3
feat: 优化世界名称更改
Mine-diamond Jan 14, 2026
82c423f
feat: 世界列表界面显示启动按钮
Mine-diamond Jan 15, 2026
6abb99d
feat: 优化getWorlds方法
Mine-diamond Jan 15, 2026
2af95d2
fix: 修复缩进问题
Mine-diamond Jan 15, 2026
5f0aff6
feat: update
Mine-diamond Jan 15, 2026
5fd9f82
feat: 部分id重命名为versionId
Mine-diamond Jan 15, 2026
f0ffb5b
Merge branch 'main' into world-info
Mine-diamond Jan 15, 2026
649202f
feat: 数据包页面在世界被占用时禁用一些功能
Mine-diamond Jan 15, 2026
8eab2ed
feat: update
Mine-diamond Jan 16, 2026
dc38668
feat: 优化代码
Mine-diamond Jan 19, 2026
18b3066
feat: 优化代码
Mine-diamond Jan 19, 2026
893abd9
feat: 世界列表界面启动按钮现在会检查世界锁定情况
Mine-diamond Jan 19, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
*/
package org.jackhuang.hmcl.ui.versions;

import javafx.beans.property.BooleanProperty;
import javafx.collections.ObservableList;
import javafx.scene.control.Skin;
import javafx.stage.FileChooser;
Expand All @@ -42,20 +43,27 @@
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
import static org.jackhuang.hmcl.util.logging.Logger.LOG;

public final class DatapackListPage extends ListPageBase<DatapackListPageSkin.DatapackInfoObject> {
public final class DatapackListPage extends ListPageBase<DatapackListPageSkin.DatapackInfoObject> implements WorldManagePage.WorldRefreshable {
private final Path worldDir;
private final Datapack datapack;
final BooleanProperty isReadOnlyProperty;

public DatapackListPage(WorldManagePage worldManagePage) {
this.worldDir = worldManagePage.getWorld().getFile();
datapack = new Datapack(worldDir.resolve("datapacks"));
setItems(MappedObservableList.create(datapack.getPacks(), DatapackListPageSkin.DatapackInfoObject::new));
isReadOnlyProperty = worldManagePage.readOnlyProperty();
FXUtils.applyDragListener(this, it -> Objects.equals("zip", FileUtils.getExtension(it)),
mods -> mods.forEach(this::installSingleDatapack), this::refresh);
this::installMutiDatapack, this::refresh);

refresh();
}

private void installMutiDatapack(List<Path> datapackPath) {
datapackPath.forEach(this::installSingleDatapack);
Controllers.showToast(i18n("datapack.reload.toast"));
}

private void installSingleDatapack(Path datapack) {
try {
this.datapack.installPack(datapack);
Expand Down Expand Up @@ -83,7 +91,7 @@ public void add() {
List<Path> res = FileUtils.toPaths(chooser.showOpenMultipleDialog(Controllers.getStage()));

if (res != null) {
res.forEach(this::installSingleDatapack);
installMutiDatapack(res);
}

datapack.loadFromDir();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
import java.util.stream.IntStream;
import java.util.stream.Stream;

import static org.jackhuang.hmcl.ui.ToolbarListPageSkin.createToolbarButton2;
import static org.jackhuang.hmcl.util.i18n.I18n.i18n;
Expand Down Expand Up @@ -114,16 +115,21 @@ final class DatapackListPageSkin extends SkinBase<DatapackListPage> {
createToolbarButton2(i18n("search"), SVG.SEARCH, () -> isSearching.set(true))
);

JFXButton removeButton = createToolbarButton2(i18n("button.remove"), SVG.DELETE, () -> {
Controllers.confirm(i18n("button.remove.confirm"), i18n("button.remove"), () -> {
skinnable.removeSelected(listView.getSelectionModel().getSelectedItems());
}, null);
});
JFXButton enableButton = createToolbarButton2(i18n("mods.enable"), SVG.CHECK, () ->
skinnable.enableSelected(listView.getSelectionModel().getSelectedItems()));
JFXButton disableButton = createToolbarButton2(i18n("mods.disable"), SVG.CLOSE, () ->
skinnable.disableSelected(listView.getSelectionModel().getSelectedItems()));
Stream.of(removeButton, enableButton, disableButton).forEach((button) -> button.disableProperty().bind(getSkinnable().isReadOnlyProperty));

selectingToolbar.getChildren().addAll(
createToolbarButton2(i18n("button.remove"), SVG.DELETE, () -> {
Controllers.confirm(i18n("button.remove.confirm"), i18n("button.remove"), () -> {
skinnable.removeSelected(listView.getSelectionModel().getSelectedItems());
}, null);
}),
createToolbarButton2(i18n("mods.enable"), SVG.CHECK, () ->
skinnable.enableSelected(listView.getSelectionModel().getSelectedItems())),
createToolbarButton2(i18n("mods.disable"), SVG.CLOSE, () ->
skinnable.disableSelected(listView.getSelectionModel().getSelectedItems())),
removeButton,
enableButton,
disableButton,
createToolbarButton2(i18n("button.select_all"), SVG.SELECT_ALL, () ->
listView.getSelectionModel().selectRange(0, listView.getItems().size())),//reason for not using selectAll() is that selectAll() first clears all selected then selects all, causing the toolbar to flicker
createToolbarButton2(i18n("button.cancel"), SVG.CANCEL, () ->
Expand Down Expand Up @@ -179,7 +185,7 @@ final class DatapackListPageSkin extends SkinBase<DatapackListPage> {
center.getStyleClass().add("large-spinner-pane");
center.loadingProperty().bind(skinnable.loadingProperty());

listView.setCellFactory(x -> new DatapackInfoListCell(listView));
listView.setCellFactory(x -> new DatapackInfoListCell(listView, getSkinnable().isReadOnlyProperty));
listView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
this.listView.setItems(filteredList);

Expand Down Expand Up @@ -302,7 +308,7 @@ private final class DatapackInfoListCell extends MDListCell<DatapackInfoObject>
final TwoLineListItem content = new TwoLineListItem();
BooleanProperty booleanProperty;

DatapackInfoListCell(JFXListView<DatapackInfoObject> listView) {
DatapackInfoListCell(JFXListView<DatapackInfoObject> listView, BooleanProperty isReadOnlyProperty) {
super(listView);

HBox container = new HBox(8);
Expand All @@ -312,6 +318,8 @@ private final class DatapackInfoListCell extends MDListCell<DatapackInfoObject>
content.setMouseTransparent(true);
setSelectable();

checkBox.disableProperty().bind(isReadOnlyProperty);

imageView.setFitWidth(32);
imageView.setFitHeight(32);
imageView.setPreserveRatio(true);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
package org.jackhuang.hmcl.ui.versions;

import com.jfoenix.controls.JFXButton;
import javafx.beans.property.BooleanProperty;
import javafx.collections.FXCollections;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
Expand Down Expand Up @@ -61,18 +62,18 @@
/**
* @author Glavo
*/
public final class WorldBackupsPage extends ListPageBase<WorldBackupsPage.BackupInfo> {
public final class WorldBackupsPage extends ListPageBase<WorldBackupsPage.BackupInfo> implements WorldManagePage.WorldRefreshable {
static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd_HH-mm-ss");

private final World world;
private final Path backupsDir;
private final boolean isReadOnly;
private final BooleanProperty readOnlyProperty;
private final Pattern backupFileNamePattern;

public WorldBackupsPage(WorldManagePage worldManagePage) {
this.world = worldManagePage.getWorld();
this.backupsDir = worldManagePage.getBackupsDir();
this.isReadOnly = worldManagePage.isReadOnly();
this.readOnlyProperty = worldManagePage.readOnlyProperty();
this.backupFileNamePattern = Pattern.compile("(?<datetime>[0-9]{4}-[0-9]{2}-[0-9]{2}_[0-9]{2}-[0-9]{2}-[0-9]{2})_" + Pattern.quote(world.getFileName()) + "( (?<count>[0-9]+))?\\.zip");

refresh();
Expand Down Expand Up @@ -164,7 +165,7 @@ private final class WorldBackupsPageSkin extends ToolbarListPageSkin<BackupInfo,
@Override
protected List<Node> initializeToolbar(WorldBackupsPage skinnable) {
JFXButton createBackup = createToolbarButton2(i18n("world.backup.create.new_one"), SVG.ARCHIVE, skinnable::createBackup);
createBackup.setDisable(isReadOnly);
createBackup.disableProperty().bind(getSkinnable().readOnlyProperty);

return Arrays.asList(
createToolbarButton2(i18n("button.refresh"), SVG.REFRESH, skinnable::refresh),
Expand Down
Loading