Merge branch 'main' of https://github.com/gan-fang-yi/hyperpoint
This commit is contained in:
@@ -40,6 +40,7 @@ public class Controller implements Initializable {
|
||||
private DrawingCanvas drawingCanvas;
|
||||
private PropertyPanel propertyPanelComponent;
|
||||
private CommandHistory commandHistory;
|
||||
private ThemeManager themeManager;
|
||||
Stage stage;
|
||||
|
||||
@Override
|
||||
@@ -48,6 +49,13 @@ public class Controller implements Initializable {
|
||||
commandHistory = new CommandHistory();
|
||||
commandHistory.setOnHistoryChanged(this::updateUndoRedoButtons);
|
||||
|
||||
// 初始化主题管理器
|
||||
themeManager = ThemeManager.getInstance();
|
||||
themeManager.setOnThemeChanged(this::applyTheme);
|
||||
|
||||
// 应用初始主题
|
||||
applyTheme();
|
||||
|
||||
pageListView.setDisable(true);
|
||||
|
||||
// 添加页面列表选择监听
|
||||
@@ -680,4 +688,70 @@ public class Controller implements Initializable {
|
||||
alert.setContentText(message);
|
||||
alert.showAndWait();
|
||||
}
|
||||
|
||||
/**
|
||||
* 应用当前主题到界面
|
||||
*/
|
||||
private void applyTheme() {
|
||||
if (themeManager == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 应用菜单栏样式
|
||||
VBox menuBarBox = (VBox) scenePane.lookup("VBox");
|
||||
if (menuBarBox != null) {
|
||||
menuBarBox.setStyle(themeManager.getMenuBarStyle());
|
||||
}
|
||||
|
||||
// 应用主场景背景
|
||||
scenePane.setStyle(themeManager.getMainSceneStyle());
|
||||
}
|
||||
|
||||
/**
|
||||
* 浅色主题
|
||||
*/
|
||||
@FXML
|
||||
public void onThemeLight(ActionEvent actionEvent) {
|
||||
themeManager.switchTheme("Light");
|
||||
}
|
||||
|
||||
/**
|
||||
* 深色主题
|
||||
*/
|
||||
@FXML
|
||||
public void onThemeDark(ActionEvent actionEvent) {
|
||||
themeManager.switchTheme("Dark");
|
||||
}
|
||||
|
||||
/**
|
||||
* 蓝色主题
|
||||
*/
|
||||
@FXML
|
||||
public void onThemeBlue(ActionEvent actionEvent) {
|
||||
themeManager.switchTheme("Blue");
|
||||
}
|
||||
|
||||
/**
|
||||
* 绿色主题
|
||||
*/
|
||||
@FXML
|
||||
public void onThemeGreen(ActionEvent actionEvent) {
|
||||
themeManager.switchTheme("Green");
|
||||
}
|
||||
|
||||
/**
|
||||
* 紫色主题
|
||||
*/
|
||||
@FXML
|
||||
public void onThemePurple(ActionEvent actionEvent) {
|
||||
themeManager.switchTheme("Purple");
|
||||
}
|
||||
|
||||
/**
|
||||
* 橙色主题
|
||||
*/
|
||||
@FXML
|
||||
public void onThemeOrange(ActionEvent actionEvent) {
|
||||
themeManager.switchTheme("Orange");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
package dev.bytevibe.hyperpoint;
|
||||
|
||||
import javafx.scene.paint.Color;
|
||||
|
||||
/**
|
||||
* 主题管理器,管理应用的颜色和样式主题
|
||||
*/
|
||||
public class Theme {
|
||||
// 主题名称
|
||||
private String name;
|
||||
|
||||
// 背景颜色
|
||||
private Color backgroundColor;
|
||||
|
||||
// 菜单栏颜色
|
||||
private Color menuBarColor;
|
||||
|
||||
// 菜单栏文字颜色
|
||||
private Color menuTextColor;
|
||||
|
||||
// 页面背景颜色
|
||||
private Color pageBackgroundColor;
|
||||
|
||||
// 边框颜色
|
||||
private Color borderColor;
|
||||
|
||||
// 主色调(用于按钮、选中状态等)
|
||||
private Color primaryColor;
|
||||
|
||||
// 次色调
|
||||
private Color secondaryColor;
|
||||
|
||||
public Theme(String name, Color backgroundColor, Color menuBarColor, Color menuTextColor,
|
||||
Color pageBackgroundColor, Color borderColor, Color primaryColor, Color secondaryColor) {
|
||||
this.name = name;
|
||||
this.backgroundColor = backgroundColor;
|
||||
this.menuBarColor = menuBarColor;
|
||||
this.menuTextColor = menuTextColor;
|
||||
this.pageBackgroundColor = pageBackgroundColor;
|
||||
this.borderColor = borderColor;
|
||||
this.primaryColor = primaryColor;
|
||||
this.secondaryColor = secondaryColor;
|
||||
}
|
||||
|
||||
// Getters and Setters
|
||||
public String getName() { return name; }
|
||||
public void setName(String name) { this.name = name; }
|
||||
|
||||
public Color getBackgroundColor() { return backgroundColor; }
|
||||
public void setBackgroundColor(Color backgroundColor) { this.backgroundColor = backgroundColor; }
|
||||
|
||||
public Color getMenuBarColor() { return menuBarColor; }
|
||||
public void setMenuBarColor(Color menuBarColor) { this.menuBarColor = menuBarColor; }
|
||||
|
||||
public Color getMenuTextColor() { return menuTextColor; }
|
||||
public void setMenuTextColor(Color menuTextColor) { this.menuTextColor = menuTextColor; }
|
||||
|
||||
public Color getPageBackgroundColor() { return pageBackgroundColor; }
|
||||
public void setPageBackgroundColor(Color pageBackgroundColor) { this.pageBackgroundColor = pageBackgroundColor; }
|
||||
|
||||
public Color getBorderColor() { return borderColor; }
|
||||
public void setBorderColor(Color borderColor) { this.borderColor = borderColor; }
|
||||
|
||||
public Color getPrimaryColor() { return primaryColor; }
|
||||
public void setPrimaryColor(Color primaryColor) { this.primaryColor = primaryColor; }
|
||||
|
||||
public Color getSecondaryColor() { return secondaryColor; }
|
||||
public void setSecondaryColor(Color secondaryColor) { this.secondaryColor = secondaryColor; }
|
||||
|
||||
/**
|
||||
* 转换颜色为十六进制字符串
|
||||
*/
|
||||
public static String colorToHex(Color color) {
|
||||
return String.format("#%02X%02X%02X",
|
||||
(int) (color.getRed() * 255),
|
||||
(int) (color.getGreen() * 255),
|
||||
(int) (color.getBlue() * 255));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,193 @@
|
||||
package dev.bytevibe.hyperpoint;
|
||||
|
||||
import javafx.scene.paint.Color;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* 主题管理器,管理和切换应用主题
|
||||
*/
|
||||
public class ThemeManager {
|
||||
private static final ThemeManager instance = new ThemeManager();
|
||||
private Map<String, Theme> themes;
|
||||
private Theme currentTheme;
|
||||
private Runnable onThemeChanged;
|
||||
|
||||
private ThemeManager() {
|
||||
themes = new HashMap<>();
|
||||
initializeDefaultThemes();
|
||||
currentTheme = themes.get("Light");
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取单例实例
|
||||
*/
|
||||
public static ThemeManager getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化默认主题
|
||||
*/
|
||||
private void initializeDefaultThemes() {
|
||||
// 浅色主题
|
||||
themes.put("Light", new Theme(
|
||||
"Light",
|
||||
Color.web("#FFFFFF"), // 背景颜色 - 白色
|
||||
Color.web("#F5F5F5"), // 菜单栏颜色 - 浅灰
|
||||
Color.web("#333333"), // 菜单文字 - 深灰
|
||||
Color.web("#FFFFFF"), // 页面背景 - 白色
|
||||
Color.web("#CCCCCC"), // 边框色 - 浅灰
|
||||
Color.web("#007AFF"), // 主色调 - 蓝色
|
||||
Color.web("#E8E8E8") // 次色调 - 浅灰
|
||||
));
|
||||
|
||||
// 深色主题
|
||||
themes.put("Dark", new Theme(
|
||||
"Dark",
|
||||
Color.web("#2B2B2B"), // 背景颜色 - 深灰
|
||||
Color.web("#1E1E1E"), // 菜单栏颜色 - 更深灰
|
||||
Color.web("#E0E0E0"), // 菜单文字 - 浅灰
|
||||
Color.web("#333333"), // 页面背景 - 深灰
|
||||
Color.web("#444444"), // 边框色 - 中灰
|
||||
Color.web("#0A84FF"), // 主色调 - 亮蓝
|
||||
Color.web("#555555") // 次色调 - 中灰
|
||||
));
|
||||
|
||||
// 蓝色主题
|
||||
themes.put("Blue", new Theme(
|
||||
"Blue",
|
||||
Color.web("#E3F2FD"), // 背景颜色 - 浅蓝
|
||||
Color.web("#1976D2"), // 菜单栏颜色 - 蓝色
|
||||
Color.web("#FFFFFF"), // 菜单文字 - 白色
|
||||
Color.web("#FFFFFF"), // 页面背景 - 白色
|
||||
Color.web("#1976D2"), // 边框色 - 蓝色
|
||||
Color.web("#1976D2"), // 主色调 - 蓝色
|
||||
Color.web("#E3F2FD") // 次色调 - 浅蓝
|
||||
));
|
||||
|
||||
// 绿色主题
|
||||
themes.put("Green", new Theme(
|
||||
"Green",
|
||||
Color.web("#E8F5E9"), // 背景颜色 - 浅绿
|
||||
Color.web("#388E3C"), // 菜单栏颜色 - 绿色
|
||||
Color.web("#FFFFFF"), // 菜单文字 - 白色
|
||||
Color.web("#FFFFFF"), // 页面背景 - 白色
|
||||
Color.web("#388E3C"), // 边框色 - 绿色
|
||||
Color.web("#388E3C"), // 主色调 - 绿色
|
||||
Color.web("#E8F5E9") // 次色调 - 浅绿
|
||||
));
|
||||
|
||||
// 紫色主题
|
||||
themes.put("Purple", new Theme(
|
||||
"Purple",
|
||||
Color.web("#F3E5F5"), // 背景颜色 - 浅紫
|
||||
Color.web("#7B1FA2"), // 菜单栏颜色 - 紫色
|
||||
Color.web("#FFFFFF"), // 菜单文字 - 白色
|
||||
Color.web("#FFFFFF"), // 页面背景 - 白色
|
||||
Color.web("#7B1FA2"), // 边框色 - 紫色
|
||||
Color.web("#7B1FA2"), // 主色调 - 紫色
|
||||
Color.web("#F3E5F5") // 次色调 - 浅紫
|
||||
));
|
||||
|
||||
// 橙色主题
|
||||
themes.put("Orange", new Theme(
|
||||
"Orange",
|
||||
Color.web("#FFE0B2"), // 背景颜色 - 浅橙
|
||||
Color.web("#F57C00"), // 菜单栏颜色 - 橙色
|
||||
Color.web("#FFFFFF"), // 菜单文字 - 白色
|
||||
Color.web("#FFFFFF"), // 页面背景 - 白色
|
||||
Color.web("#F57C00"), // 边框色 - 橙色
|
||||
Color.web("#F57C00"), // 主色调 - 橙色
|
||||
Color.web("#FFE0B2") // 次色调 - 浅橙
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取主题列表
|
||||
*/
|
||||
public String[] getThemeNames() {
|
||||
return themes.keySet().toArray(new String[0]);
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取指定主题
|
||||
*/
|
||||
public Theme getTheme(String name) {
|
||||
return themes.get(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* 切换主题
|
||||
*/
|
||||
public void switchTheme(String themeName) {
|
||||
Theme theme = themes.get(themeName);
|
||||
if (theme != null) {
|
||||
currentTheme = theme;
|
||||
notifyThemeChanged();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前主题
|
||||
*/
|
||||
public Theme getCurrentTheme() {
|
||||
return currentTheme;
|
||||
}
|
||||
|
||||
/**
|
||||
* 设置主题变化回调
|
||||
*/
|
||||
public void setOnThemeChanged(Runnable callback) {
|
||||
this.onThemeChanged = callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* 通知主题已改变
|
||||
*/
|
||||
private void notifyThemeChanged() {
|
||||
if (onThemeChanged != null) {
|
||||
onThemeChanged.run();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成菜单栏样式字符串
|
||||
*/
|
||||
public String getMenuBarStyle() {
|
||||
Theme theme = getCurrentTheme();
|
||||
String bgColor = Theme.colorToHex(theme.getMenuBarColor());
|
||||
return String.format("-fx-background-color: %s; -fx-text-fill: %s;",
|
||||
bgColor, Theme.colorToHex(theme.getMenuTextColor()));
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成主场景样式字符串
|
||||
*/
|
||||
public String getMainSceneStyle() {
|
||||
Theme theme = getCurrentTheme();
|
||||
String bgColor = Theme.colorToHex(theme.getBackgroundColor());
|
||||
return String.format("-fx-background-color: %s;", bgColor);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成页面列表样式字符串
|
||||
*/
|
||||
public String getPageListStyle() {
|
||||
Theme theme = getCurrentTheme();
|
||||
String bgColor = Theme.colorToHex(theme.getPageBackgroundColor());
|
||||
String borderColor = Theme.colorToHex(theme.getBorderColor());
|
||||
return String.format("-fx-background-color: %s; -fx-border-color: %s; -fx-border-width: 0 1 0 0;",
|
||||
bgColor, borderColor);
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成页面编辑区样式字符串
|
||||
*/
|
||||
public String getPageEditStyle() {
|
||||
Theme theme = getCurrentTheme();
|
||||
String bgColor = Theme.colorToHex(theme.getBackgroundColor());
|
||||
return String.format("-fx-background-color: %s; -fx-padding: 10;", bgColor);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,6 +67,18 @@
|
||||
</items>
|
||||
</MenuButton>
|
||||
|
||||
<!-- 主题菜单 -->
|
||||
<MenuButton mnemonicParsing="false" text="主题">
|
||||
<items>
|
||||
<MenuItem mnemonicParsing="false" onAction="#onThemeLight" text="浅色主题" />
|
||||
<MenuItem mnemonicParsing="false" onAction="#onThemeDark" text="深色主题" />
|
||||
<MenuItem mnemonicParsing="false" onAction="#onThemeBlue" text="蓝色主题" />
|
||||
<MenuItem mnemonicParsing="false" onAction="#onThemeGreen" text="绿色主题" />
|
||||
<MenuItem mnemonicParsing="false" onAction="#onThemePurple" text="紫色主题" />
|
||||
<MenuItem mnemonicParsing="false" onAction="#onThemeOrange" text="橙色主题" />
|
||||
</items>
|
||||
</MenuButton>
|
||||
|
||||
<Label text=" | " />
|
||||
|
||||
<!-- 退出菜单 -->
|
||||
|
||||
Reference in New Issue
Block a user