Menu
Wails v3 menyediakan sistem menu yang powerful yang memungkinkan Anda membuat menu aplikasi dan menu konteks. Panduan ini akan memandu Anda melalui berbagai fitur dan kemampuan sistem menu.
Membuat Menu
Untuk membuat menu baru, gunakan method New() dari manager Menus:
menu := app.Menu.New()Menambahkan Item Menu
Wails mendukung beberapa tipe item menu, masing-masing dengan tujuan spesifik:
Item Menu Reguler
Item menu reguler adalah blok dasar menu. Item ini menampilkan teks dan dapat memicu aksi saat diklik:
menuItem := menu.Add("Click Me")Checkbox
Item menu checkbox menyediakan state yang dapat di-toggle, berguna untuk mengaktifkan/menonaktifkan fitur atau pengaturan:
checkbox := menu.AddCheckbox("My checkbox", true) // true = initially checkedGrup Radio
Grup radio memungkinkan pengguna memilih satu opsi dari sekumpulan pilihan yang saling eksklusif. Grup dibuat otomatis saat item radio ditempatkan berdampingan:
menu.AddRadio("Option 1", true) // true = initially selected
menu.AddRadio("Option 2", false)
menu.AddRadio("Option 3", false)Separator
Separator adalah garis horizontal yang membantu mengorganisir item menu ke dalam grup logis:
menu.AddSeparator()Submenu
Submenu adalah menu bersarang yang muncul saat hover atau klik item menu. Berguna untuk mengorganisir struktur menu yang kompleks:
submenu := menu.AddSubmenu("File")
submenu.Add("Open")
submenu.Add("Save")Menggabungkan menu
Menu dapat ditambahkan ke menu lain dengan append atau prepend.
menu := app.Menu.New()
menu.Add("First Menu")
secondaryMenu := app.Menu.New()
secondaryMenu.Add("Second Menu")
// insert 'secondaryMenu' after 'menu'
menu.Append(secondaryMenu)
// insert 'secondaryMenu' before 'menu'
menu.Prepend(secondaryMenu)
// update the menu
menu.Update()Membersihkan menu
Dalam beberapa kasus, lebih baik membangun menu baru jika Anda bekerja dengan jumlah item menu yang bervariasi.
Ini akan membersihkan semua item pada menu yang ada dan memungkinkan Anda menambahkan item lagi.
menu := app.Menu.New()
menu.Add("Waiting for update...")
// after certain logic, the menu has to be updated
menu.Clear()
menu.Add("Update complete!")
menu.Update()Menghancurkan menu
Jika Anda ingin membersihkan dan melepaskan menu, gunakan method Destroy():
menu := app.Menu.New()
menu.Add("Waiting for update...")
// after certain logic, the menu has to be destroyed
menu.Destroy()Properti Item Menu
Item menu memiliki beberapa properti yang dapat dikonfigurasi:
| Properti | Method | Deskripsi |
|---|---|---|
| Label | SetLabel(string) |
Mengatur teks tampilan |
| Enabled | SetEnabled(bool) |
Mengaktifkan/menonaktifkan item |
| Checked | SetChecked(bool) |
Mengatur state checked (untuk checkbox/radio) |
| Tooltip | SetTooltip(string) |
Mengatur teks tooltip |
| Hidden | SetHidden(bool) |
Menampilkan/menyembunyikan item |
| Accelerator | SetAccelerator(string) |
Mengatur keyboard shortcut |
State Item Menu
Item menu dapat berada dalam state berbeda yang mengontrol visibilitas dan interaktivitas:
Visibilitas
Item menu dapat ditampilkan atau disembunyikan secara dinamis menggunakan method SetHidden():
menuItem := menu.Add("Dynamic Item")
// Hide the menu item
menuItem.SetHidden(true)
// Show the menu item
menuItem.SetHidden(false)
// Check current visibility
isHidden := menuItem.Hidden()Item menu yang disembunyikan sepenuhnya dihapus dari menu hingga ditampilkan kembali. Berguna untuk item menu kontekstual yang hanya muncul dalam state aplikasi tertentu.
State Enabled
Item menu dapat diaktifkan atau dinonaktifkan menggunakan method SetEnabled():
menuItem := menu.Add("Save")
// Disable the menu item
menuItem.SetEnabled(false) // Item appears grayed out and cannot be clicked
// Enable the menu item
menuItem.SetEnabled(true) // Item becomes clickable again
// Check current enabled state
isEnabled := menuItem.Enabled()Item menu yang dinonaktifkan tetap terlihat tetapi tampak abu-abu dan tidak dapat diklik. Umum digunakan untuk menandakan aksi saat ini tidak tersedia, seperti:
- Menonaktifkan “Save” saat tidak ada perubahan untuk disimpan
- Menonaktifkan “Copy” saat tidak ada yang dipilih
- Menonaktifkan “Undo” saat tidak ada aksi untuk di-undo
Manajemen State Dinamis
Anda dapat menggabungkan state ini dengan event handler untuk membuat menu dinamis:
saveMenuItem := menu.Add("Save")
// Initially disable the Save menu item
saveMenuItem.SetEnabled(false)
// Enable Save only when there are unsaved changes
documentChanged := func() {
saveMenuItem.SetEnabled(true)
menu.Update() // Remember to update the menu after changing states
}
// Disable Save after saving
documentSaved := func() {
saveMenuItem.SetEnabled(false)
menu.Update()
}Penanganan Event
Item menu dapat merespons event klik menggunakan method OnClick:
menuItem.OnClick(func(ctx *application.Context) {
// Handle the click event
println("Menu item clicked!")
})Context menyediakan informasi tentang item menu yang diklik:
menuItem.OnClick(func(ctx *application.Context) {
// Get the clicked menu item
clickedItem := ctx.ClickedMenuItem()
// Get its current state
isChecked := clickedItem.Checked()
})Item Menu Berbasis Role
Wails menyediakan sekumpulan role menu yang telah didefinisikan yang secara otomatis membuat item menu dengan fungsionalitas standar. Berikut role menu yang didukung:
Struktur Menu Lengkap
Role ini membuat struktur menu lengkap dengan fungsionalitas umum:
| Role | Deskripsi | Catatan Platform |
|---|---|---|
AppMenu |
Menu aplikasi dengan About, Services, Hide/Show, dan Quit | macOS saja |
EditMenu |
Menu Edit standar dengan Undo, Redo, Cut, Copy, Paste, dll. | Semua platform |
ViewMenu |
Menu View dengan kontrol Reload, Zoom, dan Fullscreen | Semua platform |
WindowMenu |
Kontrol window (Minimise, Zoom, dll.) | Semua platform |
HelpMenu |
Menu Help dengan tautan “Learn More” ke situs Wails | Semua platform |
Item Menu Individual
Role ini dapat digunakan untuk menambahkan item menu individual:
| Role | Deskripsi | Catatan Platform |
|---|---|---|
About |
Menampilkan dialog About aplikasi | Semua platform |
Hide |
Menyembunyikan aplikasi | macOS saja |
HideOthers |
Menyembunyikan aplikasi lain | macOS saja |
UnHide |
Menampilkan aplikasi yang disembunyikan | macOS saja |
CloseWindow |
Menutup window saat ini | Semua platform |
Minimise |
Meminimalkan window | Semua platform |
Zoom |
Zoom window | macOS saja |
Front |
Membawa window ke depan | macOS saja |
Quit |
Keluar dari aplikasi | Semua platform |
Undo |
Undo aksi terakhir | Semua platform |
Redo |
Redo aksi terakhir | Semua platform |
Cut |
Cut seleksi | Semua platform |
Copy |
Copy seleksi | Semua platform |
Paste |
Paste dari clipboard | Semua platform |
PasteAndMatchStyle |
Paste dan cocokkan style | macOS saja |
SelectAll |
Pilih semua | Semua platform |
Delete |
Hapus seleksi | Semua platform |
Reload |
Reload halaman saat ini | Semua platform |
ForceReload |
Force reload halaman saat ini | Semua platform |
ToggleFullscreen |
Toggle mode fullscreen | Semua platform |
ResetZoom |
Reset level zoom | Semua platform |
ZoomIn |
Perbesar zoom | Semua platform |
ZoomOut |
Perkecil zoom | Semua platform |
Berikut contoh penggunaan menu lengkap dan role individual:
menu := app.Menu.New()
// Add complete menu structures
menu.AddRole(application.AppMenu) // macOS only
menu.AddRole(application.EditMenu) // Common edit operations
menu.AddRole(application.ViewMenu) // View controls
menu.AddRole(application.WindowMenu) // Window controls
// Add individual role-based items to a custom menu
fileMenu := menu.AddSubmenu("File")
fileMenu.AddRole(application.CloseWindow)
fileMenu.AddSeparator()
fileMenu.AddRole(application.Quit)Menu Aplikasi
Menu aplikasi adalah menu yang muncul di bagian atas window aplikasi (Windows/Linux) atau di bagian atas layar (macOS).
Perilaku Menu Aplikasi
Saat Anda mengatur menu aplikasi menggunakan app.Menu.Set(), menu tersebut menjadi menu utama di macOS.
Menu diatur per window untuk Windows/Linux.
app.Window.NewWithOptions(application.WebviewWindowOptions{
Title: "Custom Menu Window",
Windows: application.WindowsWindow{
Menu: customMenu, // Override application menu for this window
},
})Berikut contoh lengkap yang menunjukkan perilaku menu berbeda:
func main() {
app := application.New(application.Options{})
// Create application menu
appMenu := app.Menu.New()
fileMenu := appMenu.AddSubmenu("File")
fileMenu.Add("New").OnClick(func(ctx *application.Context) {
// This will be available in all windows unless overridden
window := app.Window.Current()
window.SetTitle("New Window")
})
// Set as application menu - this is for macOS
app.Menu.Set(appMenu)
// Window with custom menu on Windows
customMenu := app.Menu.New()
customMenu.Add("Custom Action")
app.Window.NewWithOptions(application.WebviewWindowOptions{
Title: "Custom Menu",
Windows: application.WindowsWindow{
Menu: customMenu,
},
})
app.Run()
}Menu Konteks
Menu konteks adalah menu popup yang muncul saat klik kanan elemen di aplikasi Anda. Menu ini memberikan akses cepat ke aksi yang relevan untuk elemen yang diklik.
Menu Konteks Default
Menu konteks default adalah menu konteks bawaan webview yang menyediakan operasi level sistem seperti:
- Copy, Cut, dan Paste untuk manipulasi teks
- Kontrol seleksi teks
- Opsi spell checking
Mengontrol Menu Konteks Default
Anda dapat mengontrol kapan menu konteks default muncul menggunakan properti CSS --default-contextmenu:
<!-- Always show default context menu -->
<div style="--default-contextmenu: show">
<input type="text" placeholder="Right-click for text operations"/>
<textarea>Standard text operations available here</textarea>
</div>
<!-- Hide default context menu -->
<div style="--default-contextmenu: hide">
<div class="custom-component">Custom context menu only</div>
</div>
<!-- Smart context menu behaviour (default) -->
<div style="--default-contextmenu: auto">
<!-- Shows default menu when text is selected or in input fields -->
<p>Select this text to see the default menu</p>
<input type="text" placeholder="Default menu for input operations"/>
</div>Perilaku Menu Konteks Bersarang
Saat menggunakan properti --default-contextmenu pada elemen bersarang, aturan berikut berlaku:
- Elemen anak mewarisi pengaturan menu konteks induk kecuali secara eksplisit di-override
- Pengaturan paling spesifik (terdekat) yang diutamakan
- Nilai
autodapat digunakan untuk reset ke perilaku default
Contoh perilaku menu konteks bersarang:
<!-- Parent sets hide -->
<div style="--default-contextmenu: hide">
<!-- This inherits hide -->
<p>No context menu here</p>
<!-- This overrides to show -->
<div style="--default-contextmenu: show">
<p>Context menu shown here</p>
<!-- This inherits show -->
<span>Also has context menu</span>
<!-- This resets to automatic behaviour -->
<div style="--default-contextmenu: auto">
<p>Shows menu only when text is selected</p>
</div>
</div>
</div>Menu Konteks Kustom
Menu konteks kustom memungkinkan Anda menyediakan aksi spesifik aplikasi yang relevan dengan elemen yang diklik. Sangat berguna untuk:
- Operasi file di document manager
- Alat manipulasi gambar
- Aksi kustom di data grid
- Operasi spesifik komponen
Membuat Menu Konteks Kustom
Saat membuat menu konteks kustom, Anda menyediakan identifier unik (nama) yang menghubungkan menu ke elemen HTML:
// Create a context menu with identifier "imageMenu"
contextMenu := app.ContextMenu.New()
app.ContextMenu.Add("imageMenu", contextMenu)Parameter name (“imageMenu” dalam contoh ini) berfungsi sebagai identifier unik yang akan digunakan untuk:
- Menghubungkan elemen HTML ke menu konteks spesifik ini
- Mengidentifikasi menu mana yang ditampilkan saat klik kanan
- Memungkinkan pembaruan dan pembersihan menu
Data Konteks
Saat menangani event menu konteks, Anda dapat mengakses item menu yang diklik dan data konteks terkait:
contextMenu.Add("Process").OnClick(func(ctx *application.Context) {
// Get the clicked menu item
menuItem := ctx.ClickedMenuItem()
// Get the context data as a string
contextData := ctx.ContextMenuData()
// Check if the menu item is checked (for checkbox/radio items)
isChecked := ctx.IsChecked()
// Use the data
if contextData != "" {
processItem(contextData)
}
})Data konteks diteruskan dari properti --custom-contextmenu-data elemen HTML dan tersedia di click handler melalui ctx.ContextMenuData(). Sangat berguna saat:
- Bekerja dengan list atau grid di mana setiap item membutuhkan identifikasi unik
- Menangani operasi pada komponen atau elemen spesifik
- Meneruskan state atau metadata dari frontend ke backend
Manajemen Menu Konteks
Setelah melakukan perubahan pada menu konteks, panggil method Update() untuk menerapkan perubahan:
contextMenu.Update()Saat menu konteks tidak lagi diperlukan, Anda dapat menghancurkannya:
contextMenu.Destroy()Contoh Dunia Nyata: Galeri Gambar
Berikut contoh lengkap implementasi menu konteks kustom untuk galeri gambar:
// Backend: Create the context menu
imageMenu := app.ContextMenu.New()
app.ContextMenu.Add("imageMenu", imageMenu)
// Add relevant operations
imageMenu.Add("View Full Size").OnClick(func(ctx *application.Context) {
// Get the image ID from context data
if imageID := ctx.ContextMenuData(); imageID != "" {
openFullSizeImage(imageID)
}
})
imageMenu.Add("Download").OnClick(func(ctx *application.Context) {
if imageID := ctx.ContextMenuData(); imageID != "" {
downloadImage(imageID)
}
})
imageMenu.Add("Share").OnClick(func(ctx *application.Context) {
if imageID := ctx.ContextMenuData(); imageID != "" {
showShareDialog(imageID)
}
})<!-- Frontend: Image gallery implementation -->
<div class="gallery">
<!-- Each image container with context menu -->
<div class="image-container"
style="--custom-contextmenu: imageMenu; --custom-contextmenu-data: img_123">
<img src="/images/img_123.jpg" alt="Gallery Image"/>
<span class="caption">Nature Photo</span>
</div>
<div class="image-container"
style="--custom-contextmenu: imageMenu; --custom-contextmenu-data: img_124">
<img src="/images/img_124.jpg" alt="Gallery Image"/>
<span class="caption">City Photo</span>
</div>
</div>Dalam contoh ini:
- Menu konteks dibuat dengan identifier “imageMenu”
- Setiap container gambar dihubungkan ke menu menggunakan
--custom-contextmenu: imageMenu - Setiap container menyediakan ID gambar sebagai data konteks menggunakan
--custom-contextmenu-data - Backend menerima ID gambar di click handler dan dapat melakukan operasi spesifik
- Menu yang sama digunakan ulang untuk semua gambar, tetapi data konteks memberi tahu gambar mana yang dioperasikan
Pola ini sangat powerful untuk:
- Data grid di mana baris membutuhkan operasi spesifik
- File manager di mana file membutuhkan aksi spesifik konteks
- Alat desain di mana elemen berbeda membutuhkan operasi berbeda
- Komponen apa pun di mana operasi yang sama berlaku untuk banyak instance