00
:
00
:
00
:
00
Corso SEO AI - Usa SEOEMAIL al checkout per il 30% di sconto

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.