Electronのメニューを作る、createMenu()関数を作りエクスポート可能とします。 トップレベルメニューは、ファイルのみ。サブメニューとして画像の読み込みメニューを配置、そのサブメニューとしてロゴファイルと背景ファイルの読み込みメニューを作成してください。それぞれのメニューハンドラは別途作成します。 その下にはセパレータを一つ配置し、終了メニューを作成してください。

はい、承知いたしました。Electronで指定された構造のメニューを作成し、エクスポート可能な createMenu 関数を実装します。

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

// メニューハンドラは別途定義されることを想定
// 例:
// const handleLoadLogo = () => { console.log('ロゴファイルを読み込みます'); };
// const handleLoadBackground = () => { console.log('背景ファイルを読み込みます'); };

/**
 * アプリケーションメニューを作成します。
 * @param {object} handlers - 各メニューアイテムに対応するハンドラ関数を含むオブジェクト
 * @param {function} handlers.loadLogo - ロゴファイル読み込み処理のハンドラ
 * @param {function} handlers.loadBackground - 背景ファイル読み込み処理のハンドラ
 * @returns {Electron.Menu} 作成されたメニューオブジェクト
 */
const createMenu = (handlers) => {
  const template = [
    {
      label: 'ファイル', // Top-level menu: File
      submenu: [
        {
          label: '画像の読み込み', // Submenu: Load Image
          submenu: [
            {
              label: 'ロゴファイル', // Submenu item: Logo File
              click: handlers?.loadLogo, // Assign handler
            },
            {
              label: '背景ファイル', // Submenu item: Background File
              click: handlers?.loadBackground, // Assign handler
            },
          ],
        },
        { type: 'separator' }, // Separator
        {
          label: '終了', // Submenu item: Exit
          click: () => app.quit(), // Standard exit handler
          accelerator: process.platform === 'darwin' ? 'Cmd+Q' : 'Alt+F4' // Add accelerator
        },
      ],
    },
    // 必要に応じて他のトップレベルメニューを追加できます
    // {
    //   label: '編集',
    //   submenu: [ /* ... */ ]
    // }
  ];

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

module.exports = { createMenu };

解説:

  1. require('electron'): Electronの Menu モジュールと app モジュールをインポートします。app は「終了」メニューでアプリケーションを終了させるために使用します。
  2. createMenu(handlers) 関数:
  3. module.exports = { createMenu };createMenu 関数を他のファイルから require して利用できるようにエクスポートします。

使い方:

このファイルを例えば menu.js として保存し、メインプロセスファイル(通常 main.js)で以下のように使用します。

unfold_lessjavascript
content_copyaddcompare_arrowsopen_in_full
// main.js
const { app, BrowserWindow, Menu } = require('electron');
const { createMenu } = require('./menu'); // menu.js をインポート

// --- メニューハンドラの定義 ---
const handleLoadLogo = () => {
  console.log('ロゴファイル読み込み処理を実行');
  // ここでファイル選択ダイアログを開くなどの処理を実装
};

const handleLoadBackground = () => {
  console.log('背景ファイル読み込み処理を実行');
  // ここでファイル選択ダイアログを開くなどの処理を実装
};
// --- ハンドラの定義ここまで ---

function createWindow () {
  const mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      // preload: path.join(__dirname, 'preload.js') // 必要に応じて
    }
  });

  // mainWindow.loadFile('index.html'); // ウィンドウに表示するHTML

  // メニューを作成して設定
  const menu = createMenu({
    loadLogo: handleLoadLogo,         // ロゴ用ハンドラを渡す
    loadBackground: handleLoadBackground // 背景用ハンドラを渡す
  });
  Menu.setApplicationMenu(menu);

  // mainWindow.webContents.openDevTools() // 開発者ツールを開く場合
}

app.whenReady().then(() => {
  createWindow();

  app.on('activate', function () {
    if (BrowserWindow.getAllWindows().length === 0) createWindow();
  });
});

app.on('window-all-closed', function () {
  if (process.platform !== 'darwin') app.quit();
});

これで、指定された構造のメニューがアプリケーションに表示され、各メニュー項目がクリックされたときに(まだ実装されていないハンドラを除き)対応する動作が実行されるようになります。

今後このメニューを多言語対応させる場合どのように書けば良いですか?

メニューの多言語対応を行うには、一般的に以下のようなアプローチを取ります。

  1. 翻訳ファイルの準備: 言語ごとに翻訳テキストをまとめたファイル(JSON形式が一般的)を用意します。
  2. i18nライブラリの導入: 翻訳の読み込みや言語切り替えを管理するライブラリ(例: i18nextelectron-i18n)を導入します。
  3. メニューテンプレートの修正: ハードコードされた文字列を、翻訳キーと翻訳関数呼び出しに置き換えます。
  4. 言語設定: アプリケーションの起動時や設定変更時に、使用する言語を決定し、ライブラリに設定します。

具体的な手順とコード例を以下に示します(i18next を使用する例)。

1. 必要なライブラリのインストール

unfold_lessbash
content_copyterminal
npm install i18next i18next-fs-backend
# または
yarn add i18next i18next-fs-backend