320 lines
8.9 KiB
JavaScript
320 lines
8.9 KiB
JavaScript
const style = document.createElement('style');
|
|
style.textContent = `
|
|
* {
|
|
margin: 0;
|
|
padding: 0;
|
|
box-sizing: border-box;
|
|
}
|
|
|
|
body {
|
|
background-color: #1e1e1e;
|
|
color: #e0e0e0;
|
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
|
|
display: flex;
|
|
flex-direction: column;
|
|
height: 100vh;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.__pywebview_mac-title-bar {
|
|
width: 100%;
|
|
height: 40px;
|
|
background-color: #2d2d2d;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: space-between;
|
|
padding: 0 12px;
|
|
-webkit-app-region: drag;
|
|
border-bottom: 1px solid #1a1a1a;
|
|
z-index: 1000;
|
|
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.3);
|
|
flex-shrink: 0;
|
|
}
|
|
|
|
.__pywebview_window-controls {
|
|
display: flex;
|
|
gap: 8px;
|
|
-webkit-app-region: no-drag;
|
|
}
|
|
|
|
.__pywebview_window-btn {
|
|
width: 14px;
|
|
height: 14px;
|
|
border-radius: 50%;
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
cursor: pointer;
|
|
transition: all 0.2s ease;
|
|
position: relative;
|
|
}
|
|
|
|
.__pywebview_close-btn {
|
|
background-color: #ff5f56;
|
|
border: 1px solid #e0443e;
|
|
}
|
|
|
|
.__pywebview_minimize-btn {
|
|
background-color: #ffbd2e;
|
|
border: 1px solid #d9a122;
|
|
}
|
|
|
|
.__pywebview_maximize-btn {
|
|
background-color: #27c93f;
|
|
border: 1px solid #1aad29;
|
|
}
|
|
|
|
.__pywebview_window-btn:hover {
|
|
filter: brightness(1.1);
|
|
}
|
|
|
|
.__pywebview_window-title {
|
|
font-size: 13px;
|
|
color: #a0a0a0;
|
|
font-weight: 500;
|
|
user-select: none;
|
|
-webkit-app-region: drag;
|
|
padding: 0 10px;
|
|
}
|
|
|
|
.__pywebview_content {
|
|
padding: 20px;
|
|
flex-grow: 1;
|
|
overflow: auto;
|
|
}
|
|
|
|
body:not(.__pywebview_window-inactive) .__pywebview_mac-title-bar {
|
|
background-color: #2d2d2d;
|
|
}
|
|
|
|
body.__pywebview_window-inactive .__pywebview_mac-title-bar {
|
|
background-color: #252525;
|
|
}
|
|
|
|
body.__pywebview_window-inactive .__pywebview_window-btn {
|
|
filter: grayscale(50%) brightness(0.7);
|
|
}
|
|
|
|
html {
|
|
height: 100%;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.__pywebview_resizer {
|
|
position: absolute;
|
|
background-color: rgba(0, 0, 0, 0.2);
|
|
transition: background-color 0.2s;
|
|
}
|
|
.__pywebview_resizer:hover {
|
|
background-color: rgba(0, 0, 0, 0.4);
|
|
}
|
|
.__pywebview_resizer-right {
|
|
top: 0;
|
|
right: 0;
|
|
width: 5px;
|
|
height: 100%;
|
|
cursor: ew-resize;
|
|
}
|
|
.__pywebview_resizer-bottom {
|
|
bottom: 0;
|
|
left: 0;
|
|
width: 100%;
|
|
height: 5px;
|
|
cursor: ns-resize;
|
|
}
|
|
.__pywebview_resizer-corner {
|
|
bottom: 0;
|
|
right: 0;
|
|
width: 15px;
|
|
height: 15px;
|
|
cursor: nwse-resize;
|
|
background-color: rgba(0, 0, 0, 0.3);
|
|
z-index: 10;
|
|
}
|
|
`;
|
|
|
|
// 创建标题栏HTML结构
|
|
function createTitleBar() {
|
|
const titleBar = document.createElement('div');
|
|
titleBar.className = '__pywebview_mac-title-bar';
|
|
titleBar.setAttribute('pywebview-drag-region', '');
|
|
|
|
// 窗口控制按钮
|
|
const controls = document.createElement('div');
|
|
controls.className = '__pywebview_window-controls';
|
|
|
|
const closeBtn = document.createElement('div');
|
|
closeBtn.className = '__pywebview_window-btn __pywebview_close-btn';
|
|
closeBtn.id = '__pywebview_close-btn';
|
|
|
|
const minimizeBtn = document.createElement('div');
|
|
minimizeBtn.className = '__pywebview_window-btn __pywebview_minimize-btn';
|
|
minimizeBtn.id = '__pywebview_minimize-btn';
|
|
|
|
const maximizeBtn = document.createElement('div');
|
|
maximizeBtn.className = '__pywebview_window-btn __pywebview_maximize-btn';
|
|
maximizeBtn.id = '__pywebview_maximize-btn';
|
|
|
|
controls.appendChild(closeBtn);
|
|
controls.appendChild(minimizeBtn);
|
|
controls.appendChild(maximizeBtn);
|
|
|
|
// 窗口标题
|
|
const title = document.createElement('div');
|
|
title.className = '__pywebview_window-title';
|
|
title.id = '__pywebview_window-title';
|
|
title.textContent = document.title;
|
|
|
|
// 右侧占位
|
|
const spacer = document.createElement('div');
|
|
spacer.style.width = '70px';
|
|
|
|
// 组装标题栏
|
|
titleBar.appendChild(controls);
|
|
titleBar.appendChild(title);
|
|
titleBar.appendChild(spacer);
|
|
|
|
return titleBar;
|
|
}
|
|
|
|
// 初始化函数
|
|
function initMacTitleBar() {
|
|
// 注入样式
|
|
document.head.appendChild(style);
|
|
|
|
// 创建并插入标题栏
|
|
const titleBar = createTitleBar();
|
|
document.body.insertBefore(titleBar, document.body.firstChild);
|
|
|
|
// 添加事件监听
|
|
setupEventListeners();
|
|
}
|
|
|
|
// 设置事件监听
|
|
function setupEventListeners() {
|
|
const closeBtn = document.getElementById('__pywebview_close-btn');
|
|
const minimizeBtn = document.getElementById('__pywebview_minimize-btn');
|
|
const maximizeBtn = document.getElementById('__pywebview_maximize-btn');
|
|
const titleBar = document.querySelector('.__pywebview_mac-title-bar');
|
|
|
|
closeBtn.addEventListener('click', () => {
|
|
console.log('Close window clicked');
|
|
window.pywebview.api.Close();
|
|
});
|
|
|
|
minimizeBtn.addEventListener('click', () => {
|
|
console.log('Minimize window clicked');
|
|
window.pywebview.api.Min();
|
|
});
|
|
|
|
maximizeBtn.addEventListener('click', () => {
|
|
console.log('Maximize window clicked');
|
|
window.pywebview.api.Max();
|
|
});
|
|
|
|
titleBar.addEventListener('dblclick', (e) => {
|
|
if (e.target === titleBar || e.target.classList.contains('__pywebview_window-title')) {
|
|
console.log('Title bar double clicked - toggle maximize');
|
|
window.pywebview.api.Max();
|
|
}
|
|
});
|
|
|
|
// 模拟窗口激活状态变化
|
|
document.addEventListener('mousedown', () => {
|
|
document.body.classList.remove('__pywebview_window-inactive');
|
|
});
|
|
}
|
|
|
|
// 当DOM加载完成后初始化
|
|
if (document.readyState === 'loading') {
|
|
document.addEventListener('DOMContentLoaded', initMacTitleBar);
|
|
} else {
|
|
initMacTitleBar();
|
|
}
|
|
|
|
// 调整大小功能实现
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
// Create resizers
|
|
const resizerRight = document.createElement('div');
|
|
resizerRight.className = '__pywebview_resizer __pywebview_resizer-right';
|
|
resizerRight.id = '__pywebview_resizerRight';
|
|
|
|
const resizerBottom = document.createElement('div');
|
|
resizerBottom.className = '__pywebview_resizer __pywebview_resizer-bottom';
|
|
resizerBottom.id = '__pywebview_resizerBottom';
|
|
|
|
const resizerCorner = document.createElement('div');
|
|
resizerCorner.className = '__pywebview_resizer __pywebview_resizer-corner';
|
|
resizerCorner.id = '__pywebview_resizerCorner';
|
|
|
|
// Append all elements to body
|
|
document.body.appendChild(resizerRight);
|
|
document.body.appendChild(resizerBottom);
|
|
document.body.appendChild(resizerCorner);
|
|
const sizeInfo = document.getElementById('__pywebview_sizeInfo');
|
|
|
|
let isResizing = false;
|
|
let resizeDirection = '';
|
|
let startX, startY, startWidth, startHeight;
|
|
|
|
// 鼠标按下事件 - 右边框
|
|
resizerRight.addEventListener('mousedown', function(e) {
|
|
isResizing = true;
|
|
resizeDirection = 'right';
|
|
startX = e.clientX;
|
|
startWidth = window.innerWidth;
|
|
document.body.style.cursor = 'ew-resize';
|
|
e.preventDefault();
|
|
});
|
|
|
|
// 鼠标按下事件 - 下边框
|
|
resizerBottom.addEventListener('mousedown', function(e) {
|
|
isResizing = true;
|
|
resizeDirection = 'bottom';
|
|
startY = e.clientY;
|
|
startHeight = window.innerHeight;
|
|
document.body.style.cursor = 'ns-resize';
|
|
e.preventDefault();
|
|
});
|
|
|
|
// 鼠标按下事件 - 右下角
|
|
resizerCorner.addEventListener('mousedown', function(e) {
|
|
isResizing = true;
|
|
resizeDirection = 'corner';
|
|
startX = e.clientX;
|
|
startY = e.clientY;
|
|
startWidth = window.innerWidth;
|
|
startHeight = window.innerHeight;
|
|
document.body.style.cursor = 'nwse-resize';
|
|
e.preventDefault();
|
|
});
|
|
|
|
// 鼠标移动事件
|
|
document.addEventListener('mousemove', function(e) {
|
|
if (!isResizing) return;
|
|
|
|
let newWidth = startWidth;
|
|
let newHeight = startHeight;
|
|
|
|
if (resizeDirection === 'right' || resizeDirection === 'corner') {
|
|
newWidth = Math.max(300, startWidth + (e.clientX - startX));
|
|
}
|
|
|
|
if (resizeDirection === 'bottom' || resizeDirection === 'corner') {
|
|
newHeight = Math.max(200, startHeight + (e.clientY - startY));
|
|
}
|
|
|
|
// 通过 pywebview API 调整窗口大小
|
|
pywebview.api.resizeWindow(newWidth, newHeight);
|
|
});
|
|
|
|
// 鼠标释放事件
|
|
document.addEventListener('mouseup', function() {
|
|
isResizing = false;
|
|
resizeDirection = '';
|
|
document.body.style.cursor = '';
|
|
});
|
|
|
|
// 初始化显示
|
|
updateSizeInfo();
|
|
}); |