メニュー項目の「有効/無効」状態を切り替えて、クリックできないようにグレーアウトする方法を解説します。
ユーザーが特定の操作を行うまで選択できない項目(例:テキストを選択するまで「コピー」を無効にする、保存する変更がない間は「保存」を無効にするなど)を作る場合に便利です。
前提条件
Permissions (権限) の設定
src-tauri/capabilities/default.json に menu:default を追加します。
{
"permissions": [
...,
"core:menu:default"
]
}
1. フロントエンドから変更する (TypeScript)
初期状態で無効化する
オブジェクト形式で enabled: false を指定するか、MenuItem.new のオプションで指定します。
import { Menu } from '@tauri-apps/api/menu';
// オブジェクト形式: 初期状態で無効化
const menu = await Menu.new({
items: [
{
id: 'save',
text: '保存',
enabled: false // <--- 無効化された状態で作成
},
{
id: 'copy',
text: 'コピー',
enabled: false
}
]
});
await menu.setAsAppMenu();
クラスを使用した記法
import { Menu, MenuItem } from '@tauri-apps/api/menu';
// 最初から無効化された状態で作成
const saveItem = await MenuItem.new({
id: 'save',
text: '保存',
enabled: false // <--- ここで無効化
});
// メニューを作成してセット
const menu = await Menu.new({
items: [saveItem]
});
await menu.setAsAppMenu();
動的に有効/無効を切り替える
setEnabled メソッドを使用して、後から状態を変更できます。
import { Menu } from '@tauri-apps/api/menu';
// メニュー作成時に参照を保持
const menu = await Menu.new({
items: [
{
id: 'save',
text: '保存',
enabled: false
}
]
});
await menu.setAsAppMenu();
// 後から状態を変更する場合
const saveItem = await menu.get('save');
if (saveItem) {
// 有効化 (クリック可能にする)
await saveItem.setEnabled(true);
// 再び無効化 (グレーアウトする)
// await saveItem.setEnabled(false);
}
2. バックエンドから変更する (Rust)
Rust 側でも同様に enabled 引数で初期状態を指定し、set_enabled で変更できます。
初期状態で無効化する
use tauri::menu::{MenuBuilder, MenuItemBuilder};
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
tauri::Builder::default()
.setup(|app| {
let menu = MenuBuilder::new(app)
.item(
&MenuItemBuilder::with_id("save", "保存")
.enabled(false) // 初期状態で無効化
.build(app)?
)
.build()?;
app.set_menu(menu)?;
Ok(())
})
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
従来の記法(MenuItem を個別に作成)
use tauri::menu::{Menu, MenuItem};
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
tauri::Builder::default()
.setup(|app| {
let handle = app.handle();
// 1. 初期状態で無効化 (3番目の引数が enabled)
let save_item = MenuItem::with_id(handle, "save", "保存", false, None::<&str>)?;
let menu = Menu::with_items(handle, &[&save_item])?;
app.set_menu(menu)?;
Ok(())
})
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
動的に有効/無効を切り替える
コマンド内でメニュー項目の状態を変更する例です。
use tauri::{AppHandle, Manager};
use tauri::menu::MenuItem;
use std::sync::Mutex;
// State でメニュー項目を保持する構造体
struct MenuState {
save_item: MenuItem<tauri::Wry>,
}
#[tauri::command]
fn enable_save_menu(state: tauri::State<'_, Mutex<MenuState>>) -> Result<(), String> {
let menu_state = state.lock().map_err(|e| e.to_string())?;
menu_state.save_item.set_enabled(true).map_err(|e| e.to_string())?;
Ok(())
}
#[tauri::command]
fn disable_save_menu(state: tauri::State<'_, Mutex<MenuState>>) -> Result<(), String> {
let menu_state = state.lock().map_err(|e| e.to_string())?;
menu_state.save_item.set_enabled(false).map_err(|e| e.to_string())?;
Ok(())
}
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
tauri::Builder::default()
.setup(|app| {
let handle = app.handle();
// 初期状態で無効化
let save_item = MenuItem::with_id(handle, "save", "保存", false, None::<&str>)?;
let menu = tauri::menu::Menu::with_items(handle, &[&save_item])?;
app.set_menu(menu)?;
// State として保存
app.manage(Mutex::new(MenuState { save_item }));
Ok(())
})
.invoke_handler(tauri::generate_handler![enable_save_menu, disable_save_menu])
.run(tauri::generate_context!())
.expect("error while running tauri application");
}
補足
* 無効化されたアイテムの見た目: OSによって異なりますが、通常グレーアウトされ、クリックしても反応しません。
* State の活用: Rustで動的に変更する場合は、MenuItem インスタンスを State として保持するのが一般的です。