Update Settings Shell.

This commit is contained in:
Bruce
2025-11-29 23:02:15 +08:00
parent cf50b09bf0
commit 5796fb40e1
41 changed files with 515 additions and 383 deletions
+3
View File
@@ -39,6 +39,9 @@
byid: function(resid) { return ext.System.Resources.GetById(resid); },
nameToId: function(resname) { return ext.System.Resources.ToId(resname); },
idToName: function(resid) { return ext.System.Resources.ToName(resid); },
fromOthers: function(filepath, resid) { return ext.System.Resources.GetFromOthers(filepath, resid); },
fromFile: function(filepath, resid) { return ext.System.Resources.GetFromOthers(filepath, resid); },
fromfile: function(filepath, resid) { return ext.System.Resources.GetFromOthers(filepath, resid); },
},
Package: {
filepaths: function() {
+60
View File
@@ -482,5 +482,65 @@
var json = JSON.parse(window.external.IEFrame.ParseHtmlColor(str));
return new Color(json.r, json.g, json.b, json.a);
}
Color.getSuitableForegroundTextColor = function(backgroundColor, foregroundColorArray) {
// 将 0255 转为 W3C 的 01,并做 gamma 校正
function gammaCorrect(c) {
c /= 255;
if (c <= 0.03928) return c / 12.92;
return Math.pow((c + 0.055) / 1.055, 2.4);
}
// 计算相对亮度 L01
function relativeLuminance(color) {
var R = gammaCorrect(color.red);
var G = gammaCorrect(color.green);
var B = gammaCorrect(color.blue);
return 0.2126 * R + 0.7152 * G + 0.0722 * B;
}
// 计算对比度 (L1+0.05)/(L2+0.05)
function contrastRatio(l1, l2) {
var light = Math.max(l1, l2);
var dark = Math.min(l1, l2);
return (light + 0.05) / (dark + 0.05);
}
// 混合背景透明度:背景 alpha 与白色混合
function blendWithWhite(color) {
const a = (color.alpha !== undefined ? color.alpha : 255) / 255;
return {
red: color.red * a + 255 * (1 - a),
green: color.green * a + 255 * (1 - a),
blue: color.blue * a + 255 * (1 - a),
alpha: 255
};
}
// 透明背景视为与白色叠加
const bg = blendWithWhite(backgroundColor);
const bgL = relativeLuminance(bg);
// 找出和背景对比度最高的前景色
let bestColor = null;
let bestContrast = -1;
for (var i = 0; i < foregroundColorArray.length; i++) {
var fg = foregroundColorArray[i];
var fgBlended = blendWithWhite(fg); // 若前景也有透明度
var fgL = relativeLuminance(fgBlended);
var cr = contrastRatio(bgL, fgL);
if (cr > bestContrast) {
bestContrast = cr;
bestColor = fg;
}
}
return bestColor;
}
Color.Const = {
white: new Color(255, 255, 255),
black: new Color(0, 0, 0),
red: new Color(255, 0, 0),
green: new Color(0, 255, 0),
blue: new Color(0, 0, 255),
yellow: new Color(255, 255, 0),
cyan: new Color(0, 255, 255),
magenta: new Color(255, 0, 255),
transparent: new Color(0, 0, 0, 0),
};
module.exports = { Color: Color };
})(this);
+12
View File
@@ -1,5 +1,17 @@
(function(global) {
"use strict";
var storage = Bridge.External.Storage;
var path = storage.path;
var root = path.getDir(path.program);
var respath = path.combine(root, "reslib.dll");
var res = Bridge.Resources;
global.respath = respath;
global.getPublicRes = function(resId) {
return res.fromfile(respath, resId);
}
global.publicRes = function(resId) {
return getFileResPair(respath, resId);
}
function ready(e) {
function nextstep() {
+18 -1
View File
@@ -12,17 +12,27 @@
}
var byName = el.getAttribute('data-res-byname');
var byId = el.getAttribute('data-res-byid');
if ((byName && !Bridge.NString.empty(byName)) || (byId && parseInt(byId, 10) > 0)) {
var fromFile = el.getAttribute('data-res-fromfile');
if ((byName && !Bridge.NString.empty(byName)) || (byId && parseInt(byId, 10) > 0) || (fromFile && !Bridge.NString.empty(fromFile))) {
result.push(el);
}
}
return result; // 返回符合条件的元素数组
}
module.exports = {
getFileResPair: function(filepath, resid) {
return {
filepath: filepath,
resid: resid
};
}
};
module.exports = {
Resources: {
processAll: function() {
var nodes = getAllNodesHasResource();
var resources = Bridge.Resources;
for (var i = 0; i < nodes.length; i++) {
if (nodes[i].hasAttribute('data-res-byname')) {
var resName = nodes[i].getAttribute('data-res-byname');
@@ -30,6 +40,13 @@
} else if (nodes[i].hasAttribute('data-res-byid')) {
var resId = parseInt(nodes[i].getAttribute('data-res-byid'), 10);
nodes[i].textContent = Bridge.Resources.byid(resId);
} else if (nodes[i].hasAttribute('data-res-fromfile')) {
try {
var obj = eval(nodes[i].getAttribute('data-res-fromfile'));
nodes[i].textContent = resources.fromfile(obj.filepath, obj.resid);
} catch (e) {
nodes[i].textContent = "";
}
} else {
nodes[i].textContent = "";
}
+3 -3
View File
@@ -37,7 +37,7 @@
<header aria-label="Header content" role="banner" class="titlebanner" id="pagebanner" style="height: 120px;">
<button id="back" class="win-backbutton pagetitlewb-backbutton" onclick="Bridge.Frame.callEvent ('InvokeBackPage')" style="margin-left: 20px; transform: scale(0.72);" disabled></button>
<h2 class="titlearea win-type-ellipsis" id="apptitle" style="">
<span class="pagetitlewb-title" id="apptitlestr" style="margin-left: 10px; margin-right: 20px;">Settings</span>
<span class="pagetitlewb-title" id="apptitlestr" style="margin-left: 10px; margin-right: 20px;" data-res-byname="IDS_TITLE"></span>
</h2>
</header>
<nav class="container">
@@ -46,8 +46,8 @@
</nav>
</aside>
<main class="main right padding">
<h2>设置</h2>
<p>通过左侧的导航页,载入相应的设置。</p>
<h2 data-res-byname="IDS_GUIDE"></h2>
<p data-res-byname="IDS_GUIDETEXT"></p>
</main>
</div>
</div>
+2 -4
View File
@@ -26,6 +26,7 @@
<script type="text/javascript" src="../js/init.js"></script>
<script type="text/javascript" src="initsame.js"></script>
<link rel="stylesheet" type="text/css" href="page.css">
<script type="text/javascript" src="appinstaller/preinit.js"></script>
<script type="text/javascript" src="appinstaller/items.js"></script>
<script type="text/javascript" src="appinstaller/init.js"></script>
</head>
@@ -37,14 +38,11 @@
<header aria-label="Header content" role="banner" class="titlebanner" id="pagebanner" style="height: 120px;">
<button id="back" class="win-backbutton pagetitlewb-backbutton" onclick="Bridge.Frame.callEvent ('InvokeBackPage')" style="margin-left: 20px; transform: scale(0.72);"></button>
<h2 class="titlearea win-type-ellipsis" id="apptitle" style="">
<span class="pagetitlewb-title" id="apptitlestr" style="margin-left: 10px; margin-right: 20px;">Settings</span>
<span class="pagetitlewb-title" id="apptitlestr" style="margin-left: 10px; margin-right: 20px;" data-res-fromfile="getFileResPair(exepath, 300)"></span>
</h2>
</header>
<nav class="container">
<ul class="list">
<li role="button" tabindex="0">项1</li>
<li role="button" tabindex="0" class="selected">项2</li>
<li role="button" tabindex="0">项3</li>
</ul>
</nav>
</aside>
+14 -1
View File
@@ -26,13 +26,26 @@
<script type="text/javascript" src="../../js/init.js"></script>
<link rel="stylesheet" type="text/css" href="../page.css">
<link rel="stylesheet" type="text/css" href="../subpage.css">
<script type="text/javascript" src="preinit.js"></script>
<script type="text/javascript" src="initsame.js"></script>
</head>
<body>
<div class="section padding">
<h2>App Installer Settings</h2>
<h2 id="guide-title"></h2>
<p id="guide-desc" style="white-space: pre-wrap;"></p>
</div>
<script>
(function() {
"use strict";
var res = Bridge.Resources;
var stru = Bridge.String;
var title = document.getElementById("guide-title");
title.textContent = stru.format(res.byname("IDS_TITLEFORMAT"), res.fromfile(exepath, 300));
var text = document.getElementById("guide-desc");
text.textContent = res.byname("IDS_GUIDETEXT_COMMON");
})();
</script>
</body>
</html>
+3 -3
View File
@@ -8,9 +8,9 @@
};
}
var pages = {
general: getPage("appinstaller/general.html", "General"),
theme: getPage("appinstaller/theme.html", "Theme"),
update: getPage("update.html", "Update")
general: getPage("appinstaller/general.html", getPublicRes(101)),
theme: getPage("appinstaller/theme.html", getPublicRes(102)),
update: getPage("update.html", getPublicRes(103))
};
Object.defineProperty(global, "pages", {
get: function() {
@@ -0,0 +1,12 @@
(function(global) {
var storage = Bridge.External.Storage;
var path = storage.path;
var root = path.getDir(path.program);
var exepath = path.combine(root, "appinstaller.exe");
var id = "App";
var ve = Bridge.External.VisualElements.get(id);
var slideback = ve["BackgroundColor"];
global.slideback = slideback;
global.exepath = exepath;
global.visual = ve;
})(this);
+11 -1
View File
@@ -8,7 +8,17 @@
var content = guide.querySelector(".main");
var shead = slide.querySelector("header");
var list = slide.querySelector("ul");
try { slide.style.backgroundColor = Bridge.UI.themeColor; } catch (e) {}
var apptitle = shead.querySelector("#apptitle");
var backbtn = shead.querySelector("#back");
if (backbtn && backbtn.disabled) {
apptitle.style.marginLeft = backbtn.style.marginLeft;
} else {
apptitle.style.marginLeft = "";
}
try {
slide.style.backgroundColor = Bridge.UI.themeColor;
slide.style.color = Color.getSuitableForegroundTextColor(Color.parse(slide.style.backgroundColor), [Color.Const.white, Color.Const.black]);
} catch (e) {}
setTimeout(function() {
slide.style.transition = "all 0.5s cubic-bezier(0.1, 0.9, 0.2, 1)";
}, 0);
+10 -1
View File
@@ -1,5 +1,14 @@
(function(global) {
"use strict";
var res = Bridge.Resources;
var storage = Bridge.External.Storage;
var path = storage.path;
var root = path.getDir(path.program);
function getLibRes(libfilename, resid) {
var libpath = path.combine(root, libfilename);
return res.fromfile(libpath, resid);
}
function getSettingsItem(page, displayName) {
return {
@@ -8,7 +17,7 @@
};
}
var settingItems = {
appinstaller: getSettingsItem("appinstaller.html", "App Installer")
appinstaller: getSettingsItem("appinstaller.html", getLibRes("appinstaller.exe", 300))
};
Object.defineProperty(global, "settingPages", {
get: function() { return settingItems; }
+8 -2
View File
@@ -121,7 +121,7 @@ aside.left {
left: 0px;
width: 300px;
box-sizing: border-box;
padding: 0;
padding: 0 1px 0 0;
background-color: rgb(20, 0, 68);
color: white;
}
@@ -157,11 +157,12 @@ aside .container ul li {
align-content: center;
justify-content: flex-start;
align-items: center;
transition: all 0.3s cubic-bezier(0.1, 0.9, 0.2, 1);
}
aside .container ul li.selected {
/* background-color: rgba(101, 38, 254, 0.61); */
background-color: rgba(95, 95, 95, 0.45);
background-color: rgba(170, 170, 170, 0.45);
}
aside .container ul li:hover {
@@ -171,12 +172,17 @@ aside .container ul li:hover {
aside .container ul li:active {
background-color: white;
color: black;
transform: scale(0.9594);
}
aside .container ul li:focus {
border: 1px solid white;
}
#back:disabled {
display: none;
}
.main.right {
position: absolute;
top: 0px;