feat(ui): frameless modern window frame with dark titlebar controls and sleek dark scrollbars
Build Windows Installer / build (push) Successful in 18m51s
Build Windows Installer / build (push) Successful in 18m51s
This commit is contained in:
5 files changed
+197
-6
No files matched your search
+72
-1
@@ -124,7 +124,7 @@ function renderShell() {
|
||||
const root = document.getElementById('app')!;
|
||||
const verText = state.appInfo?.version ? `v${state.appInfo.version}` : 'v2.0';
|
||||
root.innerHTML = `
|
||||
<header class="topbar">
|
||||
<header class="topbar" id="topbar">
|
||||
<div class="brand">
|
||||
<div class="brand-icon">▶</div>
|
||||
<span class="brand-title">ConvertGUI</span>
|
||||
@@ -140,6 +140,17 @@ function renderShell() {
|
||||
<div class="topbar-right">
|
||||
<button id="ffmpegStatusBtn" class="status-pill warn">${tr.ffmpegMissing}</button>
|
||||
<button id="langBtn">${state.lang.toUpperCase()}</button>
|
||||
<div class="win-controls" id="winControls">
|
||||
<button id="winMinBtn" class="win-btn" title="Свернуть">
|
||||
<svg width="10" height="1" viewBox="0 0 10 1"><rect width="10" height="1" fill="currentColor"/></svg>
|
||||
</button>
|
||||
<button id="winMaxBtn" class="win-btn" title="Развернуть">
|
||||
<svg id="winMaxIcon" width="10" height="10" viewBox="0 0 10 10" fill="none" stroke="currentColor" stroke-width="1.2"><rect x="0.6" y="0.6" width="8.8" height="8.8"/></svg>
|
||||
</button>
|
||||
<button id="winCloseBtn" class="win-btn close" title="Закрыть">
|
||||
<svg width="10" height="10" viewBox="0 0 10 10" stroke="currentColor" stroke-width="1.2"><line x1="0.5" y1="0.5" x2="9.5" y2="9.5"/><line x1="9.5" y1="0.5" x2="0.5" y2="9.5"/></svg>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
|
||||
@@ -899,6 +910,7 @@ function bindGlobalEvents() {
|
||||
|
||||
window.addEventListener('resize', () => {
|
||||
fitVideoStage();
|
||||
void syncMaximizedUI();
|
||||
});
|
||||
|
||||
window.addEventListener('keydown', (e) => {
|
||||
@@ -1285,7 +1297,66 @@ function bindEvents() {
|
||||
if (state.donePath) void api?.OpenOutputFile(state.donePath);
|
||||
});
|
||||
|
||||
// Window titlebar controls (frameless mode)
|
||||
el<'button'>('winMinBtn')?.addEventListener('click', async () => {
|
||||
if (window.runtime?.WindowMinimise) {
|
||||
window.runtime.WindowMinimise();
|
||||
} else {
|
||||
await api?.WindowMinimise();
|
||||
}
|
||||
});
|
||||
|
||||
const toggleMaximize = async () => {
|
||||
if (window.runtime?.WindowToggleMaximise) {
|
||||
window.runtime.WindowToggleMaximise();
|
||||
} else {
|
||||
await api?.WindowToggleMaximise();
|
||||
}
|
||||
await syncMaximizedUI();
|
||||
};
|
||||
|
||||
el<'button'>('winMaxBtn')?.addEventListener('click', () => {
|
||||
void toggleMaximize();
|
||||
});
|
||||
|
||||
el<'button'>('winCloseBtn')?.addEventListener('click', async () => {
|
||||
if (window.runtime?.WindowClose) {
|
||||
window.runtime.WindowClose();
|
||||
} else {
|
||||
await api?.WindowClose();
|
||||
}
|
||||
});
|
||||
|
||||
el<'header'>('topbar')?.addEventListener('dblclick', (e) => {
|
||||
const target = e.target as HTMLElement;
|
||||
if (target.closest('button, input, select, .file-pill')) return;
|
||||
void toggleMaximize();
|
||||
});
|
||||
|
||||
bindWheelControls();
|
||||
void syncMaximizedUI();
|
||||
}
|
||||
|
||||
async function syncMaximizedUI() {
|
||||
const api = appApi();
|
||||
let isMax = false;
|
||||
try {
|
||||
if (window.runtime?.WindowIsMaximised) {
|
||||
isMax = await window.runtime.WindowIsMaximised();
|
||||
} else if (api?.WindowIsMaximised) {
|
||||
isMax = await api.WindowIsMaximised();
|
||||
}
|
||||
} catch {
|
||||
// ignore
|
||||
}
|
||||
document.body.classList.toggle('maximized', isMax);
|
||||
const maxBtn = el<'button'>('winMaxBtn');
|
||||
if (maxBtn) {
|
||||
maxBtn.innerHTML = isMax
|
||||
? `<svg width="10" height="10" viewBox="0 0 10 10" fill="none" stroke="currentColor" stroke-width="1.1"><rect x="2.5" y="0.5" width="7" height="7"/><polyline points="2.5,2.5 0.5,2.5 0.5,9.5 7.5,9.5 7.5,7.5"/></svg>`
|
||||
: `<svg id="winMaxIcon" width="10" height="10" viewBox="0 0 10 10" fill="none" stroke="currentColor" stroke-width="1.2"><rect x="0.6" y="0.6" width="8.8" height="8.8"/></svg>`;
|
||||
maxBtn.title = isMax ? 'Восстановить' : 'Развернуть';
|
||||
}
|
||||
}
|
||||
|
||||
function setupWailsEvents() {
|
||||
|
||||
Reference in new issue
Block a user