mirror of
https://github.com/MasterAcnolo/Freedom-Loader.git
synced 2026-07-29 18:25:47 +02:00
feat: Implement topbar with custom window controls and actions
This commit is contained in:
32
main.js
32
main.js
@@ -77,6 +77,7 @@ async function createMainWindow() {
|
|||||||
height: 800,
|
height: 800,
|
||||||
minWidth: 750,
|
minWidth: 750,
|
||||||
minHeight: 800,
|
minHeight: 800,
|
||||||
|
frame:false,
|
||||||
webPreferences: {
|
webPreferences: {
|
||||||
nodeIntegration: false,
|
nodeIntegration: false,
|
||||||
contextIsolation: true,
|
contextIsolation: true,
|
||||||
@@ -118,6 +119,37 @@ ipcMain.on("set-progress", (event, percent) => {
|
|||||||
if (mainWindow) mainWindow.setProgressBar(percent / 100); // Electron attend 0 → 1
|
if (mainWindow) mainWindow.setProgressBar(percent / 100); // Electron attend 0 → 1
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Topbar window controls
|
||||||
|
ipcMain.on("window-minimize", () => {
|
||||||
|
if (mainWindow) mainWindow.minimize();
|
||||||
|
});
|
||||||
|
ipcMain.on("window-maximize", () => {
|
||||||
|
if (mainWindow) {
|
||||||
|
if (mainWindow.isMaximized()) {
|
||||||
|
mainWindow.unmaximize();
|
||||||
|
} else {
|
||||||
|
mainWindow.maximize();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
ipcMain.on("window-close", () => {
|
||||||
|
if (mainWindow) mainWindow.close();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Topbar custom actions
|
||||||
|
ipcMain.on("open-devtools", () => {
|
||||||
|
if (mainWindow) mainWindow.webContents.openDevTools({ mode: 'detach' });
|
||||||
|
});
|
||||||
|
ipcMain.on("open-logs", () => {
|
||||||
|
if (logsFolderPath) shell.openPath(logsFolderPath);
|
||||||
|
});
|
||||||
|
ipcMain.on("open-website", () => {
|
||||||
|
shell.openExternal("https://masteracnolo.github.io/FreedomLoader/index.html");
|
||||||
|
});
|
||||||
|
ipcMain.on("open-wiki", () => {
|
||||||
|
shell.openExternal("https://masteracnolo.github.io/FreedomLoader/pages/wiki.html");
|
||||||
|
});
|
||||||
|
|
||||||
// Menu
|
// Menu
|
||||||
function setupMenu() {
|
function setupMenu() {
|
||||||
const menuTemplate = [
|
const menuTemplate = [
|
||||||
|
|||||||
11
preload.js
11
preload.js
@@ -5,3 +5,14 @@ contextBridge.exposeInMainWorld("electronAPI", {
|
|||||||
selectDownloadFolder: () => ipcRenderer.invoke("select-download-folder"),
|
selectDownloadFolder: () => ipcRenderer.invoke("select-download-folder"),
|
||||||
setProgress: (percent) => ipcRenderer.send("set-progress", percent)
|
setProgress: (percent) => ipcRenderer.send("set-progress", percent)
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Contrôles de fenêtre et outils custom pour la topbar
|
||||||
|
contextBridge.exposeInMainWorld("topbarAPI", {
|
||||||
|
minimize: () => ipcRenderer.send("window-minimize"),
|
||||||
|
maximize: () => ipcRenderer.send("window-maximize"),
|
||||||
|
close: () => ipcRenderer.send("window-close"),
|
||||||
|
openDevTools: () => ipcRenderer.send("open-devtools"),
|
||||||
|
openLogs: () => ipcRenderer.send("open-logs"),
|
||||||
|
openWebsite: () => ipcRenderer.send("open-website"),
|
||||||
|
openWiki: () => ipcRenderer.send("open-wiki")
|
||||||
|
});
|
||||||
|
|||||||
1
public/assets/icon/close.svg
Normal file
1
public/assets/icon/close.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M128 128C92.7 128 64 156.7 64 192L64 448C64 483.3 92.7 512 128 512L512 512C547.3 512 576 483.3 576 448L576 192C576 156.7 547.3 128 512 128L128 128zM231 231C240.4 221.6 255.6 221.6 264.9 231L319.9 286L374.9 231C384.3 221.6 399.5 221.6 408.8 231C418.1 240.4 418.2 255.6 408.8 264.9L353.8 319.9L408.8 374.9C418.2 384.3 418.2 399.5 408.8 408.8C399.4 418.1 384.2 418.2 374.9 408.8L319.9 353.8L264.9 408.8C255.5 418.2 240.3 418.2 231 408.8C221.7 399.4 221.6 384.2 231 374.9L286 319.9L231 264.9C221.6 255.5 221.6 240.3 231 231z"/></svg>
|
||||||
|
After Width: | Height: | Size: 751 B |
1
public/assets/icon/maximize.svg
Normal file
1
public/assets/icon/maximize.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M128 128C92.7 128 64 156.7 64 192L64 448C64 483.3 92.7 512 128 512L512 512C547.3 512 576 483.3 576 448L576 192C576 156.7 547.3 128 512 128L128 128zM152 192L488 192C501.3 192 512 202.7 512 216C512 229.3 501.3 240 488 240L152 240C138.7 240 128 229.3 128 216C128 202.7 138.7 192 152 192z"/></svg>
|
||||||
|
After Width: | Height: | Size: 515 B |
1
public/assets/icon/minimize.svg
Normal file
1
public/assets/icon/minimize.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2025 Fonticons, Inc.--><path d="M64 480C64 462.3 78.3 448 96 448L544 448C561.7 448 576 462.3 576 480C576 497.7 561.7 512 544 512L96 512C78.3 512 64 497.7 64 480z"/></svg>
|
||||||
|
After Width: | Height: | Size: 360 B |
@@ -12,9 +12,23 @@
|
|||||||
<title></title>
|
<title></title>
|
||||||
|
|
||||||
<link rel="stylesheet" href="styles/styles.css">
|
<link rel="stylesheet" href="styles/styles.css">
|
||||||
|
<link rel="stylesheet" href="styles/layout/topbar.css">
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
<div class="topbar">
|
||||||
|
<div class="custom-controls">
|
||||||
|
<button id="devtools-btn" title="Dev Tools">Tools</button>
|
||||||
|
<button id="logs-btn" title="Logs">Logs</button>
|
||||||
|
<button id="website-btn" title="Website">Website</button>
|
||||||
|
<button id="wiki-btn" title="Wiki">Wiki</button>
|
||||||
|
</div>
|
||||||
|
<div class="window-controls">
|
||||||
|
<button id="minimize-btn" title="Réduire"><img src="assets/icon/minimize.svg"></button>
|
||||||
|
<button id="maximize-btn" title="Maximiser"><img src="assets/icon/maximize.svg"></button>
|
||||||
|
<button id="close-btn" title="Fermer"><img src="assets/icon/close.svg"></button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div class="theme-switcher">
|
<div class="theme-switcher">
|
||||||
<label for="themeSelect">Thème :</label>
|
<label for="themeSelect">Thème :</label>
|
||||||
@@ -86,6 +100,7 @@
|
|||||||
<script src="script/fetchinfo.js"></script>
|
<script src="script/fetchinfo.js"></script>
|
||||||
<script src="script/progressBar.js"></script>
|
<script src="script/progressBar.js"></script>
|
||||||
<script src="script/customthemes.js"></script>
|
<script src="script/customthemes.js"></script>
|
||||||
|
<script type="module" src="script/topbar.js"></script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
24
public/script/topbar.js
Normal file
24
public/script/topbar.js
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
// Ajout des listeners pour la topbar
|
||||||
|
function setupTopbarListeners() {
|
||||||
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
|
const { topbarAPI } = window;
|
||||||
|
if (!topbarAPI) return;
|
||||||
|
const minBtn = document.getElementById('minimize-btn');
|
||||||
|
const maxBtn = document.getElementById('maximize-btn');
|
||||||
|
const closeBtn = document.getElementById('close-btn');
|
||||||
|
const devtoolsBtn = document.getElementById('devtools-btn');
|
||||||
|
const logsBtn = document.getElementById('logs-btn');
|
||||||
|
const websiteBtn = document.getElementById('website-btn');
|
||||||
|
const wikiBtn = document.getElementById('wiki-btn');
|
||||||
|
|
||||||
|
if (minBtn) minBtn.onclick = () => topbarAPI.minimize();
|
||||||
|
if (maxBtn) maxBtn.onclick = () => topbarAPI.maximize();
|
||||||
|
if (closeBtn) closeBtn.onclick = () => topbarAPI.close();
|
||||||
|
if (devtoolsBtn) devtoolsBtn.onclick = () => topbarAPI.openDevTools();
|
||||||
|
if (logsBtn) logsBtn.onclick = () => topbarAPI.openLogs();
|
||||||
|
if (websiteBtn) websiteBtn.onclick = () => topbarAPI.openWebsite();
|
||||||
|
if (wikiBtn) wikiBtn.onclick = () => topbarAPI.openWiki();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
setupTopbarListeners();
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
.theme-switcher {
|
.theme-switcher {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 10px;
|
top: 60px;
|
||||||
right: 10px;
|
right: 10px;
|
||||||
background: #242424;
|
background: #242424;
|
||||||
padding: 8px 12px;
|
padding: 8px 12px;
|
||||||
|
|||||||
95
public/styles/layout/topbar.css
Normal file
95
public/styles/layout/topbar.css
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
.topbar {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
|
||||||
|
height: 48px;
|
||||||
|
width: 100vw;
|
||||||
|
|
||||||
|
background: #1f1f1f98;
|
||||||
|
color: #eaeaea;
|
||||||
|
|
||||||
|
-webkit-app-region: drag;
|
||||||
|
user-select: none;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* LEFT - custom buttons */
|
||||||
|
.custom-controls {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
gap: 6px;
|
||||||
|
padding-left: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* RIGHT - window buttons */
|
||||||
|
.window-controls {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* GLOBAL BUTTON RESET */
|
||||||
|
.topbar button {
|
||||||
|
border: none;
|
||||||
|
background: transparent;
|
||||||
|
color: inherit;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
-webkit-app-region: no-drag;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
|
transition: background 0.15s ease, transform 0.1s ease;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Custom buttons (Logs / Wiki / etc.) */
|
||||||
|
.custom-controls button {
|
||||||
|
height: 32px;
|
||||||
|
padding: 0 14px;
|
||||||
|
|
||||||
|
font-size: 15px;
|
||||||
|
border-radius: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-controls button:hover {
|
||||||
|
background: rgba(255, 255, 255, 0.12);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Window buttons (Windows style) */
|
||||||
|
.window-controls button {
|
||||||
|
width: 46px;
|
||||||
|
height: 48px;
|
||||||
|
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.window-controls button:hover {
|
||||||
|
background: rgba(255, 255, 255, 0.1);
|
||||||
|
}
|
||||||
|
|
||||||
|
.window-controls img {
|
||||||
|
width: 27px;
|
||||||
|
height: 27px;
|
||||||
|
pointer-events: none;
|
||||||
|
filter: invert(100%);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#close-btn:hover {
|
||||||
|
background: #e81123;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Active effect */
|
||||||
|
.topbar button:active {
|
||||||
|
background: rgba(255, 255, 255, 0.18);
|
||||||
|
transform: scale(0.9);
|
||||||
|
}
|
||||||
|
|
||||||
|
#close-btn:active {
|
||||||
|
background: #c50f1f;
|
||||||
|
transform: scale(0.9);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user