-
Notifications
You must be signed in to change notification settings - Fork 866
feat: 添加实例列表右键编辑功能 (#6000) #6038
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
base: main
Are you sure you want to change the base?
Changes from all commits
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,48 @@ | ||
| /* | ||
| * Hello Minecraft! Launcher | ||
| * Copyright (C) 2020 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.profile; | ||
|
|
||
| import com.jfoenix.controls.JFXPopup; | ||
| import javafx.scene.Node; | ||
| import javafx.scene.layout.StackPane; | ||
| import org.jackhuang.hmcl.setting.Profile; | ||
| import org.jackhuang.hmcl.ui.Controllers; | ||
| import org.jackhuang.hmcl.ui.construct.IconedMenuItem; | ||
| import org.jackhuang.hmcl.ui.construct.PopupMenu; | ||
|
|
||
| import static org.jackhuang.hmcl.util.i18n.I18n.i18n; | ||
|
|
||
| /// Popup menu for ProfileListItem. | ||
| public final class ProfileListPopupMenu extends StackPane { | ||
|
|
||
| /// Shows the popup menu for the given profile item. | ||
| public static void show(Node owner, Profile profile) { | ||
| PopupMenu menu = new PopupMenu(); | ||
| JFXPopup popup = new JFXPopup(menu); | ||
| menu.getContent().add(new IconedMenuItem( | ||
| org.jackhuang.hmcl.ui.SVG.EDIT, | ||
| i18n("button.edit"), | ||
| () -> Controllers.navigate(new ProfilePage(profile)), | ||
| popup)); | ||
| popup.show(owner, JFXPopup.PopupVPosition.BOTTOM, JFXPopup.PopupHPosition.LEFT, 0, 0); | ||
| } | ||
|
|
||
| public ProfileListPopupMenu() { | ||
| getStyleClass().add("popup-menu-content"); | ||
| } | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -53,6 +53,8 @@ public final class ProfilePage extends BorderPane implements DecoratorPage { | |
| private final JFXTextField txtProfileName; | ||
| private final LineFileChooserButton gameDir; | ||
| private final LineToggleButton toggleUseRelativePath; | ||
| private ChangeListener<String> locationChangeListener; | ||
| private ChangeListener<String> txtProfileNameChangeListener; | ||
|
|
||
| /** | ||
| * @param profile null if creating a new profile. | ||
|
|
@@ -99,7 +101,9 @@ public ProfilePage(Profile profile) { | |
| @Override | ||
| protected void eval() { | ||
| JFXTextField control = (JFXTextField) this.getSrcControl(); | ||
| hasErrors.set(Profiles.getProfiles().stream().anyMatch(profile -> profile.getName().equals(control.getText()))); | ||
| hasErrors.set(Profiles.getProfiles().stream() | ||
| .filter(p -> p != profile) | ||
| .anyMatch(p -> p.getName().equals(control.getText()))); | ||
| } | ||
| }); | ||
| } | ||
|
|
@@ -144,7 +148,7 @@ protected void eval() { | |
| txtProfileName.textProperty(), location)); | ||
| } | ||
|
|
||
| ChangeListener<String> locationChangeListener = (observable, oldValue, newValue) -> { | ||
| locationChangeListener = (observable, oldValue, newValue) -> { | ||
| Path newPath; | ||
| try { | ||
| newPath = FileUtils.toAbsolute(Path.of(newValue)); | ||
|
|
@@ -166,18 +170,22 @@ protected void eval() { | |
| }; | ||
| locationProperty().addListener(locationChangeListener); | ||
|
|
||
| txtProfileName.textProperty().addListener(new ChangeListener<>() { | ||
| txtProfileNameChangeListener = new ChangeListener<>() { | ||
| @Override | ||
| public void changed(ObservableValue<? extends String> observable, String oldValue, String newValue) { | ||
| if (txtProfileName.isFocused()) { | ||
| txtProfileName.textProperty().removeListener(this); | ||
| locationProperty().removeListener(locationChangeListener); | ||
| } | ||
| } | ||
| }); | ||
| }; | ||
| txtProfileName.textProperty().addListener(txtProfileNameChangeListener); | ||
| } | ||
|
|
||
| private void onSave() { | ||
| locationProperty().removeListener(locationChangeListener); | ||
| txtProfileName.textProperty().removeListener(txtProfileNameChangeListener); | ||
|
|
||
| if (profile != null) { | ||
| profile.setName(txtProfileName.getText()); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 本审查建议由 GPT-5 生成 编辑现有实例时,名称输入框使用 |
||
| profile.setUseRelativePath(toggleUseRelativePath.isSelected()); | ||
|
|
||
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.
本审查建议由 GPT-5 生成
locationChangeListener仍然在编辑模式注册。右键编辑现有实例后,如果用户先把实例目录改到某个.../.minecraft路径,监听器会把名称输入框自动改成父目录名,保存时就会静默重命名实例。这和 PR 描述里的“路径变化后不再自动修改名称”不一致。建议只在profile == null的新建流程中启用这个自动命名监听器,或进入编辑模式时直接禁用它。