È uscito il Corso SQL Completo

Menu dell'Applicazione

Il modulo Menu di Electron permette di creare menu nativi dell’applicazione, coerenti con il sistema operativo su cui gira l’app.

Creare un Menu Base

const { app, Menu, BrowserWindow } = require('electron');

function createMenu(mainWindow) {
  const template = [
    {
      label: 'File',
      submenu: [
        {
          label: 'Nuovo',
          accelerator: 'CmdOrCtrl+N',
          click: () => {
            mainWindow.webContents.send('menu:action', 'new');
          },
        },
        {
          label: 'Apri',
          accelerator: 'CmdOrCtrl+O',
          click: () => {
            mainWindow.webContents.send('menu:action', 'open');
          },
        },
        {
          label: 'Salva',
          accelerator: 'CmdOrCtrl+S',
          click: () => {
            mainWindow.webContents.send('menu:action', 'save');
          },
        },
        { type: 'separator' },
        {
          label: 'Esci',
          accelerator: process.platform === 'darwin' ? 'Cmd+Q' : 'Alt+F4',
          click: () => app.quit(),
        },
      ],
    },
    {
      label: 'Modifica',
      submenu: [
        { role: 'undo', label: 'Annulla' },
        { role: 'redo', label: 'Ripeti' },
        { type: 'separator' },
        { role: 'cut', label: 'Taglia' },
        { role: 'copy', label: 'Copia' },
        { role: 'paste', label: 'Incolla' },
        { role: 'selectAll', label: 'Seleziona tutto' },
      ],
    },
    {
      label: 'Visualizza',
      submenu: [
        { role: 'reload', label: 'Ricarica' },
        { role: 'forceReload', label: 'Ricarica forzata' },
        { role: 'toggleDevTools', label: 'DevTools' },
        { type: 'separator' },
        { role: 'resetZoom', label: 'Zoom predefinito' },
        { role: 'zoomIn', label: 'Zoom avanti' },
        { role: 'zoomOut', label: 'Zoom indietro' },
        { type: 'separator' },
        { role: 'togglefullscreen', label: 'Schermo intero' },
      ],
    },
    {
      label: 'Finestra',
      submenu: [
        { role: 'minimize', label: 'Minimizza' },
        { role: 'close', label: 'Chiudi' },
      ],
    },
  ];

  const menu = Menu.buildFromTemplate(template);
  Menu.setApplicationMenu(menu);
}

Ruoli Predefiniti

Electron fornisce ruoli predefiniti per le azioni comuni del menu. Usarli garantisce comportamenti nativi corretti:

// Ruoli per il menu Modifica
{ role: 'undo' }          // Annulla
{ role: 'redo' }          // Ripeti
{ role: 'cut' }           // Taglia
{ role: 'copy' }          // Copia
{ role: 'paste' }         // Incolla
{ role: 'delete' }        // Elimina
{ role: 'selectAll' }     // Seleziona tutto

// Ruoli per il menu Visualizza
{ role: 'reload' }        // Ricarica la pagina
{ role: 'forceReload' }   // Ricarica forzata
{ role: 'toggleDevTools' }// Apri/Chiudi DevTools
{ role: 'resetZoom' }     // Reset zoom
{ role: 'zoomIn' }        // Zoom in
{ role: 'zoomOut' }       // Zoom out
{ role: 'togglefullscreen' } // Schermo intero

// Ruoli per il menu Finestra
{ role: 'minimize' }      // Minimizza
{ role: 'close' }         // Chiudi
{ role: 'quit' }          // Esci dall'app

// macOS specifici
{ role: 'about' }         // Info su...
{ role: 'hide' }          // Nascondi
{ role: 'hideOthers' }    // Nascondi altre
{ role: 'unhide' }        // Mostra tutte
{ role: 'front' }         // Porta avanti

Accelerators (Scorciatoie)

Gli accelerator definiscono le scorciatoie da tastiera per le voci di menu:

{
  label: 'Salva',
  accelerator: 'CmdOrCtrl+S',    // Ctrl+S su Windows/Linux, Cmd+S su macOS
  click: () => { /* ... */ }
}

Modificatori disponibili:

  • CmdOrCtrl — Cmd su macOS, Ctrl su Windows/Linux
  • Alt — Tasto Alt/Option
  • Shift — Tasto Shift
  • Super — Tasto Windows/Super

Combinazioni:

  • CmdOrCtrl+Shift+S — Salva con nome
  • CmdOrCtrl+Alt+I — Combinazione a tre tasti
  • F5 — Tasto funzione

Su macOS, il primo menu è sempre il menu dell’applicazione (con il nome dell’app). È necessario gestirlo:

const isMac = process.platform === 'darwin';

const template = [
  // Menu dell'app (solo macOS)
  ...(isMac
    ? [{
        label: app.name,
        submenu: [
          { role: 'about', label: `Info su ${app.name}` },
          { type: 'separator' },
          { role: 'services', label: 'Servizi' },
          { type: 'separator' },
          { role: 'hide', label: `Nascondi ${app.name}` },
          { role: 'hideOthers', label: 'Nascondi altre' },
          { role: 'unhide', label: 'Mostra tutte' },
          { type: 'separator' },
          { role: 'quit', label: `Esci da ${app.name}` },
        ],
      }]
    : []),

  // Menu File
  {
    label: 'File',
    submenu: [
      isMac
        ? { role: 'close', label: 'Chiudi finestra' }
        : { role: 'quit', label: 'Esci' },
    ],
  },

  // ... altri menu
];

Voci di Menu Personalizzate

Checkbox

{
  label: 'Modalità scura',
  type: 'checkbox',
  checked: isDarkMode,
  click: (menuItem) => {
    mainWindow.webContents.send('theme:toggle', menuItem.checked);
  },
}

Radio

{
  label: 'Dimensione testo',
  submenu: [
    { label: 'Piccolo', type: 'radio', checked: fontSize === 'small' },
    { label: 'Medio', type: 'radio', checked: fontSize === 'medium' },
    { label: 'Grande', type: 'radio', checked: fontSize === 'large' },
  ],
}

Abilitare/Disabilitare

{
  label: 'Salva',
  accelerator: 'CmdOrCtrl+S',
  enabled: hasUnsavedChanges,    // Disabilitato se non ci sono modifiche
  click: () => { /* ... */ },
}

Aggiornare il Menu Dinamicamente

Per aggiornare il menu in base allo stato dell’applicazione, ricostruiscilo:

function updateMenu(state) {
  const template = [
    {
      label: 'File',
      submenu: [
        {
          label: 'Salva',
          accelerator: 'CmdOrCtrl+S',
          enabled: state.hasChanges,    // Dinamico
          click: () => saveFile(),
        },
        { type: 'separator' },
        {
          label: `File recenti (${state.recentFiles.length})`,
          submenu: state.recentFiles.map((file) => ({
            label: path.basename(file),
            click: () => openFile(file),
          })),
        },
      ],
    },
  ];

  Menu.setApplicationMenu(Menu.buildFromTemplate(template));
}

Rimuovere il Menu

Per rimuovere completamente il menu dell’applicazione:

Menu.setApplicationMenu(null);

Su macOS questo nasconde il menu ma mantiene le scorciatoie standard. Su Windows/Linux rimuove completamente la barra del menu.