diff --git a/code/th_14_color_picker.js b/code/th_14_color_picker.js index 8b79f19..2b0c57f 100644 --- a/code/th_14_color_picker.js +++ b/code/th_14_color_picker.js @@ -109,6 +109,46 @@ FloatBallAppWM.prototype.showColorPickerPopup = function(opts) { var isFollowTheme = !currentColor; var currentBaseRgbHex = extractTintRgbHex(currentColor); var currentAlphaByte = extractTintAlphaByte(currentColor); + var alphaSeek = null; + var alphaValTv = null; + var updatePreviewFn = function() {}; + var updateValueTvFn = function() {}; + var refreshRecentGridFn = function() {}; + var refreshCommonGridFn = function() {}; + var syncRgbSeeksFn = function() {}; + + // 操作按钮:对齐设置页/按钮管理页的 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) { + 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 { + 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 popupResult = self.showPopupOverlay({ title: "换颜色", @@ -146,7 +186,7 @@ FloatBallAppWM.prototype.showColorPickerPopup = function(opts) { 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)); } + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } else { try { dr.clearColorFilter(); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } @@ -154,8 +194,9 @@ FloatBallAppWM.prototype.showColorPickerPopup = function(opts) { } else { previewIv.setImageDrawable(null); } - } catch(e) { safeLog(null, 'e', "catch " + String(e)); } + } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } + updatePreviewFn = updatePreview; updatePreview(); // ========== 最近使用颜色 ========== @@ -239,6 +280,7 @@ FloatBallAppWM.prototype.showColorPickerPopup = function(opts) { } } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } + refreshRecentGridFn = refreshRecentGrid; refreshRecentGrid(); // 21 色常用颜色 @@ -328,6 +370,7 @@ FloatBallAppWM.prototype.showColorPickerPopup = function(opts) { } } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } + refreshCommonGridFn = refreshCommonGrid; // 颜色值显示 var valueTv = new android.widget.TextView(context); @@ -339,6 +382,7 @@ FloatBallAppWM.prototype.showColorPickerPopup = function(opts) { function updateValueTv() { valueTv.setText(isFollowTheme ? "当前:跟随岛屿主题" : ("当前:" + (selectedColor || "无"))); } + updateValueTvFn = updateValueTv; updateValueTv(); // RGB 滑块 @@ -412,6 +456,7 @@ FloatBallAppWM.prototype.showColorPickerPopup = function(opts) { rgbValTvs[2].setText(String(initB)); } catch(e) { safeLog(null, 'e', "catch " + String(e)); } } + syncRgbSeeksFn = syncRgbSeeks; syncRgbSeeks(); // 透明度滑块 @@ -427,14 +472,14 @@ FloatBallAppWM.prototype.showColorPickerPopup = function(opts) { alphaLabel.setMinWidth(self.dp(20)); alphaRow.addView(alphaLabel); - var alphaSeek = new android.widget.SeekBar(context); + 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 = new android.widget.TextView(context); alphaValTv.setTextColor(subTextColor); alphaValTv.setTextSize(android.util.TypedValue.COMPLEX_UNIT_SP, 11); alphaValTv.setMinWidth(self.dp(28)); @@ -460,59 +505,25 @@ FloatBallAppWM.prototype.showColorPickerPopup = function(opts) { 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; - } - + // 底部操作按钮放到 showPopupOverlay 的固定 footer 中,避免默认首屏看不到。 + }, + footerBuilder: function(footer, closePopup) { 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)); + actionRow.setPadding(self.dp(10), self.dp(6), self.dp(10), self.dp(4)); var btnClear = createColorPanelActionButton("恢复默认", false, function() { isFollowTheme = true; selectedColor = ""; - updatePreview(); - updateValueTv(); - refreshRecentGrid(); - refreshCommonGrid(); - syncRgbSeeks(); - alphaSeek.setProgress(255); - alphaValTv.setText("255"); currentAlphaByte = 255; + try { updatePreviewFn(); } catch(eUp) {} + try { updateValueTvFn(); } catch(eVal) {} + try { refreshRecentGridFn(); } catch(eRecent) {} + try { refreshCommonGridFn(); } catch(eCommon) {} + try { syncRgbSeeksFn(); } catch(eSync) {} + try { if (alphaSeek) alphaSeek.setProgress(255); } catch(eAlphaSeek) {} + try { if (alphaValTv) alphaValTv.setText("255"); } catch(eAlphaTv) {} }); var clearLp = new android.widget.LinearLayout.LayoutParams(0, self.dp(52)); clearLp.weight = 1; @@ -522,13 +533,9 @@ FloatBallAppWM.prototype.showColorPickerPopup = function(opts) { var btnOk = createColorPanelActionButton("保存颜色", true, function() { try { var finalColor = isFollowTheme ? "" : String(selectedColor || ""); - if (!isFollowTheme && selectedColor) { - pushRecentColor(selectedColor); - } + if (!isFollowTheme && selectedColor) pushRecentColor(selectedColor); if (typeof onSelect === "function") { - try { onSelect(finalColor); } catch(eOnSelect) { - safeLog(self.L, 'e', "colorPicker onSelect err=" + String(eOnSelect)); - } + 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)); @@ -540,7 +547,7 @@ FloatBallAppWM.prototype.showColorPickerPopup = function(opts) { okLp.setMargins(self.dp(6), 0, 0, 0); actionRow.addView(btnOk, okLp); - content.addView(actionRow, new android.widget.LinearLayout.LayoutParams( + footer.addView(actionRow, new android.widget.LinearLayout.LayoutParams( android.widget.LinearLayout.LayoutParams.MATCH_PARENT, android.widget.LinearLayout.LayoutParams.WRAP_CONTENT )); diff --git a/code/th_14_panels.js b/code/th_14_panels.js index 63b4ac4..4f3e141 100644 --- a/code/th_14_panels.js +++ b/code/th_14_panels.js @@ -4592,6 +4592,7 @@ FloatBallAppWM.prototype.showPopupOverlay = function(opts) { var title = String(opt.title || ""); var onDismiss = (typeof opt.onDismiss === "function") ? opt.onDismiss : null; var builder = (typeof opt.builder === "function") ? opt.builder : null; + var footerBuilder = (typeof opt.footerBuilder === "function") ? opt.footerBuilder : null; var PT = this.getIslandPickerTheme ? this.getIslandPickerTheme() : null; var isDark = PT ? PT.isDark : this.isDarkTheme(); @@ -4674,6 +4675,15 @@ FloatBallAppWM.prototype.showPopupOverlay = function(opts) { )); card.addView(scroll); + var footer = new android.widget.LinearLayout(context); + footer.setOrientation(android.widget.LinearLayout.VERTICAL); + footer.setVisibility(android.view.View.GONE); + try { footer.setPadding(0, self.dp(6), 0, 0); } catch(eFooterPad) {} + card.addView(footer, new android.widget.LinearLayout.LayoutParams( + android.widget.LinearLayout.LayoutParams.MATCH_PARENT, + android.widget.LinearLayout.LayoutParams.WRAP_CONTENT + )); + root.addView(card); root.setOnClickListener(new android.view.View.OnClickListener({ @@ -4709,8 +4719,14 @@ FloatBallAppWM.prototype.showPopupOverlay = function(opts) { if (typeof builder === "function") { try { builder(content, closePopup); } catch(eB) { safeLog(self.L, 'e', "popup builder fail: " + String(eB)); } } + if (typeof footerBuilder === "function") { + try { + footerBuilder(footer, closePopup); + if (footer.getChildCount && footer.getChildCount() > 0) footer.setVisibility(android.view.View.VISIBLE); + } catch(eF) { safeLog(self.L, 'e', "popup footer builder fail: " + String(eF)); } + } - return { close: closePopup, content: content }; + return { close: closePopup, content: content, footer: footer }; }; // 兼容旧入口:旧 ToolHub.js 不会自动加载新增 th_14_color_picker.js, diff --git a/manifest.json b/manifest.json index 9037787..dfb3084 100644 --- a/manifest.json +++ b/manifest.json @@ -54,16 +54,16 @@ "size": 22308 }, "th_14_color_picker.js": { - "sha256": "d3ca89146e31e611e17d703ae9834d82794321e651b6ef156ade006227d231e7", - "size": 23587 + "sha256": "2f6378fbb718d4b31cf11d3047cee6b32af93cfbb932442da29dd05225881432", + "size": 23870 }, "th_14_icon_picker.js": { "sha256": "1df5c4bf82e68de24d7b89c852a4d9878768451effe086e8ddb86620ecc98c35", "size": 23906 }, "th_14_panels.js": { - "sha256": "1af01633720865a83a10a1e5261e3738d91be310195b014e17e579893eae90ee", - "size": 267207 + "sha256": "fcbab7b835c4f020c258d8ddd81675e486572bc140dc6db4aa3bee3f9c2aa27d", + "size": 268044 }, "th_14_schema_editor.js": { "sha256": "5669d0b5a16f770bed24eedee24203df57f7cbc7910c840931e533adac1ef146", @@ -80,5 +80,5 @@ }, "keyId": "toolhub-targets-2026-rsa3072", "schema": 2, - "version": 20260522213610 + "version": 20260522220033 } diff --git a/manifest.sig b/manifest.sig index d74ae0a..889027c 100644 --- a/manifest.sig +++ b/manifest.sig @@ -1 +1 @@ -ipKGsoLWacyAl7V4tyWIsocOwZpxQujuC2v/Rg4bMJ6FpSmLI7KdwL9RFIWw4qRHN9/37S+0pkIjGj1FQeJ9dvnw80po2GI9hcZufG6Us4CTWeJrdEuGCTBI38yvPduhl/Wmdg1aGLVx9GqIcG+ALOLXslaHt2WVVgJQMShiGsZwgNRbFQ0uXhvT6EHzz3o09CPoF1E0xelI2r6EVlCX+iJtbvbHlsuCtmidPEHICK1ks6AsDT+O9YyFqEEDw0KP0KBQ3Y9ej+3RfmwNOrvKrVsm3Y3glb1biKnlXfSIjlArr/mQK/C6snUV3vX4hsu6lYnyhQQoSpMvtbZpjsf5yGFPKkx11Dqhc1MeVSTszhCEUP13jPS95EEv9CToV0k1B4kI9uFTP57Jityvx5NruFarBUvEvzyJKATb7o4a15hdwDfyLK+1ei7xLxWr/j5qOYtbvMgAf+KnmiRQauJS4az23DLMLypr0Jor4oBXL/SUCXCX2e0IK0Om/e54bE9v +C96vTXwZOxNzf6dPnp6DLtQzgY1xdVSe+JAObGu78cZqXO4BNCooFVfLGN4/WaTICx6e6mJ/dtmRVnPtJVc39+EDSaDWUg1ELtD4pPW4u5a5r8qU0J7mCxpUvLcTowG0txvheU4Cu5FQqPdHuBgNiyS1J5pNu0WAHapVBhyR7PXgOA8gnzzSaYZyawO/tf6uG20nVS3cFnlcw+ImvmY0tdLUTnfoaRJZBZMDAy5P36oLZCb3NSoqKPSrNj2cWr6i0x+h5D1jdDxRDjBGpK/fRsJAh4CdZTch8pEQsHVlGakb5hLmGARF0WR3RMHOCVeJNj2LXza1ktx2apjfUPJj84neHBgTCj0BcfwrZ0VY52cwE7n5aJn9xdXMaOiPzlioF7fcN9gmMS6ib0+N9qpW2sqfSSXmiWVEuUvNS0f11w39WfzPI5UNE+rt5bwplIWCuiLPWu65wAewm5Fz+y49ysqYuhPJwUEfJ8HLn+wRJnFcaOdWGod2U3DSVLliwi5Y