Electron Adventures: 에피소드 34: 애플리케이션 메뉴
20891 단어 electronsveltejavascript
글쎄, 이것은 예상보다 훨씬 더 많은 문제에 직면합니다.
Menu.setApplicationMenu
를 호출하면 종료, 복사, 붙여넣기, 다시 로드, 개발자 도구 등과 같은 유용한 작업이 있는 전체 기본 메뉴가 지워집니다. Menu.getApplicationMenu
는 수정할 수 있는 기본 메뉴를 반환하지 않습니다. 설정하지 않은 경우 null
가 됩니다. 기본 메뉴에서 항목을 추가할 수 있는 방법이 없습니다. 망할 항목 전체를 교체해야 합니다. ! 이것은 부끄러운 일이며, Electron은 정말로 문제를 해결해야 합니다. 예, 결국 전체를 교체해야 하지만 이 시점에서 개발을 비참하게 만듭니다. 그래서 엄청난 두통.
장점은 일단 문제를 해결하면 모든 응용 프로그램 명령을 메뉴에 넣고 모든 키보드 단축키 논리를 처리하도록 할 수 있다는 것입니다. 활성 응용 프로그램 바로 가기와 함께 보이지 않는 메뉴 항목을 추가하여 메뉴를 작게 유지하면서 바로 가기를 가질 수도 있지만 솔직히 Javascript에서 키보드 바로 가기를 처리하는 것은 로켓 과학이 아니므로 이 작업을 수행하지 않을 것입니다.
메뉴 만들기
I had to dig the default menu out of Electron source code 복사하여 붙여넣습니다. 기본적으로 npm 패키지도 있지만 이전 버전입니다.
메뉴는 완전히 정적이므로 한 번만 설정하면 됩니다. 애플리케이션 상태에 따라 수정해야 한다면 이 코드는 훨씬 더 많은 작업을 수행해야 합니다.
다음은
main/menu.js
입니다.let { Menu } = require("electron")
let isMac = process.platform === "darwin"
let defaultMenuTemplate = [
...(isMac ? [{ role: "appMenu" }] : []),
{ role: "fileMenu" },
{ role: "editMenu" },
{ role: "viewMenu" },
{ role: "windowMenu" },
]
let extraMenuTemplate = [
{
label: "Box",
submenu: [
{
label: "Box 1",
click: (item, window) => window.webContents.send("menuevent", "app", "changeBox", "box-1"),
},
{
label: "Box 2",
click: (item, window) => window.webContents.send("menuevent", "app", "changeBox", "box-2"),
},
{
label: "Box 3",
click: (item, window) => window.webContents.send("menuevent", "app", "changeBox", "box-3"),
},
{
label: "Box 4",
click: (item, window) => window.webContents.send("menuevent", "app", "changeBox", "box-4"),
},
],
},
{
label: "BoxEdit",
submenu: [
{
label: "Cut",
click: (item, window) => window.webContents.send("menuevent", "activeBox", "cut"),
},
{
label: "Copy",
click: (item, window) => window.webContents.send("menuevent", "activeBox", "copy"),
},
{
label: "Paste",
click: (item, window) => window.webContents.send("menuevent", "activeBox", "paste"),
},
],
},
]
let menu = Menu.buildFromTemplate([
...defaultMenuTemplate,
...extraMenuTemplate ,
])
module.exports = {menu}
해당 이벤트가 바로 이벤트 버스로 가는 것처럼 보입니까? 네 그렇습니다!
index.js
let { app, BrowserWindow, Menu } = require("electron")
let { menu } = require("./main/menu")
function createWindow() {
let win = new BrowserWindow({
webPreferences: {
preload: `${__dirname}/preload.js`,
},
})
win.maximize()
win.loadURL("http://localhost:5000/")
}
Menu.setApplicationMenu(menu)
app.on("ready", createWindow)
app.on("window-all-closed", () => {
app.quit()
})
세 가지만 수정하면 됩니다.
menu
에서 새 정적main/menu.js
가져오기Menu
에서 electron
수입Menu.setApplicationMenu(menu)
로 세트preload.js
이벤트를 목적지로 전달하기 전에 이벤트를 약간 반송해야 합니다. 따라서 먼저 사전 로드는 이벤트 핸들러를 설정하고 프런트엔드에 노출해야 합니다.
let { contextBridge, ipcRenderer } = require("electron")
let onMenuEvent = (callback) => {
ipcRenderer.on("menuevent", callback)
}
contextBridge.exposeInMainWorld(
"api", { onMenuEvent }
)
모든 메뉴 이벤트에 대한 핸들러가 하나뿐이므로 매우 간단합니다. 하지만 복잡하거나 동적인 작업을 수행했다면 다음과 같은 추가 코드가 필요합니다.
contextBridge.exposeInMainWorld(
"api", { onMenuEvent, setMenu }
)
src/App.svelte
Keyboard
논리가 자체 구성 요소에 있는 것처럼 AppMenu
도 마찬가지입니다. App
는 구성 요소 트리에 추가하기만 하면 됩니다. 나머지 파일은 이전과 같습니다.<script>
import AppMenu from "./AppMenu.svelte"
</script>
<div class="app">
<Box id="box-1" />
<Box id="box-2" />
<Box id="box-3" />
<Box id="box-4" />
<Footer />
</div>
<Keyboard />
<AppMenu />
src/AppMenu.svelte
그리고 마지막으로
menuevent
에 관심이 있다고 사전 로드에 알려야 합니다. 그런 다음 수신한 내용을 추가 처리 없이 바로 eventBus
로 보냅니다.<script>
import { onMount, getContext } from "svelte"
let { eventBus } = getContext("app")
function handleMenuEvent(event, ...args) {
eventBus.emit(...args)
}
onMount(() => {
window.api.onMenuEvent(handleMenuEvent)
})
</script>
앱에 따라 구성 요소가 마운트 해제될 때 일부 정리 단계를 추가해야 할 수도 있습니다. 우리는 여기서 하지 않을 것입니다.
그것은 많은 작업이었지만 정적 기능이 있는 작은 메뉴를 위해 마침내 준비되었습니다!
결과
결과는 다음과 같습니다.
다음 에피소드에서는 지난 10년 동안 최고의 UI 혁신인 명령 팔레트를 추가할 것입니다.
평소와 같이 all the code for the episode is here .
Reference
이 문제에 관하여(Electron Adventures: 에피소드 34: 애플리케이션 메뉴), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/taw/electron-adventures-episode-34-application-menu-3570텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)