add custom titlebar

This commit is contained in:
jeffvli
2021-08-05 00:08:57 -07:00
parent 0a738a5d46
commit af86b58776
57 changed files with 229 additions and 1 deletions

View File

@@ -4,6 +4,7 @@ import { Container, Content, Footer } from 'rsuite';
import classNames from 'classnames';
import Sidebar from './Sidebar';
import '../../styles/Layout.global.css';
import Titlebar from './Titlebar';
const Layout = ({ footer, children }: any) => {
const [expandSidebar, setExpandSidebar] = useState(true);
@@ -50,6 +51,7 @@ const Layout = ({ footer, children }: any) => {
return (
<>
<Titlebar />
<Sidebar
expand={expandSidebar}
handleToggle={handleToggle}

View File

@@ -0,0 +1,53 @@
import React from 'react';
import '../../styles/Titlebar.global.css';
const Titlebar = () => {
return (
<header id="titlebar">
<div id="drag-region">
<div id="window-title">
<span>{document.title}</span>
</div>
<div id="window-controls">
<div className="button" id="min-button">
<img
className="icon"
srcSet="icons/min-w-10.png 1x, icons/min-w-12.png 1.25x, icons/min-w-15.png 1.5x, icons/min-w-15.png 1.75x, icons/min-w-20.png 2x, icons/min-w-20.png 2.25x, icons/min-w-24.png 2.5x, icons/min-w-30.png 3x, icons/min-w-30.png 3.5x"
draggable="false"
alt=""
/>
</div>
<div className="button" id="max-button">
<img
className="icon"
srcSet="icons/max-w-10.png 1x, icons/max-w-12.png 1.25x, icons/max-w-15.png 1.5x, icons/max-w-15.png 1.75x, icons/max-w-20.png 2x, icons/max-w-20.png 2.25x, icons/max-w-24.png 2.5x, icons/max-w-30.png 3x, icons/max-w-30.png 3.5x"
draggable="false"
alt=""
/>
</div>
<div className="button" id="restore-button">
<img
className="icon"
srcSet="icons/restore-w-10.png 1x, icons/restore-w-12.png 1.25x, icons/restore-w-15.png 1.5x, icons/restore-w-15.png 1.75x, icons/restore-w-20.png 2x, icons/restore-w-20.png 2.25x, icons/restore-w-24.png 2.5x, icons/restore-w-30.png 3x, icons/restore-w-30.png 3.5x"
draggable="false"
alt=""
/>
</div>
<div className="button" id="close-button">
<img
className="icon"
srcSet="icons/close-w-10.png 1x, icons/close-w-12.png 1.25x, icons/close-w-15.png 1.5x, icons/close-w-15.png 1.75x, icons/close-w-20.png 2x, icons/close-w-20.png 2.25x, icons/close-w-24.png 2.5x, icons/close-w-30.png 3x, icons/close-w-30.png 3.5x"
draggable="false"
alt=""
/>
</div>
</div>
</div>
</header>
);
};
export default Titlebar;

BIN
src/icons/close-k-10.png Normal file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
src/icons/close-k-12.png Normal file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
src/icons/close-k-15.png Normal file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
src/icons/close-k-20.png Normal file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
src/icons/close-k-24.png Normal file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
src/icons/close-k-30.png Normal file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
src/icons/close-w-10.png Normal file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
src/icons/close-w-12.png Normal file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
src/icons/close-w-15.png Normal file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
src/icons/close-w-20.png Normal file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
src/icons/close-w-24.png Normal file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
src/icons/close-w-30.png Normal file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
src/icons/max-k-10.png Normal file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
src/icons/max-k-12.png Normal file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
src/icons/max-k-15.png Normal file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
src/icons/max-k-20.png Normal file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
src/icons/max-k-24.png Normal file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
src/icons/max-k-30.png Normal file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
src/icons/max-w-10.png Normal file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
src/icons/max-w-12.png Normal file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
src/icons/max-w-15.png Normal file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
src/icons/max-w-20.png Normal file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
src/icons/max-w-24.png Normal file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
src/icons/max-w-30.png Normal file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
src/icons/min-k-10.png Normal file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
src/icons/min-k-12.png Normal file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

BIN
src/icons/min-k-15.png Normal file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
src/icons/min-k-20.png Normal file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
src/icons/min-k-24.png Normal file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
src/icons/min-k-30.png Normal file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
src/icons/min-w-10.png Normal file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
src/icons/min-w-12.png Normal file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

BIN
src/icons/min-w-15.png Normal file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
src/icons/min-w-20.png Normal file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
src/icons/min-w-24.png Normal file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
src/icons/min-w-30.png Normal file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
src/icons/restore-k-10.png Normal file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
src/icons/restore-k-12.png Normal file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
src/icons/restore-k-15.png Normal file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
src/icons/restore-k-20.png Normal file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
src/icons/restore-k-24.png Normal file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
src/icons/restore-k-30.png Normal file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
src/icons/restore-w-10.png Normal file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
src/icons/restore-w-12.png Normal file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

BIN
src/icons/restore-w-15.png Normal file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
src/icons/restore-w-20.png Normal file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
src/icons/restore-w-24.png Normal file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
src/icons/restore-w-30.png Normal file
View File

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

@@ -75,10 +75,12 @@ const createWindow = async () => {
webPreferences: {
nodeIntegration: true,
enableRemoteModule: true,
preload: path.join(__dirname, 'preload.ts'), // Add custom titlebar functionality
},
autoHideMenuBar: true,
minWidth: 800,
minHeight: 600,
frame: false,
});
mainWindow.loadURL(`file://${__dirname}/index.html`);

50
src/preload.ts Normal file
View File

@@ -0,0 +1,50 @@
import { remote } from 'electron';
const win = remote.getCurrentWindow(); /* Note this is different to the
html global `window` variable */
window.onbeforeunload = () => {
/* If window is reloaded, remove win event listeners
(DOM element listeners get auto garbage collected but not
Electron win listeners as the win is not dereferenced unless closed) */
win.removeAllListeners();
};
function handleWindowControls() {
// Make minimise/maximise/restore/close buttons work when they are clicked
document.getElementById('min-button')?.addEventListener('click', () => {
win.minimize();
});
document.getElementById('max-button')?.addEventListener('click', () => {
win.maximize();
});
document.getElementById('restore-button')?.addEventListener('click', () => {
win.unmaximize();
});
document.getElementById('close-button')?.addEventListener('click', () => {
win.close();
});
function toggleMaxRestoreButtons() {
if (win.isMaximized()) {
document.body.classList.add('maximized');
} else {
document.body.classList.remove('maximized');
}
}
// Toggle maximise/restore buttons when maximisation/unmaximisation occurs
toggleMaxRestoreButtons();
win.on('maximize', toggleMaxRestoreButtons);
win.on('unmaximize', toggleMaxRestoreButtons);
}
// When document has loaded, initialise
document.onreadystatechange = () => {
if (document.readyState === 'complete') {
handleWindowControls();
}
};

View File

@@ -12,10 +12,19 @@ body {
height: 100%;
}
body {
border: 1px solid #48545c;
overflow-y: hidden;
}
#root {
min-height: 100%;
}
h1 {
font-size: 30px !important;
}
.rs-panel-heading {
padding-bottom: 5px !important;
}

View File

@@ -23,5 +23,5 @@
}
.container__page {
height: 100vh;
height: 100%;
}

View File

@@ -1,5 +1,6 @@
.container__sidebar {
position: fixed;
top: 33px; /* Account for custom titlebar */
z-index: 1;
}

View File

@@ -0,0 +1,110 @@
@media (-webkit-device-pixel-ratio: 1.5),
(device-pixel-ratio: 1.5),
(-webkit-device-pixel-ratio: 2),
(device-pixel-ratio: 2),
(-webkit-device-pixel-ratio: 3),
(device-pixel-ratio: 3) {
#window-controls .icon {
width: 10px;
height: 10px;
}
}
#main {
height: calc(100% - 32px);
margin-top: 32px;
padding: 20px;
overflow-y: auto;
}
#titlebar {
display: block;
position: fixed;
height: 32px;
width: calc(100% - 2px); /*Compensate for body 1px border*/
background: #1a1d24;
padding: 4px;
color: #fff;
}
#titlebar #drag-region {
width: 100%;
height: 100%;
-webkit-app-region: drag;
}
#window-controls {
display: grid;
grid-template-columns: repeat(3, 46px);
position: absolute;
top: 0;
right: 0;
height: 100%;
}
#window-controls .button {
grid-row: 1 / span 1;
display: flex;
justify-content: center;
align-items: center;
width: 100%;
height: 100%;
}
#min-button {
grid-column: 1;
}
#max-button,
#restore-button {
grid-column: 2;
}
#close-button {
grid-column: 3;
}
#window-controls {
-webkit-app-region: no-drag;
}
#window-controls .button {
user-select: none;
}
#window-controls .button:hover {
background: rgba(255, 255, 255, 0.1);
}
#window-controls .button:active {
background: rgba(255, 255, 255, 0.2);
}
#close-button:hover {
background: #e81123 !important;
}
#close-button:active {
background: #f1707a !important;
}
#close-button:active .icon {
filter: invert(1);
}
#restore-button {
display: none !important;
}
.maximized #titlebar {
width: 100%;
padding: 0;
}
#window-title {
margin-left: 12px;
}
.maximized #restore-button {
display: flex !important;
}
.maximized #max-button {
display: none;
}

View File

@@ -3,6 +3,7 @@
@table-border-color: #0f131a;
// Sidenav
@sidenav-default-bg: #0f131a;
@sidenav-collapse-transition-config: 0s;
// Panel