diff --git a/code/th_01_base.js b/code/th_01_base.js index 661343c..10533ef 100644 --- a/code/th_01_base.js +++ b/code/th_01_base.js @@ -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 { diff --git a/code/th_04_theme.js b/code/th_04_theme.js index c945f13..c190a55 100644 --- a/code/th_04_theme.js +++ b/code/th_04_theme.js @@ -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; diff --git a/code/th_05_persistence.js b/code/th_05_persistence.js index 570f12b..9152186 100644 --- a/code/th_05_persistence.js +++ b/code/th_05_persistence.js @@ -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"); diff --git a/code/th_14_panels.js b/code/th_14_panels.js index daca033..19f1b5a 100644 --- a/code/th_14_panels.js +++ b/code/th_14_panels.js @@ -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; diff --git a/manifest.json b/manifest.json index 72d97de..b2b1447 100644 --- a/manifest.json +++ b/manifest.json @@ -2,8 +2,8 @@ "alg": "SHA256withRSA", "files": { "th_01_base.js": { - "sha256": "abb3e1ea017874d1ac26979ad784c21f7e398f8473355d0c5697ce7e128408ed", - "size": 53143 + "sha256": "df8a72de4da16452d19ed6a1f704b42e1f090356af52d2d4769f4ea66300313e", + "size": 52885 }, "th_02_core.js": { "sha256": "15bb9bfbd19a673d442e221b0a00a456ed5f87af2666b9c73b117d6223faeecd", @@ -14,12 +14,12 @@ "size": 5598 }, "th_04_theme.js": { - "sha256": "09a6fd1087cffd0a77aa72212f1c7ce15b145bbc9084c0f159e70e02397006c6", - "size": 41425 + "sha256": "b56b9013de31bf191a786359f1371b07375c3aa60bbb15bdf318dd39945858d7", + "size": 38293 }, "th_05_persistence.js": { - "sha256": "a7ffd7f4d5e75dfcb6eeb8ffd8689da251f5ace3cd8c2ffc24397301f616afb8", - "size": 14950 + "sha256": "2aac4db26a0f1969d3b47fd23ce24e1da5cc42658aa5762d52a9f2a1285bd547", + "size": 14953 }, "th_06_icon_parser.js": { "sha256": "25b95a5df634a7ee359f3ab798e4d3154a71c24016f7b4bf8a658096644b2484", @@ -54,8 +54,8 @@ "size": 20392 }, "th_14_panels.js": { - "sha256": "f9d450c8d42dbdca8ef9bb6b4b7556cff7a3da8f841849a9a1d2dc426b24e0d1", - "size": 246197 + "sha256": "9e8200cd2b4855484952501aa5e838e0ee57da83251c57ad7a8ca85c0f169e64", + "size": 244802 }, "th_15_extra.js": { "sha256": "b607620f1900c1bd93ccbec8d901d4de53b3d36e9373877f4264442f79b9b956", @@ -68,5 +68,5 @@ }, "keyId": "toolhub-targets-2026-rsa3072", "schema": 2, - "version": 20260514181134 + "version": 20260514182424 } diff --git a/manifest.sig b/manifest.sig index b6096c1..70faa65 100644 --- a/manifest.sig +++ b/manifest.sig @@ -1 +1 @@ -Q6SrwKQWn8sqD26NKkAy09VuBvJUMz1nSpv40wzE+/h3rmI+aYaubBL6A3rKK4Jthv94Ql4ulHGheEarHrElailP0JkJE+Pvr6SyGPrlCF2CmDdgCNJBWcI23x6bjATTMDDPj/ELFAbUwrXuSU7CZ5grHYnBjAIDFywkt0BEKeQ6wSqQ/P5uRWwT61CBvGznVblBh0BoaMtTG64TmeveuUmBA8diax3HSw4oGGVWETiMzCwJPmdxLsoxCOZig0eXiOQzkVLnXCVyyoh4rxKzz+espf9H3pjVTXKaNHDmjbbvyhIT6r2VrwbX8Cq2EF3HCfO1WNcvCoKlN0zRwxI6rl8Uz4ESxDeSuD9jHlmFZHH7qerFG/eSfaHTzWVxzDrzZz8zbpctWlmiPiRdfy4g+IGRMVYXxBoFnBA3q5xB0i/euHx46/j/+3lCr1G5e/LknhsK93TQu1k8F5kQaL9ZNHfG4E+WBg7GqMDLh8rj1o7vIzAWf+Agcd+gJjUEZ/m2 +XbvlBLrkCDw72fS8i9hgfSmLRA8MoH5FCBn4Vg+OhFIddDkYJoO5spnG2ZoLdhDurSvBeoGPK9vUij0Ps8V6s+L6k6KjzX33LNncwWcYrop3Eho1hvtsJMq4pGZZOqhloqElhrY6dWBiOS4lFlrNAkrKUh/afFVv/5jsrCzJBNZHj06D1wUw5aswaJ0NRQSyhTMBNc3fEYfb5/G6yfNNWy6RfY8V9asbRyOAJbd5IgdB5nhOFt3X6WzQ2rBxmK60S+vOC6zs91uBqkQuzjbpWY7rSbyoPtccub3z3AAEXjAUVYkJ8w5a0XJdgb7vo29aq91s31A0vgBMCIJgCeDPDe+zikOh6suCslwKSRpbMem1m/Ae/xbfRyNW3gunFTFY0b7r3w/DSdNzG2DJOUfraAUMz5WdxzAOnj1vwPRUnYmFCIO8ilQIkQwoFFH63+YCst6KPD4y7PRd9Dc5Gz+Svqb/3q5+3wIro73eSO/eFAUIQtUJAJ2ihQK8um1dgG1t