自定义窗口标题栏,增加窗口置顶功能

This commit is contained in:
purocean
2019-08-19 20:10:52 +08:00
parent 386890ecab
commit 127e38159e
8 changed files with 152 additions and 5 deletions
Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

+1
View File
@@ -0,0 +1 @@
<svg width='11' height='11' viewBox='0 0 11 11' fill='none' xmlns='http://www.w3.org/2000/svg'><path d='M6.279 5.5L11 10.221l-.779.779L5.5 6.279.779 11 0 10.221 4.721 5.5 0 .779.779 0 5.5 4.721 10.221 0 11 .779 6.279 5.5z' fill='#000'/></svg>

After

Width:  |  Height:  |  Size: 242 B

+1
View File
@@ -0,0 +1 @@
<svg width='11' height='11' viewBox='0 0 11 11' fill='none' xmlns='http://www.w3.org/2000/svg'><path d='M11 0v11H0V0h11zM9.899 1.101H1.1V9.9h8.8V1.1z' fill='#000'/></svg>

After

Width:  |  Height:  |  Size: 170 B

+1
View File
@@ -0,0 +1 @@
<svg width='11' height='11' viewBox='0 0 11 11' fill='none' xmlns='http://www.w3.org/2000/svg'><path d='M11 4.399V5.5H0V4.399h11z' fill='#000'/></svg>

After

Width:  |  Height:  |  Size: 150 B

@@ -0,0 +1 @@
<svg width='11' height='11' viewBox='0 0 11 11' fill='none' xmlns='http://www.w3.org/2000/svg'><path d='M11 8.798H8.798V11H0V2.202h2.202V0H11v8.798zm-3.298-5.5h-6.6v6.6h6.6v-6.6zM9.9 1.1H3.298v1.101h5.5v5.5h1.1v-6.6z' fill='#000'/></svg>

After

Width:  |  Height:  |  Size: 237 B

+144 -2
View File
@@ -1,28 +1,73 @@
<template>
<div class="title-bar" :style="saved ? '' : 'background: orange'">
<h4 class="title"> {{statusText}}</h4>
<h4 class="title">
<img v-if="win" @dblclick="close" class="logo" src="~@/assets/icon.png" alt="logo">
<span>{{statusText}}</span>
</h4>
<div class="action" v-if="win">
<div title="置顶窗口" :class="{btn: true, pin: true, ontop: isAlwaysOnTop}" @click="toggleAlwaysOnTop">
<y-icon class="pin-icon" name="thumbtack"></y-icon>
</div>
<div class="btn" @click="minimize">
<div class="icon minimize"></div>
</div>
<div v-if="isMaximized" class="btn" @click="unmaximize">
<div class="icon unmaximize"></div>
</div>
<div v-else class="btn" @click="maximize">
<div class="icon maximize"></div>
</div>
<div class="btn" @click="close">
<div class="icon close"></div>
</div>
</div>
</div>
</template>
<script>
import { mapState } from 'vuex'
import env from '@/lib/env'
import 'vue-awesome/icons/thumbtack'
const isElectron = env.isElectron
export default {
name: 'title-bar',
data () {
return {
win: null,
isMaximized: false,
isAlwaysOnTop: false,
}
},
mounted () {
if (!isElectron) {
window.onbeforeunload = () => {
return !this.saved || null
}
}
if (isElectron && env.require) {
this.win = env.require('electron').remote.getCurrentWindow()
this.isMaximized = this.win.isMaximized()
this.win.on('maximize', this.changeWindowStatus)
this.win.on('restore', this.changeWindowStatus)
this.win.on('unmaximize', this.changeWindowStatus)
this.win.on('always-on-top-changed', this.changeWindowStatus)
}
},
beforeDestroy () {
if (!isElectron) {
window.onbeforeunload = null
}
if (this.win) {
this.win.removeListener('maximize', this.changeWindowStatus)
this.win.removeListener('restore', this.changeWindowStatus)
this.win.removeListener('unmaximize', this.changeWindowStatus)
this.win.removeListener('minimize', this.changeWindowStatus)
this.win.removeListener('always-on-top-changed', this.changeWindowStatus)
}
},
computed: {
...mapState('app', ['currentFile', 'savedAt', 'previousContent', 'currentContent']),
@@ -68,7 +113,32 @@ export default {
window.documentSaved = val
},
},
}
},
methods: {
changeWindowStatus () {
if (this.win) {
this.isMaximized = this.win.isMaximized()
this.isAlwaysOnTop = this.win.isAlwaysOnTop()
}
},
toggleAlwaysOnTop () {
this.win && this.win.setAlwaysOnTop(!this.win.isAlwaysOnTop())
},
unmaximize () {
this.win && this.win.unmaximize()
},
minimize () {
this.win && this.win.minimize()
},
maximize () {
// 最大化后取消窗口置顶
this.win && this.win.maximize()
this.win && this.win.setAlwaysOnTop(false)
},
close () {
this.win && this.win.close()
},
},
}
</script>
@@ -82,10 +152,82 @@ export default {
display: flex;
align-items: center;
justify-content: center;
-webkit-user-select: none;
-webkit-app-region: drag;
}
.title {
margin: 0;
text-align: center;
height: 100%;
display: flex;
align-items: center;
}
.logo {
height: 60%;
margin: 0 5px;
-webkit-app-region: no-drag;
}
.action {
display: flex;
flex-grow: 0;
flex-shrink: 0;
text-align: center;
position: relative;
z-index: 3000;
-webkit-app-region: no-drag;
height: 100%;
width: 138px;
margin-left: auto;
}
.action .btn {
display: inline-block;
-webkit-app-region: no-drag;
height: 100%;
width: 33.34%;
}
.action .icon {
background-color: #cccccc;
height: 100%;
width: 100%;
mask-size: 23.1%;
}
.action .icon.unmaximize {
mask: url(~@/assets/window-unmaximize.svg) no-repeat 50% 50%;
}
.action .icon.maximize {
mask: url(~@/assets/window-maximize.svg) no-repeat 50% 50%;
}
.action .icon.minimize {
mask: url(~@/assets/window-minimize.svg) no-repeat 50% 50%;
}
.action .icon.close {
mask: url(~@/assets/window-close.svg) no-repeat 50% 50%;
}
.action .btn:hover {
background-color: hsla(0, 0%, 100%, .1)
}
.action .btn.pin {
display: flex;
align-items: center;
justify-content: center;
}
.action .btn.pin.ontop {
background-color: hsla(0, 0%, 100%, .3)
}
.action .btn.pin .pin-icon {
fill: hsla(0, 0%, 100%, .5)
}
</style>
+4 -3
View File
@@ -32,8 +32,9 @@ const createWindow = () => {
win = new BrowserWindow({
maximizable: true,
show: false,
minWidth: 700,
minWidth: 800,
minHeight: 500,
frame: false,
backgroundColor: '#282a2b',
webPreferences: {
webSecurity: false,
@@ -41,7 +42,7 @@ const createWindow = () => {
},
})
win.maximize()
// win.maximize()
win.show()
win.setMenu(null)
@@ -90,7 +91,7 @@ const showWindow = () => {
win.setSkipTaskbar(false)
win.show()
}
if (win.isFocused() && win.isVisible()) {
if (win.isVisible()) {
hide()
} else {
// 先隐藏再显示,以便在 windows 10 当前虚拟窗口展示