refactor: 精简主题模板为设置页主题二选一
去掉之前多余的6套模板配色(ocean/sunset/forest/mono等), 只保留一个清晰的二选一功能: - 动物岛风 (默认) — 当前 Animal Island 固定配色,不变 - 系统莫奈色 — 设置页 UI 使用系统 Monet 色系,与主面板一致 改动: - THEME_TEMPLATE → SETTINGS_THEME (animal/monet) - 删除 th_04_theme.js 的 getThemeTemplate/applyThemeTemplate - buildSettingsGroupPanelView 直接根据 SETTINGS_THEME 用 ui.colors 的 Monet 色构造 T 结构 - setPendingValue 中 SETTINGS_THEME 切换时重建设置页
This commit is contained in:
@@ -83,7 +83,7 @@ var ConfigValidator = {
|
||||
PANEL_PADDING_DP: { type: "int", min: 8, max: 32, default: 12 },
|
||||
|
||||
// 主题配置
|
||||
THEME_TEMPLATE: { type: "enum", values: ["system", "animal", "ocean", "sunset", "forest", "mono"], default: "system" },
|
||||
SETTINGS_THEME: { type: "enum", values: ["animal", "monet"], default: "animal" },
|
||||
THEME_MODE: { type: "enum", values: [0, 1, 2], default: 1 },
|
||||
THEME_ACCENT_LIGHT: { type: "string", default: "#FF3A86FF" },
|
||||
THEME_ACCENT_DARK: { type: "string", default: "#FF90CAF9" },
|
||||
@@ -755,7 +755,7 @@ var ConfigManager = {
|
||||
PANEL_LABEL_TOP_MARGIN_DP: 4,
|
||||
PANEL_BG_FALLBACK_HEX: "#EE1E1E1E",
|
||||
PANEL_BG_ALPHA: 0.85,
|
||||
THEME_TEMPLATE: "system",
|
||||
SETTINGS_THEME: "animal",
|
||||
THEME_MODE: 1,
|
||||
THEME_DAY_BG_HEX: null,
|
||||
THEME_DAY_TEXT_HEX: null,
|
||||
@@ -772,13 +772,9 @@ var ConfigManager = {
|
||||
],
|
||||
defaultSchema: [
|
||||
{ type: "section", name: "外观" },
|
||||
{ key: "THEME_TEMPLATE", name: "主题模板", type: "single_choice", options: [
|
||||
{ label: "系统莫奈色", value: "system" },
|
||||
{ label: "动物岛(绿)", value: "animal" },
|
||||
{ label: "海洋(蓝)", value: "ocean" },
|
||||
{ label: "日落(橙)", value: "sunset" },
|
||||
{ label: "森林(绿)", value: "forest" },
|
||||
{ label: "黑白(极简)", value: "mono" }
|
||||
{ key: "SETTINGS_THEME", name: "设置页主题", type: "single_choice", options: [
|
||||
{ label: "动物岛风", value: "animal" },
|
||||
{ label: "系统莫奈色", value: "monet" }
|
||||
]},
|
||||
{ key: "THEME_MODE", name: "主题(0跟随/1白/2黑)", type: "int", min: 0, max: 2, step: 1 },
|
||||
{ key: "THEME_DAY_BG_HEX", name: "日间背景色(#RRGGBB)", type: "text" },
|
||||
@@ -874,7 +870,7 @@ var ConfigManager = {
|
||||
var needReset = false;
|
||||
if (s) {
|
||||
var sStr = JSON.stringify(s);
|
||||
if (sStr.indexOf("ENABLE_SNAP_TO_EDGE") < 0 || sStr.indexOf("ENABLE_ANIMATIONS") < 0 || sStr.indexOf("BALL_IDLE_ALPHA") < 0 || sStr.indexOf("PANEL_POS_GRAVITY") < 0 || sStr.indexOf("single_choice") < 0 || sStr.indexOf("ball_shortx_icon") < 0 || sStr.indexOf("ball_color") < 0 || sStr.indexOf("THEME_TEMPLATE") < 0) {
|
||||
if (sStr.indexOf("ENABLE_SNAP_TO_EDGE") < 0 || sStr.indexOf("ENABLE_ANIMATIONS") < 0 || sStr.indexOf("BALL_IDLE_ALPHA") < 0 || sStr.indexOf("PANEL_POS_GRAVITY") < 0 || sStr.indexOf("single_choice") < 0 || sStr.indexOf("ball_shortx_icon") < 0 || sStr.indexOf("ball_color") < 0 || sStr.indexOf("SETTINGS_THEME") < 0) {
|
||||
needReset = true;
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -747,67 +747,14 @@ FloatBallAppWM.prototype.safeParseColor = function(hex, fallbackInt) {
|
||||
try { return android.graphics.Color.parseColor(String(hex)); } catch (e) { return fallbackInt; }
|
||||
};
|
||||
|
||||
// =======================【主题模板:一键切换配色预设】======================
|
||||
// 每个模板定义日间/夜间 背景+文字色。选择模板后如果用户没单独覆盖那4个颜色配置,
|
||||
// 就在 getPanelBgColorInt/getPanelTextColorInt 中自动填充模板值。
|
||||
FloatBallAppWM.prototype.getThemeTemplate = function(name) {
|
||||
var tplMap = {
|
||||
system: { dayBg: null, dayText: null, nightBg: null, nightText: null },
|
||||
animal: { dayBg: "#A8DDB4", dayText: "#5E472D", nightBg: "#2F4034", nightText: "#FFF1D2" },
|
||||
ocean: { dayBg: "#B3E5FC", dayText: "#1A237E", nightBg: "#1A237E", nightText: "#B3E5FC" },
|
||||
sunset: { dayBg: "#FFE0B2", dayText: "#4E342E", nightBg: "#3E2723", nightText: "#FFCCBC" },
|
||||
forest: { dayBg: "#C8E6C9", dayText: "#1B5E20", nightBg: "#1B5E20", nightText: "#C8E6C9" },
|
||||
mono: { dayBg: "#F5F5F5", dayText: "#212121", nightBg: "#212121", nightText: "#F5F5F5" }
|
||||
};
|
||||
return tplMap[name] || tplMap.system;
|
||||
};
|
||||
|
||||
// 应用主题模板:如果选择非 system 模板且那4个颜色未手动覆盖,用模板值填充。
|
||||
// preview=true 时从 pendingUserCfg 读/写(预览态),否则从 this.config 读/写。
|
||||
FloatBallAppWM.prototype.applyThemeTemplate = function(preview) {
|
||||
try {
|
||||
var cfg = preview && this.state.pendingUserCfg ? this.state.pendingUserCfg : this.config;
|
||||
var tpl = String(cfg.THEME_TEMPLATE || "system");
|
||||
if (tpl === "system") return; // system 走 Monet,不填充
|
||||
|
||||
var t = this.getThemeTemplate(tpl);
|
||||
var _isNull = function(v) { return v == null || String(v) === "" || String(v) === "null"; };
|
||||
|
||||
if (t.dayBg != null && _isNull(cfg.THEME_DAY_BG_HEX)) {
|
||||
cfg.THEME_DAY_BG_HEX = String(t.dayBg);
|
||||
}
|
||||
if (t.dayText != null && _isNull(cfg.THEME_DAY_TEXT_HEX)) {
|
||||
cfg.THEME_DAY_TEXT_HEX = String(t.dayText);
|
||||
}
|
||||
if (t.nightBg != null && _isNull(cfg.THEME_NIGHT_BG_HEX)) {
|
||||
cfg.THEME_NIGHT_BG_HEX = String(t.nightBg);
|
||||
}
|
||||
if (t.nightText != null && _isNull(cfg.THEME_NIGHT_TEXT_HEX)) {
|
||||
cfg.THEME_NIGHT_TEXT_HEX = String(t.nightText);
|
||||
}
|
||||
|
||||
try { _th_log(this.L, "d", "[theme:template] applied " + tpl + " dayBg=" + String(t.dayBg) + " preview=" + !!preview); } catch(eL) {}
|
||||
} catch(e) {
|
||||
try { _th_log(this.L, "e", "[theme:template] apply err=" + String(e)); } catch(eL2) {}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
FloatBallAppWM.prototype.getPanelBgColorInt = function() {
|
||||
// 这段代码的主要内容/用途:配合"白天/夜晚"两档主题,返回统一的背景颜色(不再依赖自动亮度推断)。
|
||||
|
||||
// 应用主题模板(如果选择模板且用户未手动覆盖)
|
||||
// 预览态从 pendingUserCfg 读模板值并填充 pendingUserCfg 的颜色字段
|
||||
var inPreview = this.state.pendingUserCfg != null;
|
||||
try { this.applyThemeTemplate(inPreview); } catch(eAT) {}
|
||||
|
||||
var isDark = this.isDarkTheme();
|
||||
|
||||
// 预览态优先从 pendingUserCfg 读颜色值
|
||||
var cfg = inPreview && this.state.pendingUserCfg ? this.state.pendingUserCfg : this.config;
|
||||
var dayBgHex = (cfg.THEME_DAY_BG_HEX != null) ? String(cfg.THEME_DAY_BG_HEX) : null;
|
||||
var nightBgHex = (cfg.THEME_NIGHT_BG_HEX != null) ? String(cfg.THEME_NIGHT_BG_HEX) : null;
|
||||
var dayBgHex = (this.config.THEME_DAY_BG_HEX != null) ? String(this.config.THEME_DAY_BG_HEX) : null;
|
||||
var nightBgHex = (this.config.THEME_NIGHT_BG_HEX != null) ? String(this.config.THEME_NIGHT_BG_HEX) : null;
|
||||
|
||||
// # 兼容旧版默认配色:若仍为旧默认值,自动回退到莫奈色
|
||||
if (dayBgHex === "#FAF4E3") dayBgHex = null;
|
||||
@@ -835,18 +782,10 @@ FloatBallAppWM.prototype.getPanelBgColorInt = function() {
|
||||
|
||||
FloatBallAppWM.prototype.getPanelTextColorInt = function(bgInt) {
|
||||
// 这段代码的主要内容/用途:配合"白天/夜晚"两档主题,返回统一的文字颜色(不再依赖自动亮度推断)。
|
||||
|
||||
// 应用主题模板(如果选择模板且用户未手动覆盖)
|
||||
// 预览态从 pendingUserCfg 读模板值并填充 pendingUserCfg 的颜色字段
|
||||
var inPreviewText = this.state.pendingUserCfg != null;
|
||||
try { this.applyThemeTemplate(inPreviewText); } catch(eAT) {}
|
||||
|
||||
var isDark = this.isDarkTheme();
|
||||
|
||||
// 预览态优先从 pendingUserCfg 读颜色值
|
||||
var cfgT = inPreviewText && this.state.pendingUserCfg ? this.state.pendingUserCfg : this.config;
|
||||
var dayTextHex = (cfgT.THEME_DAY_TEXT_HEX != null) ? String(cfgT.THEME_DAY_TEXT_HEX) : null;
|
||||
var nightTextHex = (cfgT.THEME_NIGHT_TEXT_HEX != null) ? String(cfgT.THEME_NIGHT_TEXT_HEX) : null;
|
||||
var dayTextHex = (this.config.THEME_DAY_TEXT_HEX != null) ? String(this.config.THEME_DAY_TEXT_HEX) : null;
|
||||
var nightTextHex = (this.config.THEME_NIGHT_TEXT_HEX != null) ? String(this.config.THEME_NIGHT_TEXT_HEX) : null;
|
||||
|
||||
// # 兼容旧版默认配色:若仍为旧默认值,自动回退到莫奈色
|
||||
if (dayTextHex === "#333333") dayTextHex = null;
|
||||
|
||||
@@ -154,8 +154,8 @@ FloatBallAppWM.prototype.setPendingValue = function(k, v) {
|
||||
this.state.pendingUserCfg[k] = v;
|
||||
this.state.pendingDirty = true;
|
||||
if (this.state.previewMode) {
|
||||
// 主题模板切换需要重建整个设置页 UI(配色来自 buildSettingsGroupPanelView)
|
||||
if (String(k) === "THEME_TEMPLATE") {
|
||||
// 设置页主题切换需要重建整个设置页 UI(配色来自 buildSettingsGroupPanelView)
|
||||
if (String(k) === "SETTINGS_THEME") {
|
||||
try {
|
||||
if (this.state.toolAppActive && this.replaceToolAppPage) {
|
||||
this.replaceToolAppPage("settings_group");
|
||||
|
||||
@@ -257,54 +257,30 @@ FloatBallAppWM.prototype.buildSettingsGroupPanelView = function() {
|
||||
var C = this.ui.colors;
|
||||
var T = this.getAnimalIslandTheme();
|
||||
|
||||
// 如果用户选择了非 system 的主题模板,根据模板颜色构造设置页配色替代 Animal Island
|
||||
// 优先从 pendingUserCfg 读模板值(预览态),其次从 this.config
|
||||
// 设置页主题切换:animal(默认动物岛风)或 monet(系统莫奈色)
|
||||
var cfgTpl = this.state.pendingUserCfg ? this.state.pendingUserCfg : this.config;
|
||||
var tpl = String(cfgTpl.THEME_TEMPLATE || "system");
|
||||
if (tpl !== "system") {
|
||||
var settTheme = String(cfgTpl.SETTINGS_THEME || "animal");
|
||||
if (settTheme === "monet") {
|
||||
try {
|
||||
var tplColors = this.getThemeTemplate(tpl);
|
||||
var Color = android.graphics.Color;
|
||||
var dayBg = tplColors.dayBg ? android.graphics.Color.parseColor(tplColors.dayBg) : null;
|
||||
var dayText = tplColors.dayText ? android.graphics.Color.parseColor(tplColors.dayText) : null;
|
||||
var nightBg = tplColors.nightBg ? android.graphics.Color.parseColor(tplColors.nightBg) : null;
|
||||
var nightText = tplColors.nightText ? android.graphics.Color.parseColor(tplColors.nightText) : null;
|
||||
var bg = isDark ? (nightBg || T.bg) : (dayBg || T.bg);
|
||||
var txt = isDark ? (nightText || T.text) : (dayText || T.text);
|
||||
// 根据主背景色推导辅助色:用调亮/调暗/混合方式生成 T 结构的其他字段
|
||||
var r = Color.red(bg), g = Color.green(bg), b = Color.blue(bg);
|
||||
var lum = (r*0.299 + g*0.587 + b*0.114) / 255.0;
|
||||
var subTxt = isDark ? Color.rgb(
|
||||
Math.min(255, Color.red(txt) + 40),
|
||||
Math.min(255, Color.green(txt) + 40),
|
||||
Math.min(255, Color.blue(txt) + 40)
|
||||
) : Color.rgb(
|
||||
Math.max(0, Color.red(txt) - 40),
|
||||
Math.max(0, Color.green(txt) - 40),
|
||||
Math.max(0, Color.blue(txt) - 40)
|
||||
);
|
||||
var cardBg = isDark ? Color.rgb(
|
||||
Math.min(255, r + 25), Math.min(255, g + 25), Math.min(255, b + 25)
|
||||
) : Color.rgb(
|
||||
Math.max(0, r - 20), Math.max(0, g - 20), Math.max(0, b - 20)
|
||||
);
|
||||
var card2 = isDark ? Color.rgb(
|
||||
Math.max(0, r + 40), Math.max(0, g + 40), Math.max(0, b + 40)
|
||||
) : Color.rgb(
|
||||
Math.min(255, r - 30), Math.min(255, g - 30), Math.min(255, b - 30)
|
||||
);
|
||||
T.bg = bg;
|
||||
T.card = cardBg;
|
||||
T.card2 = card2;
|
||||
T.text = txt;
|
||||
T.sub = subTxt;
|
||||
T.primary = this.ui.colors.primary;
|
||||
T.primaryDeep = this.ui.colors.primary;
|
||||
T.primarySoft = isDark ? this.withAlpha(this.ui.colors.primary, 0.20) : this.withAlpha(this.ui.colors.primary, 0.12);
|
||||
T.brown = txt;
|
||||
T.stroke = isDark ? this.withAlpha(txt, 0.25) : this.withAlpha(txt, 0.18);
|
||||
T.onPrimary = this.ui.colors._monetOnPrimary || (isDark ? Color.parseColor("#062E6F") : Color.WHITE);
|
||||
} catch(eTpl) { safeLog(null, 'e', "catch " + String(eTpl)); }
|
||||
var monetBg = isDark ? C.bgDark : C.bgLight;
|
||||
var monetTxt = isDark ? C.textPriDark : C.textPriLight;
|
||||
var monetCard = isDark ? C.cardDark : C.cardLight;
|
||||
var monetSub = isDark ? C.textSecDark : C.textSecLight;
|
||||
var monetPrimary = C.primary;
|
||||
var monetOnP = C._monetOnPrimary || (isDark ? Color.parseColor("#062E6F") : Color.WHITE);
|
||||
T.bg = monetBg;
|
||||
T.card = monetCard;
|
||||
T.card2 = monetCard;
|
||||
T.text = monetTxt;
|
||||
T.sub = monetSub;
|
||||
T.primary = monetPrimary;
|
||||
T.primaryDeep = monetPrimary;
|
||||
T.primarySoft = isDark ? this.withAlpha(monetPrimary, 0.20) : this.withAlpha(monetPrimary, 0.10);
|
||||
T.brown = monetSub;
|
||||
T.stroke = isDark ? this.withAlpha(monetTxt, 0.16) : this.withAlpha(monetTxt, 0.12);
|
||||
T.onPrimary = monetOnP;
|
||||
} catch(eM) { safeLog(null, 'e', "catch " + String(eM)); }
|
||||
}
|
||||
|
||||
var bgColor = T.bg;
|
||||
|
||||
Reference in New Issue
Block a user