iT邦幫忙

第 12 屆 iT 邦幫忙鐵人賽

DAY 15
0
Modern Web

ElectronJS系列 第 15

[ Day 15 ] - 動物聊天室(八) - Menu 選單

[ Day 15 ] - 動物聊天室(八) - Menu 選單

在 electron 中有 3 種類型的 Menu

  • applicationMenu
  • contextMenu on BrowserWindow
  • contextMenu on Tray

下面我們來介紹一下 , 3 種 Menu 各是甚麼 , 以及其存在的環境


applicationMenu

  • 系統工具列 - 本身就有預設一些功能

當然我們可以也可以將其設定成我們想要的

// 加到 background.js 的 createWindow 函式中 
const applicationMenu = Menu.buildFromTemplate([

    {
        label: '編輯',
        submenu: [
            {role: 'undo', label: '返回'},
            {role: 'redo', label: '重做'},
            {type: 'separator'},
            {
                label: '常用功能',
                submenu: [
                    {role: 'cut'},
                    {role: 'copy'},
                    {role: 'paste'},
                    {role: 'delete'},
                ]
            },
            {type: 'separator'},
            {role: 'selectAll', label: '全選'}
        ]
    },
    {
        label: '關閉',
        click: () => app.quit(),
    },
]);
Menu.setApplicationMenu(applicationMenu);

由於 electron 的 applicationMenu 無法調整高度 . 背景色 ...等樣式 ,
所以大部分的 electron 程式不會使用 applicationMenu ,
而是會自己用 html + css 自己刻一個 applicationMenu

舉個例子

vscode:將標題列與工具列整合在一起


contextMenu on BrowserWindow ( popupMenu )

  • 在應用程式上面的彈跳選單

我們將 "動物聊天室" 追加彈跳選單

將 <template/> 中的文字區塊加上 @contextmenu 使其對右鍵產生反應

- <div class="msg" :class="[chat.team]">
+ <div class="msg" :class="[chat.team]" @contextmenu="openMenu(chat)">
    <span class="break-words">
       {{chat.msg}}
    </span>
</div>

當然我們要設定 method - openMenu

methods: {
    openMenu(chat) {
    
        window.ipcRenderer.send('open-contextmenu', chat);
    },
    ...
}

ipcRenderer 送出 open-contextmenu , 因此 background.js 需要註冊 ipcMain.on('open-contextmenu' 來接受訊息

ipcMain.on('open-contextmenu', (event, chat) => {

    Menu.buildFromTemplate([
        {label: '複製', click: () => event.reply('chatroom:copy-msg', chat)},
        {label: '刪除', click: () => event.reply('chatroom:delete-msg', chat)},
        {label: '收回', click: () => event.reply('chatroom:take-back-msg', chat)},
    ])
        .popup(BrowserWindow.getFocusedWindow())
});

然而 , 複製 . 刪除 . 收回 這些動作必定需要更新畫面 ,
因此用 event.reply 請求畫面更新 ,
並在 created 時註冊對應的 ipcRenderer.on

created() {

    // 複製訊息
    window.ipcRenderer.on('chatroom:copy-msg', (event, chat) => {

        this.text = chat.msg;
        this.$refs['text-input'].focus();
    });

    //  刪除訊息
    window.ipcRenderer.on('chatroom:delete-msg', (event, chat) => {

        firestoreUtils.sender
            .deleteMessage(this.roomId, chat.uuid)
            .catch(e => console.error(e));
    });

    //  收回訊息
    window.ipcRenderer.on('chatroom:take-back-msg', (event, chat) => {

        firestoreUtils.sender
            .updateMessage(this.roomId, {...chat, takeBack: true})
            .catch(e => console.error(e));
    });
},

之前我們沒有設計 收回訊息 的樣式 , 因此需要追加設計一下

  • 目標:

Chatroom.vue 的 <template/> 中追加 v-if 判別此訊息要顯示收回 or 詳細內容

<div v-if="chat.takeBack"
     :key="chat.uuid"
     class="msg-wrap justify-center"
>
    <div class="take-back-msg">
        <span> {{chat.name}} 已收回訊息 </span>
    </div>
</div>

上方追加區塊多使用了 justify-centertake-back-msg ,
因此需要在 區塊中定義一下

.justify-center {
    justify-content: center;
}

.take-back-msg{
    padding: 3px 20px 3px 20px;
    border-radius: 30px;
    color: white;
    background-color: #8F8989;
}

成果


contextMenu on Tray ( trayMenu )

  • 在系統通知區內小圖示上面的右鍵選單
  const switchCat = catNo => () => { 
      win.show();
      win.webContents.send('switch-cat', catNo);
  }

  tray = new Tray('/path/to/my/icon');
  const contextMenu = Menu.buildFromTemplate([
      {label: '貓咪 4', click: switchCat(4)},
      {label: '貓咪 5', click: switchCat(5)},
      {label: '貓咪 6', click: switchCat(6)},
      {label: '縮小', click: () => win.hide()},
      {label: '結束', click: () => app.quit()}
  ]);
  tray.setToolTip('This is my application.'); // 提示訊息
  tray.setContextMenu(contextMenu);   // 右鍵選單

不知道邦友有沒有覺得熟悉 ?
其實在 [ Day 5 ] - 桌面小圖示(四) - 系統通知區與縮小的貓咪 我們已經使用過了 /images/emoticon/emoticon34.gif

參考資料

今年小弟第一次參加 `鐵人賽` , 如文章有誤 , 請各位前輩提出指正 , 感謝  <(_ _)>

上一篇
[ Day 14 ] - 動物聊天室(七) - 客製化標題列
下一篇
[ Day 16 ] - 動物聊天室(九) - Dialog 介紹
系列文
ElectronJS20

尚未有邦友留言

立即登入留言