• 07.《Electron 跨平台开发实战》- chapter07-应用菜单、上下文菜单


    应用菜单

    替换设置应用程序菜单

    • 创建应用菜单模块
      创建一个新的名为application-menu.js文件,
    const { app, BrowseWindow, Menu, shell } = require('electron');
    const mainProcess = require('./main');
    
    //创建数组模板,它描述了整个菜单的完整结构
    const template = [
        {
            label: 'Edit',
            submenu: [
                {
                    label: '复制',
                    accelerator: 'CommandOrControl+C', //accelerator属性定义键盘快捷键
                    role: 'copy'
                },
                {
                    label: '粘贴',
                    accelerator: 'CommandOrControl+V', //accelerator属性定义键盘快捷键
                    role: 'paste'
                }
            ]
        }
    ];
    //macOS系统:总是将第一个菜单作为应用菜单,故将Edit菜单及其以后的菜单都往后移一个位置
    if (process.platform === 'darwin') {
        const name = 'Fire Sale';
        template.unshift({ label: name }); //向数组的开头添加一个或更多元素,并返回新的长度
    }
    
    //https://www.cnblogs.com/fayin/p/6831071.html
    module.exports = Menu.buildFromTemplate(template);
    
    • main.js 已入并设置应用菜单
    const {..., Menu } = require('electron');
    const applicationMenu = require('./application-menu'); //引入应用菜单模块
    ...
    app.on('ready', () => {
        Menu.setApplicationMenu(applicationMenu); //设置应用菜单
        mainWindow = createwindow();
    });
    
    

    知识点

    module.exports = Menu.buildFromTemplate(template);

    macOS系统:总是将第一个菜单作为应用菜单,故将Edit菜单及其以后的菜单都往后移一个位置

    菜单项的role 属性

    每一种role属性都关联到一种操作系统内置的功能,有如下值:

    • undo
    • redo
    • cut
    • copy
    • paste
    • selectall
    • minimize
    • close

    补上macOS系统的应用菜单

    大部分macOS应用都具备的应用菜单功能,electron为macOS系统提供一组额外的role

    if (process.platform === 'darwin') {
      const name = 'Firesale';
      template.unshift({
        label: name,
        submenu: [
          {
            label: `About ${name}`,
            role: 'about',
          },
          { type: 'separator' },
          {
            label: 'Services',
            role: 'services',
            submenu: [],
          },
          { type: 'separator' },
          {
            label: `Hide ${name}`,
            accelerator: 'Command+H',
            role: 'hide',
          },
          {
            label: 'Hide Others',
            accelerator: 'Command+Alt+H',
            role: 'hideothers',
          },
          {
            label: 'Show All',
            role: 'unhide',
          },
          { type: 'separator' },
          {
            label: `Quit ${name}`,
            accelerator: 'Command+Q',
            click() { app.quit(); }, // A
          },
        ],
      });
    

    知识点

     #### 自定义菜单项的点击事件: { label:xxx, click() { app.quit(); }}  
     #### 菜单项分割线  { type: 'separator' }
    

    Window role

    仅在macOS系统中用 Window role,会在菜单的末尾添加一个包含当前应用所有窗口的列表

    不支持 Window role 的系统自动略过
    窗口的最大化,最小化,关闭等

     {
        label: 'Window',
        submenu: [
          {
            label: 'Minimize',
            accelerator: 'CommandOrControl+M',
            role: 'minimize',
          },
          {
            label: 'Close',
            accelerator: 'CommandOrControl+W',
            role: 'close',
          },
        ],
      },
    
    ...
      //为macOS系统中用Window role
      const windowMenu = template.find(item => item.label === 'Window'); // B
      windowMenu.role = 'window';
      windowMenu.submenu.push(
        { type: 'separator' },
        {
          label: 'Bring All to Front',
          role: 'front',
        }
      );
    
    

    help菜单

    • 大部分macOS系统使用这个功能,按下 command+shift+?, 用户就可以使用这个菜单搜索功能
    • 一般可以在help菜单中添加打开开发者工具
     {
        label: 'Help',
        role: 'help',
        submenu: [
          {
            label: 'Visit Website',
            click() { /* To be implemented */ }
          },
          {
            label: 'Toggle Developer Tools',
            click(item, focusedWindow) {
              if (focusedWindow) focusedWindow.webContents.toggleDevTools();
            }
          }
        ]
      }
    

    特有的功能菜单

    New File、Open File、Save File、Export Html

    • applicatoinMenu.js
    {
            label: 'File',
            submenu: [
                {
                    label: 'New File',
                    accelerator: 'CommandOrControl+N',
                    click() {
                        mainProcess.createWindow();
                    }
                },
                {
                    label: 'Open File',
                    accelerator: 'CommandOrControl+O',
                    click(item, focusedWindow) {
                        if (focusedWindow) {
                            return mainProcess.getFileFromUser(focusedWindow);
                        }
    
                        const newWindow = mainProcess.createWindow();
    
                        newWindow.on('show', () => {
                            mainProcess.getFileFromUser(newWindow);
                        });
                    },
                },
                {
                    label: 'Save File',
                    accelerator: 'CommandOrControl+S',
                    click(item, focusedWindow) {
                        if (!focusedWindow) {
                            return dialog.showErrorBox(
                                'Cannot Save or Export',
                                'There is currently no active document to save or export.'
                            );
                        }
                        focusedWindow.webContents.send('save-markdown');
                    },
                },
                {
                    label: 'Export HTML',
                    accelerator: 'Shift+CommandOrControl+S',
                    click(item, focusedWindow) {
                        if (!focusedWindow) {
                            return dialog.showErrorBox(
                                'Cannot Save or Export',
                                'There is currently no active document to save or export.'
                            );
                        }
                        focusedWindow.webContents.send('save-html');
                    },
                },
            ],
        },
    
    • renderer.js
    ipcRenderer.on('save-markdown', () => {
      mainProcess.saveMarkdown(currentWindow, filePath, markdownView.value);
    });
    
    ipcRenderer.on('save-html', () => {
      mainProcess.saveHtml(currentWindow, htmlView.innerHTML);
    });
    

    上下文菜单

    const markdownContextMenu = Menu.buildFromTemplate([{},{}])->markdownContextMenu.popup();

    • renderer.js
    const { remote, ...} = require('electron');
    const { Menu } = remote;
    ...
    //上下文菜单
    const markdownContextMenu = Menu.buildFromTemplate([
        { label: 'Open File', click() { mainProcess.getFileFromUser(); } },
        { type: 'separator' },
        { label: 'Cut', role: 'cut' },
        { label: 'Copy', role: 'copy' },
        { label: 'Paste', role: 'paste' },
        { label: 'Select All', role: 'selectall' },
    ]);
    
    markdownView.addEventListener('contextmenu', (event) => {
        event.preventDefault();
        markdownContextMenu.popup();
    });
    
    
  • 相关阅读:
    100——第9例
    100——第8例
    100——第7例
    POJ
    POJ
    POJ
    Egyptian Collegiate Programming Contest 2017 (ACM ECPC 2017)
    SCUT
    SCUT
    SCUT
  • 原文地址:https://www.cnblogs.com/easy5weikai/p/13138861.html
Copyright © 2020-2023  润新知