From 954caa9d9bd1a01965d5a4ea2672933f6d1d054f Mon Sep 17 00:00:00 2001 From: 7015725 Date: Sat, 23 May 2026 01:15:56 +0800 Subject: [PATCH] refactor: split color picker module --- ToolHub.js | 2 +- ToolHub.js.sha256 | 2 +- code/th_14_color_picker.js | 551 ++++++++++++++++++++++++++++ code/th_14_panels.js | 548 --------------------------- manifest.json | 10 +- manifest.sig | 2 +- scripts/generate_signed_manifest.py | 2 +- 7 files changed, 562 insertions(+), 555 deletions(-) create mode 100644 code/th_14_color_picker.js diff --git a/ToolHub.js b/ToolHub.js index bfbf167..9b4e57d 100644 --- a/ToolHub.js +++ b/ToolHub.js @@ -341,7 +341,7 @@ function loadScript(relPath) { var modules = ["th_01_base.js", "th_02_core.js", "th_03_icon.js", "th_04_theme.js", "th_05_persistence.js", "th_06_icon_parser.js", "th_07_shortcut.js", "th_08_content.js", "th_09_animation.js", "th_10_shell.js", "th_11_action.js", "th_12_rebuild.js", "th_13_panel_ui.js", - "th_14_panels.js", "th_14_icon_picker.js", "th_15_extra.js", "th_16_entry.js"]; + "th_14_panels.js", "th_14_color_picker.js", "th_14_icon_picker.js", "th_15_extra.js", "th_16_entry.js"]; var __moduleUpdates = []; var loadErrors = []; var criticalModules = { "th_01_base.js": true, "th_16_entry.js": true }; diff --git a/ToolHub.js.sha256 b/ToolHub.js.sha256 index 7958515..56a617c 100644 --- a/ToolHub.js.sha256 +++ b/ToolHub.js.sha256 @@ -1 +1 @@ -243ccea1f11cf64b53a7cb7b5bdad2ca13d6e6c96cedbae9cdac818f0b4ef136 ToolHub.js +1649183178273623b1c72ad228ac0622c3853c9f1ab46f2766574ca097048da7 ToolHub.js diff --git a/code/th_14_color_picker.js b/code/th_14_color_picker.js new file mode 100644 index 0000000..8b79f19 --- /dev/null +++ b/code/th_14_color_picker.js @@ -0,0 +1,551 @@ +// ToolHub - 颜色选择器弹窗模块 +// 依赖:th_14_panels.js 中的 showPopupOverlay()、th_04_theme.js 主题工具、th_06_icon_parser.js 图标解析。 + +FloatBallAppWM.prototype.showColorPickerPopup = function(opts) { + var self = this; + var opt = opts || {}; + var currentColor = String(opt.currentColor || ""); + var currentIconName = String(opt.currentIconName || ""); + var onSelect = (typeof opt.onSelect === "function") ? opt.onSelect : null; + var onDismiss = (typeof opt.onDismiss === "function") ? opt.onDismiss : null; + + var PT = this.getIslandPickerTheme ? this.getIslandPickerTheme() : null; + var isDark = PT ? PT.isDark : this.isDarkTheme(); + var C = this.ui.colors; + var T = PT ? PT.T : this.getAnimalIslandTheme(); + var textColor = PT ? PT.text : (isDark ? C.textPriDark : C.textPriLight); + var subTextColor = PT ? PT.sub : (isDark ? C.textSecDark : C.textSecLight); + + function getThemeTintHex() { + try { + if (self.ui.colors && self.ui.colors.accent) { + var c = self.ui.colors.accent; + return "#" + ("00000000" + (c >>> 0).toString(16)).slice(-8); + } + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } + return "#FF4081"; + } + + function buildArgbHex(alphaByte, rgbHex) { + var a = ("00" + (Math.max(0, Math.min(255, Number(alphaByte || 0))) >>> 0).toString(16)).slice(-2); + var rgb = String(rgbHex || "000000").replace(/^#/, ""); + if (rgb.length === 3) rgb = rgb.split("").map(function(c){ return c+c; }).join(""); + if (rgb.length > 6) rgb = rgb.slice(-6); + while (rgb.length < 6) rgb = "0" + rgb; + return "#" + a + rgb; + } + + function extractTintRgbHex(hex) { + var h = String(hex || "").replace(/^#/, ""); + if (h.length >= 8) return h.slice(-6); + if (h.length === 6) return h; + if (h.length === 3) return h.split("").map(function(c){ return c+c; }).join(""); + return "000000"; + } + + function extractTintAlphaByte(hex) { + var h = String(hex || "").replace(/^#/, ""); + if (h.length >= 8) return parseInt(h.slice(0, 2), 16); + return 255; + } + + function normalizeTintColorValue(val) { + var s = String(val || "").trim(); + if (!s) return ""; + if (s.charAt(0) === "#") s = s.substring(1); + if (/^[0-9A-Fa-f]{1,8}$/.test(s)) { + while (s.length < 6) s = "0" + s; + if (s.length === 6) s = "FF" + s; + else if (s.length > 8) s = s.substring(0, 8); + return "#" + s.toUpperCase(); + } + return ""; + } + + var commonTintHexValues = [ + "#FFFF0000", "#FFFF5722", "#FFFF9800", "#FFFFC107", "#FFFFEB3B", + "#FFCDDC39", "#FF8BC34A", "#FF4CAF50", "#FF009688", "#FF00BCD4", + "#FF03A9F4", "#FF2196F3", "#FF3F51B5", "#FF673AB7", "#FF9C27B0", + "#FFE91E63", "#FF795548", "#FF9E9E9E", "#FF607D8B", "#FF000000", "#FFFFFFFF" + ]; + + // ========== 最近使用颜色 ========== + var RECENT_COLORS_KEY = "color_picker_recent"; + var MAX_RECENT_COLORS = 8; + var recentColors = []; + try { + var recentSaved = self.loadPanelState(RECENT_COLORS_KEY); + if (recentSaved && recentSaved.colors && recentSaved.colors.length) { + var rc; + for (rc = 0; rc < recentSaved.colors.length && rc < MAX_RECENT_COLORS; rc++) { + var rn = normalizeTintColorValue(recentSaved.colors[rc], false); + if (rn) recentColors.push(rn); + } + } + } catch(eRecentLoad) { safeLog(null, 'e', "catch " + String(eRecentLoad)); } + + function saveRecentColors() { + try { + self.savePanelState(RECENT_COLORS_KEY, { colors: recentColors.slice(0, MAX_RECENT_COLORS) }); + } catch(eRecentSave) { safeLog(null, 'e', "catch " + String(eRecentSave)); } + } + + function pushRecentColor(hex) { + var normalized = normalizeTintColorValue(hex, false); + if (!normalized) return; + var next = [normalized]; + var i; + for (i = 0; i < recentColors.length; i++) { + if (recentColors[i] !== normalized) { + next.push(recentColors[i]); + } + if (next.length >= MAX_RECENT_COLORS) break; + } + recentColors = next; + saveRecentColors(); + } + + var selectedColor = currentColor; + var isFollowTheme = !currentColor; + var currentBaseRgbHex = extractTintRgbHex(currentColor); + var currentAlphaByte = extractTintAlphaByte(currentColor); + + var popupResult = self.showPopupOverlay({ + title: "换颜色", + onDismiss: onDismiss, + builder: function(content, closePopup) { + // 图标预览区 + var previewRow = new android.widget.LinearLayout(context); + previewRow.setOrientation(android.widget.LinearLayout.HORIZONTAL); + previewRow.setGravity(android.view.Gravity.CENTER_VERTICAL); + previewRow.setPadding(self.dp(12), self.dp(10), self.dp(12), self.dp(10)); + previewRow.setBackground(self.ui.createStrokeDrawable(T.primarySoft, self.withAlpha(T.primaryDeep, isDark ? 0.24 : 0.18), self.dp(1), self.dp(18))); + + var previewIv = new android.widget.ImageView(context); + previewIv.setLayoutParams(new android.widget.LinearLayout.LayoutParams(self.dp(48), self.dp(48))); + previewIv.setScaleType(android.widget.ImageView.ScaleType.FIT_CENTER); + previewRow.addView(previewIv); + + var previewLabel = new android.widget.TextView(context); + previewLabel.setText("小图标试衣间"); + previewLabel.setTextColor(subTextColor); + previewLabel.setTextSize(android.util.TypedValue.COMPLEX_UNIT_SP, 12); + previewLabel.setPadding(self.dp(12), 0, 0, 0); + previewRow.addView(previewLabel); + + content.addView(previewRow); + + function updatePreview() { + try { + var dr = null; + if (currentIconName) { + try { dr = self.getShortXIconDrawable(currentIconName); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } + } + if (dr) { + if (!isFollowTheme && selectedColor) { + try { + var parsed = android.graphics.Color.parseColor(selectedColor); + dr.setColorFilter(parsed, android.graphics.PorterDuff.Mode.SRC_IN); + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } + } else { + try { dr.clearColorFilter(); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } + } + previewIv.setImageDrawable(dr); + } else { + previewIv.setImageDrawable(null); + } + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } + } + updatePreview(); + + // ========== 最近使用颜色 ========== + var recentTitle = new android.widget.TextView(context); + recentTitle.setText("最近用过的小颜色"); + recentTitle.setTextColor(subTextColor); + recentTitle.setTextSize(android.util.TypedValue.COMPLEX_UNIT_SP, 12); + recentTitle.setPadding(self.dp(12), self.dp(8), self.dp(12), self.dp(4)); + content.addView(recentTitle); + + var recentGrid = new android.widget.GridLayout(context); + recentGrid.setColumnCount(8); + recentGrid.setPadding(self.dp(8), self.dp(4), self.dp(8), self.dp(4)); + content.addView(recentGrid); + + var recentEmptyTv = new android.widget.TextView(context); + recentEmptyTv.setText("还没有最近颜色"); + recentEmptyTv.setTextColor(subTextColor); + recentEmptyTv.setTextSize(android.util.TypedValue.COMPLEX_UNIT_SP, 11); + recentEmptyTv.setPadding(self.dp(12), self.dp(4), self.dp(12), self.dp(8)); + recentEmptyTv.setVisibility(android.view.View.GONE); + content.addView(recentEmptyTv); + + function refreshRecentGrid() { + try { + recentGrid.removeAllViews(); + if (!recentColors.length) { + recentEmptyTv.setVisibility(android.view.View.VISIBLE); + return; + } + recentEmptyTv.setVisibility(android.view.View.GONE); + var ri; + for (ri = 0; ri < recentColors.length && ri < MAX_RECENT_COLORS; ri++) { + (function(hex) { + var cell = new android.widget.FrameLayout(context); + var margin = self.dp(3); + try { + var lp = new android.widget.GridLayout.LayoutParams(); + lp.width = self.dp(28); + lp.height = self.dp(28); + lp.setMargins(margin, margin, margin, margin); + cell.setLayoutParams(lp); + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } + + var swatch = new android.view.View(context); + swatch.setLayoutParams(new android.widget.FrameLayout.LayoutParams(android.widget.FrameLayout.LayoutParams.MATCH_PARENT, android.widget.FrameLayout.LayoutParams.MATCH_PARENT)); + try { + var bg = new android.graphics.drawable.GradientDrawable(); + bg.setColor(android.graphics.Color.parseColor(hex)); + bg.setCornerRadius(self.dp(5)); + swatch.setBackground(bg); + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } + cell.addView(swatch); + + if (selectedColor === hex) { + try { + var border = new android.graphics.drawable.GradientDrawable(); + border.setColor(android.graphics.Color.TRANSPARENT); + border.setCornerRadius(self.dp(5)); + border.setStroke(self.dp(2), T.primaryDeep); + cell.setForeground(border); + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } + } + + cell.setOnClickListener(new android.view.View.OnClickListener({ + onClick: function() { + self.touchActivity(); + isFollowTheme = false; + selectedColor = hex; + currentBaseRgbHex = extractTintRgbHex(hex); + currentAlphaByte = extractTintAlphaByte(hex); + updatePreview(); + updateValueTv(); + refreshRecentGrid(); + refreshCommonGrid(); + syncRgbSeeks(); + } + })); + recentGrid.addView(cell); + })(recentColors[ri]); + } + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } + } + refreshRecentGrid(); + + // 21 色常用颜色 + var commonTitle = new android.widget.TextView(context); + commonTitle.setText("糖果常用色"); + commonTitle.setTextColor(subTextColor); + commonTitle.setTextSize(android.util.TypedValue.COMPLEX_UNIT_SP, 12); + commonTitle.setPadding(self.dp(12), self.dp(8), self.dp(12), self.dp(4)); + content.addView(commonTitle); + + var commonGrid = new android.widget.GridLayout(context); + commonGrid.setColumnCount(7); + commonGrid.setPadding(self.dp(8), self.dp(4), self.dp(8), self.dp(8)); + var ci; + for (ci = 0; ci < commonTintHexValues.length; ci++) { + (function(hex) { + var cell = new android.widget.FrameLayout(context); + var margin = self.dp(4); + try { + var lp = new android.widget.GridLayout.LayoutParams(); + lp.width = self.dp(32); + lp.height = self.dp(32); + lp.setMargins(margin, margin, margin, margin); + cell.setLayoutParams(lp); + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } + + var swatch = new android.view.View(context); + swatch.setLayoutParams(new android.widget.FrameLayout.LayoutParams(android.widget.FrameLayout.LayoutParams.MATCH_PARENT, android.widget.FrameLayout.LayoutParams.MATCH_PARENT)); + try { + var bg = new android.graphics.drawable.GradientDrawable(); + bg.setColor(android.graphics.Color.parseColor(hex)); + bg.setCornerRadius(self.dp(6)); + swatch.setBackground(bg); + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } + cell.addView(swatch); + + if (selectedColor === hex) { + try { + var border = new android.graphics.drawable.GradientDrawable(); + border.setColor(android.graphics.Color.TRANSPARENT); + border.setCornerRadius(self.dp(6)); + border.setStroke(self.dp(3), T.primaryDeep); + cell.setForeground(border); + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } + } + + cell.setOnClickListener(new android.view.View.OnClickListener({ + onClick: function() { + self.touchActivity(); + isFollowTheme = false; + selectedColor = hex; + currentBaseRgbHex = extractTintRgbHex(hex); + currentAlphaByte = extractTintAlphaByte(hex); + updatePreview(); + updateValueTv(); + refreshRecentGrid(); + refreshCommonGrid(); + syncRgbSeeks(); + } + })); + commonGrid.addView(cell); + })(commonTintHexValues[ci]); + } + content.addView(commonGrid); + + function refreshCommonGrid() { + try { + var count = commonGrid.getChildCount(); + var i; + for (i = 0; i < count; i++) { + var cell = commonGrid.getChildAt(i); + if (!cell) continue; + try { cell.setForeground(null); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } + } + var idx = commonTintHexValues.indexOf(selectedColor); + if (idx >= 0 && idx < count) { + var matchedCell = commonGrid.getChildAt(idx); + if (matchedCell) { + try { + var border = new android.graphics.drawable.GradientDrawable(); + border.setColor(android.graphics.Color.TRANSPARENT); + border.setCornerRadius(self.dp(6)); + border.setStroke(self.dp(3), T.primaryDeep); + matchedCell.setForeground(border); + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } + } + } + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } + } + + // 颜色值显示 + var valueTv = new android.widget.TextView(context); + valueTv.setTextColor(textColor); + valueTv.setTextSize(android.util.TypedValue.COMPLEX_UNIT_SP, 13); + valueTv.setPadding(self.dp(12), self.dp(4), self.dp(12), self.dp(4)); + content.addView(valueTv); + + function updateValueTv() { + valueTv.setText(isFollowTheme ? "当前:跟随岛屿主题" : ("当前:" + (selectedColor || "无"))); + } + updateValueTv(); + + // RGB 滑块 + var rgbLabels = ["R", "G", "B"]; + var rgbSeeks = []; + var rgbValTvs = []; + var ri; + for (ri = 0; ri < 3; ri++) { + (function(idx) { + var row = new android.widget.LinearLayout(context); + row.setOrientation(android.widget.LinearLayout.HORIZONTAL); + row.setGravity(android.view.Gravity.CENTER_VERTICAL); + row.setPadding(self.dp(12), self.dp(4), self.dp(12), self.dp(4)); + + var label = new android.widget.TextView(context); + label.setText(rgbLabels[idx]); + label.setTextColor(textColor); + label.setTextSize(android.util.TypedValue.COMPLEX_UNIT_SP, 12); + label.setMinWidth(self.dp(20)); + row.addView(label); + + var seek = new android.widget.SeekBar(context); + seek.setMax(255); + var seekLp = new android.widget.LinearLayout.LayoutParams(0, android.widget.LinearLayout.LayoutParams.WRAP_CONTENT, 1); + seekLp.setMargins(self.dp(8), 0, self.dp(8), 0); + seek.setLayoutParams(seekLp); + row.addView(seek); + rgbSeeks.push(seek); + + var valTv = new android.widget.TextView(context); + valTv.setTextColor(subTextColor); + valTv.setTextSize(android.util.TypedValue.COMPLEX_UNIT_SP, 11); + valTv.setMinWidth(self.dp(28)); + row.addView(valTv); + rgbValTvs.push(valTv); + + seek.setOnSeekBarChangeListener(new android.widget.SeekBar.OnSeekBarChangeListener({ + onProgressChanged: function(s, progress, fromUser) { + if (!fromUser) return; + valTv.setText(String(progress)); + var r = rgbSeeks[0].getProgress(); + var g = rgbSeeks[1].getProgress(); + var b = rgbSeeks[2].getProgress(); + var hex = ("00" + (r >>> 0).toString(16)).slice(-2) + ("00" + (g >>> 0).toString(16)).slice(-2) + ("00" + (b >>> 0).toString(16)).slice(-2); + currentBaseRgbHex = hex; + isFollowTheme = false; + selectedColor = buildArgbHex(currentAlphaByte, currentBaseRgbHex); + updatePreview(); + updateValueTv(); + refreshRecentGrid(); + refreshCommonGrid(); + }, + onStartTrackingTouch: function() {}, + onStopTrackingTouch: function() {} + })); + + content.addView(row); + })(ri); + } + + function syncRgbSeeks() { + try { + var initR = parseInt(currentBaseRgbHex.slice(0, 2), 16) || 0; + var initG = parseInt(currentBaseRgbHex.slice(2, 4), 16) || 0; + var initB = parseInt(currentBaseRgbHex.slice(4, 6), 16) || 0; + rgbSeeks[0].setProgress(initR); + rgbSeeks[1].setProgress(initG); + rgbSeeks[2].setProgress(initB); + rgbValTvs[0].setText(String(initR)); + rgbValTvs[1].setText(String(initG)); + rgbValTvs[2].setText(String(initB)); + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } + } + syncRgbSeeks(); + + // 透明度滑块 + var alphaRow = new android.widget.LinearLayout(context); + alphaRow.setOrientation(android.widget.LinearLayout.HORIZONTAL); + alphaRow.setGravity(android.view.Gravity.CENTER_VERTICAL); + alphaRow.setPadding(self.dp(12), self.dp(4), self.dp(12), self.dp(8)); + + var alphaLabel = new android.widget.TextView(context); + alphaLabel.setText("A"); + alphaLabel.setTextColor(textColor); + alphaLabel.setTextSize(android.util.TypedValue.COMPLEX_UNIT_SP, 12); + alphaLabel.setMinWidth(self.dp(20)); + alphaRow.addView(alphaLabel); + + var alphaSeek = new android.widget.SeekBar(context); + alphaSeek.setMax(255); + var alphaSeekLp = new android.widget.LinearLayout.LayoutParams(0, android.widget.LinearLayout.LayoutParams.WRAP_CONTENT, 1); + alphaSeekLp.setMargins(self.dp(8), 0, self.dp(8), 0); + alphaSeek.setLayoutParams(alphaSeekLp); + alphaRow.addView(alphaSeek); + + var alphaValTv = new android.widget.TextView(context); + alphaValTv.setTextColor(subTextColor); + alphaValTv.setTextSize(android.util.TypedValue.COMPLEX_UNIT_SP, 11); + alphaValTv.setMinWidth(self.dp(28)); + alphaRow.addView(alphaValTv); + + alphaSeek.setOnSeekBarChangeListener(new android.widget.SeekBar.OnSeekBarChangeListener({ + onProgressChanged: function(s, progress, fromUser) { + if (!fromUser) return; + alphaValTv.setText(String(progress)); + currentAlphaByte = progress; + isFollowTheme = false; + selectedColor = buildArgbHex(currentAlphaByte, currentBaseRgbHex); + updatePreview(); + updateValueTv(); + refreshRecentGrid(); + refreshCommonGrid(); + }, + onStartTrackingTouch: function() {}, + onStopTrackingTouch: function() {} + })); + + alphaSeek.setProgress(currentAlphaByte); + alphaValTv.setText(String(currentAlphaByte)); + content.addView(alphaRow); + + // 操作按钮:对齐设置页/按钮管理页的 chip + 主按钮视觉。 + function createColorPanelActionButton(label, primary, onClick) { + var b = new android.widget.TextView(context); + b.setText(label); + b.setGravity(android.view.Gravity.CENTER); + b.setSingleLine(true); + b.setTypeface(null, android.graphics.Typeface.BOLD); + try { b.setIncludeFontPadding(false); } catch(eFontPad) {} + if (primary) { + // 与设置页底部“保存布置”一致:主色胶囊、44dp 高、轻描边。 + b.setTextSize(android.util.TypedValue.COMPLEX_UNIT_SP, 15); + // 颜色面板里不用高饱和青色,改成更沉稳的深绿主按钮。 + b.setTextColor(android.graphics.Color.WHITE); + b.setPadding(self.dp(18), 0, self.dp(18), 0); + try { b.setMinHeight(self.dp(52)); } catch(eMinH1) {} + try { b.setBackground(self.ui.createStrokeDrawable(T.primaryDeep, self.withAlpha(T.brown || T.primaryDeep, isDark ? 0.28 : 0.18), self.dp(1), self.dp(26))); } catch(eBg1) {} + try { b.setElevation(self.dp(1)); } catch(eElev) {} + } else { + // 与设置页按钮一致:次级也用大圆角按钮,不再做小 chip。 + b.setTextSize(android.util.TypedValue.COMPLEX_UNIT_SP, 15); + // 次级按钮走设置页里的奶油/描边感,不再用薄荷绿底。 + b.setTextColor(T.brown || T.sub); + b.setPadding(self.dp(16), 0, self.dp(16), 0); + try { b.setMinHeight(self.dp(52)); } catch(eMinH2) {} + try { b.setBackground(self.ui.createStrokeDrawable(T.card2 || T.card, self.withAlpha(T.stroke || T.brown, isDark ? 0.42 : 0.55), self.dp(1), self.dp(26))); } catch(eBg2) {} + try { b.setElevation(self.dp(1)); } catch(eElev2) {} + } + try { b.setClickable(true); b.setFocusable(true); } catch(eClickable) {} + b.setOnClickListener(new android.view.View.OnClickListener({ + onClick: function(v) { + self.touchActivity(); + try { if (onClick) onClick(v); } catch(eBtn) { safeLog(self.L, 'e', "color panel action err=" + String(eBtn)); } + } + })); + return b; + } + + var actionRow = new android.widget.LinearLayout(context); + actionRow.setOrientation(android.widget.LinearLayout.HORIZONTAL); + actionRow.setGravity(android.view.Gravity.CENTER_VERTICAL); + actionRow.setPadding(self.dp(10), self.dp(10), self.dp(10), self.dp(12)); + + var btnClear = createColorPanelActionButton("恢复默认", false, function() { + isFollowTheme = true; + selectedColor = ""; + updatePreview(); + updateValueTv(); + refreshRecentGrid(); + refreshCommonGrid(); + syncRgbSeeks(); + alphaSeek.setProgress(255); + alphaValTv.setText("255"); + currentAlphaByte = 255; + }); + var clearLp = new android.widget.LinearLayout.LayoutParams(0, self.dp(52)); + clearLp.weight = 1; + clearLp.setMargins(0, 0, self.dp(6), 0); + actionRow.addView(btnClear, clearLp); + + var btnOk = createColorPanelActionButton("保存颜色", true, function() { + try { + var finalColor = isFollowTheme ? "" : String(selectedColor || ""); + if (!isFollowTheme && selectedColor) { + pushRecentColor(selectedColor); + } + if (typeof onSelect === "function") { + try { onSelect(finalColor); } catch(eOnSelect) { + safeLog(self.L, 'e', "colorPicker onSelect err=" + String(eOnSelect)); + } + } + } catch(e) { + safeLog(self.L, 'e', "colorPicker confirm err=" + String(e)); + } + closePopup(); + }); + var okLp = new android.widget.LinearLayout.LayoutParams(0, self.dp(52)); + okLp.weight = 1; + okLp.setMargins(self.dp(6), 0, 0, 0); + actionRow.addView(btnOk, okLp); + + content.addView(actionRow, new android.widget.LinearLayout.LayoutParams( + android.widget.LinearLayout.LayoutParams.MATCH_PARENT, + android.widget.LinearLayout.LayoutParams.WRAP_CONTENT + )); + } + }); + + return popupResult; +}; diff --git a/code/th_14_panels.js b/code/th_14_panels.js index c10ad5f..e94a979 100644 --- a/code/th_14_panels.js +++ b/code/th_14_panels.js @@ -5034,553 +5034,5 @@ FloatBallAppWM.prototype.showPopupOverlay = function(opts) { return { close: closePopup, content: content }; }; -FloatBallAppWM.prototype.showColorPickerPopup = function(opts) { - var self = this; - var opt = opts || {}; - var currentColor = String(opt.currentColor || ""); - var currentIconName = String(opt.currentIconName || ""); - var onSelect = (typeof opt.onSelect === "function") ? opt.onSelect : null; - var onDismiss = (typeof opt.onDismiss === "function") ? opt.onDismiss : null; - - var PT = this.getIslandPickerTheme ? this.getIslandPickerTheme() : null; - var isDark = PT ? PT.isDark : this.isDarkTheme(); - var C = this.ui.colors; - var T = PT ? PT.T : this.getAnimalIslandTheme(); - var textColor = PT ? PT.text : (isDark ? C.textPriDark : C.textPriLight); - var subTextColor = PT ? PT.sub : (isDark ? C.textSecDark : C.textSecLight); - - function getThemeTintHex() { - try { - if (self.ui.colors && self.ui.colors.accent) { - var c = self.ui.colors.accent; - return "#" + ("00000000" + (c >>> 0).toString(16)).slice(-8); - } - } catch(e) { safeLog(null, 'e', "catch " + String(e)); } - return "#FF4081"; - } - - function buildArgbHex(alphaByte, rgbHex) { - var a = ("00" + (Math.max(0, Math.min(255, Number(alphaByte || 0))) >>> 0).toString(16)).slice(-2); - var rgb = String(rgbHex || "000000").replace(/^#/, ""); - if (rgb.length === 3) rgb = rgb.split("").map(function(c){ return c+c; }).join(""); - if (rgb.length > 6) rgb = rgb.slice(-6); - while (rgb.length < 6) rgb = "0" + rgb; - return "#" + a + rgb; - } - - function extractTintRgbHex(hex) { - var h = String(hex || "").replace(/^#/, ""); - if (h.length >= 8) return h.slice(-6); - if (h.length === 6) return h; - if (h.length === 3) return h.split("").map(function(c){ return c+c; }).join(""); - return "000000"; - } - - function extractTintAlphaByte(hex) { - var h = String(hex || "").replace(/^#/, ""); - if (h.length >= 8) return parseInt(h.slice(0, 2), 16); - return 255; - } - - function normalizeTintColorValue(val) { - var s = String(val || "").trim(); - if (!s) return ""; - if (s.charAt(0) === "#") s = s.substring(1); - if (/^[0-9A-Fa-f]{1,8}$/.test(s)) { - while (s.length < 6) s = "0" + s; - if (s.length === 6) s = "FF" + s; - else if (s.length > 8) s = s.substring(0, 8); - return "#" + s.toUpperCase(); - } - return ""; - } - - var commonTintHexValues = [ - "#FFFF0000", "#FFFF5722", "#FFFF9800", "#FFFFC107", "#FFFFEB3B", - "#FFCDDC39", "#FF8BC34A", "#FF4CAF50", "#FF009688", "#FF00BCD4", - "#FF03A9F4", "#FF2196F3", "#FF3F51B5", "#FF673AB7", "#FF9C27B0", - "#FFE91E63", "#FF795548", "#FF9E9E9E", "#FF607D8B", "#FF000000", "#FFFFFFFF" - ]; - - // ========== 最近使用颜色 ========== - var RECENT_COLORS_KEY = "color_picker_recent"; - var MAX_RECENT_COLORS = 8; - var recentColors = []; - try { - var recentSaved = self.loadPanelState(RECENT_COLORS_KEY); - if (recentSaved && recentSaved.colors && recentSaved.colors.length) { - var rc; - for (rc = 0; rc < recentSaved.colors.length && rc < MAX_RECENT_COLORS; rc++) { - var rn = normalizeTintColorValue(recentSaved.colors[rc], false); - if (rn) recentColors.push(rn); - } - } - } catch(eRecentLoad) { safeLog(null, 'e', "catch " + String(eRecentLoad)); } - - function saveRecentColors() { - try { - self.savePanelState(RECENT_COLORS_KEY, { colors: recentColors.slice(0, MAX_RECENT_COLORS) }); - } catch(eRecentSave) { safeLog(null, 'e', "catch " + String(eRecentSave)); } - } - - function pushRecentColor(hex) { - var normalized = normalizeTintColorValue(hex, false); - if (!normalized) return; - var next = [normalized]; - var i; - for (i = 0; i < recentColors.length; i++) { - if (recentColors[i] !== normalized) { - next.push(recentColors[i]); - } - if (next.length >= MAX_RECENT_COLORS) break; - } - recentColors = next; - saveRecentColors(); - } - - var selectedColor = currentColor; - var isFollowTheme = !currentColor; - var currentBaseRgbHex = extractTintRgbHex(currentColor); - var currentAlphaByte = extractTintAlphaByte(currentColor); - - var popupResult = self.showPopupOverlay({ - title: "换颜色", - onDismiss: onDismiss, - builder: function(content, closePopup) { - // 图标预览区 - var previewRow = new android.widget.LinearLayout(context); - previewRow.setOrientation(android.widget.LinearLayout.HORIZONTAL); - previewRow.setGravity(android.view.Gravity.CENTER_VERTICAL); - previewRow.setPadding(self.dp(12), self.dp(10), self.dp(12), self.dp(10)); - previewRow.setBackground(self.ui.createStrokeDrawable(T.primarySoft, self.withAlpha(T.primaryDeep, isDark ? 0.24 : 0.18), self.dp(1), self.dp(18))); - - var previewIv = new android.widget.ImageView(context); - previewIv.setLayoutParams(new android.widget.LinearLayout.LayoutParams(self.dp(48), self.dp(48))); - previewIv.setScaleType(android.widget.ImageView.ScaleType.FIT_CENTER); - previewRow.addView(previewIv); - - var previewLabel = new android.widget.TextView(context); - previewLabel.setText("小图标试衣间"); - previewLabel.setTextColor(subTextColor); - previewLabel.setTextSize(android.util.TypedValue.COMPLEX_UNIT_SP, 12); - previewLabel.setPadding(self.dp(12), 0, 0, 0); - previewRow.addView(previewLabel); - - content.addView(previewRow); - - function updatePreview() { - try { - var dr = null; - if (currentIconName) { - try { dr = self.getShortXIconDrawable(currentIconName); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } - } - if (dr) { - if (!isFollowTheme && selectedColor) { - try { - var parsed = android.graphics.Color.parseColor(selectedColor); - dr.setColorFilter(parsed, android.graphics.PorterDuff.Mode.SRC_IN); - } catch(e) { safeLog(null, 'e', "catch " + String(e)); } - } else { - try { dr.clearColorFilter(); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } - } - previewIv.setImageDrawable(dr); - } else { - previewIv.setImageDrawable(null); - } - } catch(e) { safeLog(null, 'e', "catch " + String(e)); } - } - updatePreview(); - - // ========== 最近使用颜色 ========== - var recentTitle = new android.widget.TextView(context); - recentTitle.setText("最近用过的小颜色"); - recentTitle.setTextColor(subTextColor); - recentTitle.setTextSize(android.util.TypedValue.COMPLEX_UNIT_SP, 12); - recentTitle.setPadding(self.dp(12), self.dp(8), self.dp(12), self.dp(4)); - content.addView(recentTitle); - - var recentGrid = new android.widget.GridLayout(context); - recentGrid.setColumnCount(8); - recentGrid.setPadding(self.dp(8), self.dp(4), self.dp(8), self.dp(4)); - content.addView(recentGrid); - - var recentEmptyTv = new android.widget.TextView(context); - recentEmptyTv.setText("还没有最近颜色"); - recentEmptyTv.setTextColor(subTextColor); - recentEmptyTv.setTextSize(android.util.TypedValue.COMPLEX_UNIT_SP, 11); - recentEmptyTv.setPadding(self.dp(12), self.dp(4), self.dp(12), self.dp(8)); - recentEmptyTv.setVisibility(android.view.View.GONE); - content.addView(recentEmptyTv); - - function refreshRecentGrid() { - try { - recentGrid.removeAllViews(); - if (!recentColors.length) { - recentEmptyTv.setVisibility(android.view.View.VISIBLE); - return; - } - recentEmptyTv.setVisibility(android.view.View.GONE); - var ri; - for (ri = 0; ri < recentColors.length && ri < MAX_RECENT_COLORS; ri++) { - (function(hex) { - var cell = new android.widget.FrameLayout(context); - var margin = self.dp(3); - try { - var lp = new android.widget.GridLayout.LayoutParams(); - lp.width = self.dp(28); - lp.height = self.dp(28); - lp.setMargins(margin, margin, margin, margin); - cell.setLayoutParams(lp); - } catch(e) { safeLog(null, 'e', "catch " + String(e)); } - - var swatch = new android.view.View(context); - swatch.setLayoutParams(new android.widget.FrameLayout.LayoutParams(android.widget.FrameLayout.LayoutParams.MATCH_PARENT, android.widget.FrameLayout.LayoutParams.MATCH_PARENT)); - try { - var bg = new android.graphics.drawable.GradientDrawable(); - bg.setColor(android.graphics.Color.parseColor(hex)); - bg.setCornerRadius(self.dp(5)); - swatch.setBackground(bg); - } catch(e) { safeLog(null, 'e', "catch " + String(e)); } - cell.addView(swatch); - - if (selectedColor === hex) { - try { - var border = new android.graphics.drawable.GradientDrawable(); - border.setColor(android.graphics.Color.TRANSPARENT); - border.setCornerRadius(self.dp(5)); - border.setStroke(self.dp(2), T.primaryDeep); - cell.setForeground(border); - } catch(e) { safeLog(null, 'e', "catch " + String(e)); } - } - - cell.setOnClickListener(new android.view.View.OnClickListener({ - onClick: function() { - self.touchActivity(); - isFollowTheme = false; - selectedColor = hex; - currentBaseRgbHex = extractTintRgbHex(hex); - currentAlphaByte = extractTintAlphaByte(hex); - updatePreview(); - updateValueTv(); - refreshRecentGrid(); - refreshCommonGrid(); - syncRgbSeeks(); - } - })); - recentGrid.addView(cell); - })(recentColors[ri]); - } - } catch(e) { safeLog(null, 'e', "catch " + String(e)); } - } - refreshRecentGrid(); - - // 21 色常用颜色 - var commonTitle = new android.widget.TextView(context); - commonTitle.setText("糖果常用色"); - commonTitle.setTextColor(subTextColor); - commonTitle.setTextSize(android.util.TypedValue.COMPLEX_UNIT_SP, 12); - commonTitle.setPadding(self.dp(12), self.dp(8), self.dp(12), self.dp(4)); - content.addView(commonTitle); - - var commonGrid = new android.widget.GridLayout(context); - commonGrid.setColumnCount(7); - commonGrid.setPadding(self.dp(8), self.dp(4), self.dp(8), self.dp(8)); - var ci; - for (ci = 0; ci < commonTintHexValues.length; ci++) { - (function(hex) { - var cell = new android.widget.FrameLayout(context); - var margin = self.dp(4); - try { - var lp = new android.widget.GridLayout.LayoutParams(); - lp.width = self.dp(32); - lp.height = self.dp(32); - lp.setMargins(margin, margin, margin, margin); - cell.setLayoutParams(lp); - } catch(e) { safeLog(null, 'e', "catch " + String(e)); } - - var swatch = new android.view.View(context); - swatch.setLayoutParams(new android.widget.FrameLayout.LayoutParams(android.widget.FrameLayout.LayoutParams.MATCH_PARENT, android.widget.FrameLayout.LayoutParams.MATCH_PARENT)); - try { - var bg = new android.graphics.drawable.GradientDrawable(); - bg.setColor(android.graphics.Color.parseColor(hex)); - bg.setCornerRadius(self.dp(6)); - swatch.setBackground(bg); - } catch(e) { safeLog(null, 'e', "catch " + String(e)); } - cell.addView(swatch); - - if (selectedColor === hex) { - try { - var border = new android.graphics.drawable.GradientDrawable(); - border.setColor(android.graphics.Color.TRANSPARENT); - border.setCornerRadius(self.dp(6)); - border.setStroke(self.dp(3), T.primaryDeep); - cell.setForeground(border); - } catch(e) { safeLog(null, 'e', "catch " + String(e)); } - } - - cell.setOnClickListener(new android.view.View.OnClickListener({ - onClick: function() { - self.touchActivity(); - isFollowTheme = false; - selectedColor = hex; - currentBaseRgbHex = extractTintRgbHex(hex); - currentAlphaByte = extractTintAlphaByte(hex); - updatePreview(); - updateValueTv(); - refreshRecentGrid(); - refreshCommonGrid(); - syncRgbSeeks(); - } - })); - commonGrid.addView(cell); - })(commonTintHexValues[ci]); - } - content.addView(commonGrid); - - function refreshCommonGrid() { - try { - var count = commonGrid.getChildCount(); - var i; - for (i = 0; i < count; i++) { - var cell = commonGrid.getChildAt(i); - if (!cell) continue; - try { cell.setForeground(null); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } - } - var idx = commonTintHexValues.indexOf(selectedColor); - if (idx >= 0 && idx < count) { - var matchedCell = commonGrid.getChildAt(idx); - if (matchedCell) { - try { - var border = new android.graphics.drawable.GradientDrawable(); - border.setColor(android.graphics.Color.TRANSPARENT); - border.setCornerRadius(self.dp(6)); - border.setStroke(self.dp(3), T.primaryDeep); - matchedCell.setForeground(border); - } catch(e) { safeLog(null, 'e', "catch " + String(e)); } - } - } - } catch(e) { safeLog(null, 'e', "catch " + String(e)); } - } - - // 颜色值显示 - var valueTv = new android.widget.TextView(context); - valueTv.setTextColor(textColor); - valueTv.setTextSize(android.util.TypedValue.COMPLEX_UNIT_SP, 13); - valueTv.setPadding(self.dp(12), self.dp(4), self.dp(12), self.dp(4)); - content.addView(valueTv); - - function updateValueTv() { - valueTv.setText(isFollowTheme ? "当前:跟随岛屿主题" : ("当前:" + (selectedColor || "无"))); - } - updateValueTv(); - - // RGB 滑块 - var rgbLabels = ["R", "G", "B"]; - var rgbSeeks = []; - var rgbValTvs = []; - var ri; - for (ri = 0; ri < 3; ri++) { - (function(idx) { - var row = new android.widget.LinearLayout(context); - row.setOrientation(android.widget.LinearLayout.HORIZONTAL); - row.setGravity(android.view.Gravity.CENTER_VERTICAL); - row.setPadding(self.dp(12), self.dp(4), self.dp(12), self.dp(4)); - - var label = new android.widget.TextView(context); - label.setText(rgbLabels[idx]); - label.setTextColor(textColor); - label.setTextSize(android.util.TypedValue.COMPLEX_UNIT_SP, 12); - label.setMinWidth(self.dp(20)); - row.addView(label); - - var seek = new android.widget.SeekBar(context); - seek.setMax(255); - var seekLp = new android.widget.LinearLayout.LayoutParams(0, android.widget.LinearLayout.LayoutParams.WRAP_CONTENT, 1); - seekLp.setMargins(self.dp(8), 0, self.dp(8), 0); - seek.setLayoutParams(seekLp); - row.addView(seek); - rgbSeeks.push(seek); - - var valTv = new android.widget.TextView(context); - valTv.setTextColor(subTextColor); - valTv.setTextSize(android.util.TypedValue.COMPLEX_UNIT_SP, 11); - valTv.setMinWidth(self.dp(28)); - row.addView(valTv); - rgbValTvs.push(valTv); - - seek.setOnSeekBarChangeListener(new android.widget.SeekBar.OnSeekBarChangeListener({ - onProgressChanged: function(s, progress, fromUser) { - if (!fromUser) return; - valTv.setText(String(progress)); - var r = rgbSeeks[0].getProgress(); - var g = rgbSeeks[1].getProgress(); - var b = rgbSeeks[2].getProgress(); - var hex = ("00" + (r >>> 0).toString(16)).slice(-2) + ("00" + (g >>> 0).toString(16)).slice(-2) + ("00" + (b >>> 0).toString(16)).slice(-2); - currentBaseRgbHex = hex; - isFollowTheme = false; - selectedColor = buildArgbHex(currentAlphaByte, currentBaseRgbHex); - updatePreview(); - updateValueTv(); - refreshRecentGrid(); - refreshCommonGrid(); - }, - onStartTrackingTouch: function() {}, - onStopTrackingTouch: function() {} - })); - - content.addView(row); - })(ri); - } - - function syncRgbSeeks() { - try { - var initR = parseInt(currentBaseRgbHex.slice(0, 2), 16) || 0; - var initG = parseInt(currentBaseRgbHex.slice(2, 4), 16) || 0; - var initB = parseInt(currentBaseRgbHex.slice(4, 6), 16) || 0; - rgbSeeks[0].setProgress(initR); - rgbSeeks[1].setProgress(initG); - rgbSeeks[2].setProgress(initB); - rgbValTvs[0].setText(String(initR)); - rgbValTvs[1].setText(String(initG)); - rgbValTvs[2].setText(String(initB)); - } catch(e) { safeLog(null, 'e', "catch " + String(e)); } - } - syncRgbSeeks(); - - // 透明度滑块 - var alphaRow = new android.widget.LinearLayout(context); - alphaRow.setOrientation(android.widget.LinearLayout.HORIZONTAL); - alphaRow.setGravity(android.view.Gravity.CENTER_VERTICAL); - alphaRow.setPadding(self.dp(12), self.dp(4), self.dp(12), self.dp(8)); - - var alphaLabel = new android.widget.TextView(context); - alphaLabel.setText("A"); - alphaLabel.setTextColor(textColor); - alphaLabel.setTextSize(android.util.TypedValue.COMPLEX_UNIT_SP, 12); - alphaLabel.setMinWidth(self.dp(20)); - alphaRow.addView(alphaLabel); - - var alphaSeek = new android.widget.SeekBar(context); - alphaSeek.setMax(255); - var alphaSeekLp = new android.widget.LinearLayout.LayoutParams(0, android.widget.LinearLayout.LayoutParams.WRAP_CONTENT, 1); - alphaSeekLp.setMargins(self.dp(8), 0, self.dp(8), 0); - alphaSeek.setLayoutParams(alphaSeekLp); - alphaRow.addView(alphaSeek); - - var alphaValTv = new android.widget.TextView(context); - alphaValTv.setTextColor(subTextColor); - alphaValTv.setTextSize(android.util.TypedValue.COMPLEX_UNIT_SP, 11); - alphaValTv.setMinWidth(self.dp(28)); - alphaRow.addView(alphaValTv); - - alphaSeek.setOnSeekBarChangeListener(new android.widget.SeekBar.OnSeekBarChangeListener({ - onProgressChanged: function(s, progress, fromUser) { - if (!fromUser) return; - alphaValTv.setText(String(progress)); - currentAlphaByte = progress; - isFollowTheme = false; - selectedColor = buildArgbHex(currentAlphaByte, currentBaseRgbHex); - updatePreview(); - updateValueTv(); - refreshRecentGrid(); - refreshCommonGrid(); - }, - onStartTrackingTouch: function() {}, - onStopTrackingTouch: function() {} - })); - - alphaSeek.setProgress(currentAlphaByte); - alphaValTv.setText(String(currentAlphaByte)); - content.addView(alphaRow); - - // 操作按钮:对齐设置页/按钮管理页的 chip + 主按钮视觉。 - function createColorPanelActionButton(label, primary, onClick) { - var b = new android.widget.TextView(context); - b.setText(label); - b.setGravity(android.view.Gravity.CENTER); - b.setSingleLine(true); - b.setTypeface(null, android.graphics.Typeface.BOLD); - try { b.setIncludeFontPadding(false); } catch(eFontPad) {} - if (primary) { - // 与设置页底部“保存布置”一致:主色胶囊、44dp 高、轻描边。 - b.setTextSize(android.util.TypedValue.COMPLEX_UNIT_SP, 15); - // 颜色面板里不用高饱和青色,改成更沉稳的深绿主按钮。 - b.setTextColor(android.graphics.Color.WHITE); - b.setPadding(self.dp(18), 0, self.dp(18), 0); - try { b.setMinHeight(self.dp(52)); } catch(eMinH1) {} - try { b.setBackground(self.ui.createStrokeDrawable(T.primaryDeep, self.withAlpha(T.brown || T.primaryDeep, isDark ? 0.28 : 0.18), self.dp(1), self.dp(26))); } catch(eBg1) {} - try { b.setElevation(self.dp(1)); } catch(eElev) {} - } else { - // 与设置页按钮一致:次级也用大圆角按钮,不再做小 chip。 - b.setTextSize(android.util.TypedValue.COMPLEX_UNIT_SP, 15); - // 次级按钮走设置页里的奶油/描边感,不再用薄荷绿底。 - b.setTextColor(T.brown || T.sub); - b.setPadding(self.dp(16), 0, self.dp(16), 0); - try { b.setMinHeight(self.dp(52)); } catch(eMinH2) {} - try { b.setBackground(self.ui.createStrokeDrawable(T.card2 || T.card, self.withAlpha(T.stroke || T.brown, isDark ? 0.42 : 0.55), self.dp(1), self.dp(26))); } catch(eBg2) {} - try { b.setElevation(self.dp(1)); } catch(eElev2) {} - } - try { b.setClickable(true); b.setFocusable(true); } catch(eClickable) {} - b.setOnClickListener(new android.view.View.OnClickListener({ - onClick: function(v) { - self.touchActivity(); - try { if (onClick) onClick(v); } catch(eBtn) { safeLog(self.L, 'e', "color panel action err=" + String(eBtn)); } - } - })); - return b; - } - - var actionRow = new android.widget.LinearLayout(context); - actionRow.setOrientation(android.widget.LinearLayout.HORIZONTAL); - actionRow.setGravity(android.view.Gravity.CENTER_VERTICAL); - actionRow.setPadding(self.dp(10), self.dp(10), self.dp(10), self.dp(12)); - - var btnClear = createColorPanelActionButton("恢复默认", false, function() { - isFollowTheme = true; - selectedColor = ""; - updatePreview(); - updateValueTv(); - refreshRecentGrid(); - refreshCommonGrid(); - syncRgbSeeks(); - alphaSeek.setProgress(255); - alphaValTv.setText("255"); - currentAlphaByte = 255; - }); - var clearLp = new android.widget.LinearLayout.LayoutParams(0, self.dp(52)); - clearLp.weight = 1; - clearLp.setMargins(0, 0, self.dp(6), 0); - actionRow.addView(btnClear, clearLp); - - var btnOk = createColorPanelActionButton("保存颜色", true, function() { - try { - var finalColor = isFollowTheme ? "" : String(selectedColor || ""); - if (!isFollowTheme && selectedColor) { - pushRecentColor(selectedColor); - } - if (typeof onSelect === "function") { - try { onSelect(finalColor); } catch(eOnSelect) { - safeLog(self.L, 'e', "colorPicker onSelect err=" + String(eOnSelect)); - } - } - } catch(e) { - safeLog(self.L, 'e', "colorPicker confirm err=" + String(e)); - } - closePopup(); - }); - var okLp = new android.widget.LinearLayout.LayoutParams(0, self.dp(52)); - okLp.weight = 1; - okLp.setMargins(self.dp(6), 0, 0, 0); - actionRow.addView(btnOk, okLp); - - content.addView(actionRow, new android.widget.LinearLayout.LayoutParams( - android.widget.LinearLayout.LayoutParams.MATCH_PARENT, - android.widget.LinearLayout.LayoutParams.WRAP_CONTENT - )); - } - }); - - return popupResult; -}; // =======================【查看器面板:UI】====================== diff --git a/manifest.json b/manifest.json index 2154b8d..3e26e97 100644 --- a/manifest.json +++ b/manifest.json @@ -53,13 +53,17 @@ "sha256": "9052e01ccdc0af29615ef8e72550d7d312240f9ab36ebfb66e673c92ab2e4b9c", "size": 22308 }, + "th_14_color_picker.js": { + "sha256": "d3ca89146e31e611e17d703ae9834d82794321e651b6ef156ade006227d231e7", + "size": 23587 + }, "th_14_icon_picker.js": { "sha256": "1df5c4bf82e68de24d7b89c852a4d9878768451effe086e8ddb86620ecc98c35", "size": 23906 }, "th_14_panels.js": { - "sha256": "6cfeb24b7b4617d0dd5c8df376673ae072d95fcd01d856b83fb74d0b89f6bb32", - "size": 281396 + "sha256": "a3f75d42696dab72b818388c2a85034983a7b05df9232f4e43cf3193d9f7e300", + "size": 257974 }, "th_15_extra.js": { "sha256": "f49d9e94702ff6b69b800aea10ae2d21dc0d52246ad176a92904a55352dbbf82", @@ -72,5 +76,5 @@ }, "keyId": "toolhub-targets-2026-rsa3072", "schema": 2, - "version": 20260522170510 + "version": 20260522171545 } diff --git a/manifest.sig b/manifest.sig index f4e56a3..cc4b6e6 100644 --- a/manifest.sig +++ b/manifest.sig @@ -1 +1 @@ -MPutKGnzr3bKu04pc26zaYh8v9BCYRYTopnJl1YyurlakC93YKi/9iEnTOL8Nfm9kpLm2aCLPJAujhiA/xmIYuJSPGE3R/+2xIim31zt8HHLSicOEeIIeSEC39qdCGeoPUIndpT+6Rvd9etuT/T2eMo5yjkkcCd4/Z/5lepj2JszFvnX9yADJ+VJkMnzxzZ2yN0PyBVGI4rgDk7L4ICwIkI062nkE3/FPJLmpf/THaZffeE9zcuHKtU7EyHlg1JaN0VV5IhQADfTbv14zOl6KM6xiDXeZMvVR4b1C9oDZ8IIwgvIMLagJDOr7gbRl+rVMlCHActb/caGAFZMuW0hLqEE8/sMK4QMPdixFc+agIIekow7xVRMT0dtmDXisg/RT9PENfNHaaDW9pTMID5f/Z63g5XiDQVAXxT4OMYAgx1hnLg1zPXcUCbXABx63ngRPYtFC52oYE5Zu7/6zS8avm9AkySvCA8Z/DU5ezqklz3BygVfvIfk8z1Wrp5t44ZX +bpVRHmkL2Q+W/R/MoxZ/Ux9GYhiljyHGzQfxGjM8KcJlJ85lq8ZRi/+cJJiQoQ/tCUK0GmiNBUR0f2IU5NucFIywjSqet+0K2bL6iEb+top57WUzLZo9Fw+mHE92XZ0LfA51PjBbmpKdUIvjKwgtWWFKrCGuzw/ztn7zgBg7P4KYzV12S8b+w4FB/9Gx7fyuq5DsEbkA7Py5QGzF39a2a71itGm8qCoshiFjXQAkV6ykwriLFQy8voswfDcJf4W2OgvSwfviPaHjKx5p3lc3xcpJ0u4AGQTS87jdLHDR6SizLAA7/XzHCu1yqsZLPAvIGHUk5DdKaCuHlSNv4yef+OY7UT4ij4+V4Mhx0h4hkgZ21jUIKxDsaTzU3x7rKSeASrCSael5n/LQTY9sxUx6MvXu15IQ+7oMl2cHplwigNbrT4BFxdWvoLI7x1160gpbnSzriPGAwkPReR8s4Y83gy46f4i+cc4KiCafp+9HCRQgS6lB6wVXiEYYCsP66ubM diff --git a/scripts/generate_signed_manifest.py b/scripts/generate_signed_manifest.py index e6f0fa8..77b90f9 100755 --- a/scripts/generate_signed_manifest.py +++ b/scripts/generate_signed_manifest.py @@ -28,7 +28,7 @@ MODULES = [ "th_05_persistence.js", "th_06_icon_parser.js", "th_07_shortcut.js", "th_08_content.js", "th_09_animation.js", "th_10_shell.js", "th_11_action.js", "th_12_rebuild.js", "th_13_panel_ui.js", - "th_14_panels.js", "th_14_icon_picker.js", "th_15_extra.js", "th_16_entry.js", + "th_14_panels.js", "th_14_color_picker.js", "th_14_icon_picker.js", "th_15_extra.js", "th_16_entry.js", ]