### Full Application Setup - Go Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/api-reference/startup.md A complete example demonstrating the setup of a Menuet application, including setting the required `Label` and `Name`, defining custom menu children, customizing labels, and running the application. ```go package main import ( "github.com/caseymrm/menuet/v2" ) func main() { app := menuet.App() // Required for startup management app.Label = "com.example.myapp" app.Name = "My App" app.Children = func() []menuet.MenuItem { return []menuet.MenuItem{ menuet.Regular{Text: "Hello World"}, menuet.Separator{}, // "Start at Login" and "Quit" items are auto-added } } // Customize labels if needed app.StartAtLoginLabel = "Launch on Startup" app.QuitLabel = "Exit" app.RunApplication() } ``` -------------------------------- ### Install Menuet Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/USAGE-GUIDE.md Use 'go get' to install the Menuet library. ```bash go get github.com/caseymrm/menuet/v2 ``` -------------------------------- ### Example: Hide Startup - Go Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/api-reference/startup.md Demonstrates hiding the 'Start at Login' menu item before running the application. ```go app := menuet.App() app.HideStartup() app.RunApplication() ``` -------------------------------- ### Minimal Menuet Application Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/USAGE-GUIDE.md A basic Menuet application setup. This example demonstrates the essential structure for creating a menubar application, including setting the application identifier, name, and defining the initial menu items. The 'app.RunApplication()' call blocks indefinitely, keeping the application running. ```go package main import ( "github.com/caseymrm/menuet/v2" ) func main() { app := menuet.App() app.Label = "com.example.myapp" app.Name = "My App" app.Children = func() []menuet.MenuItem { return []menuet.MenuItem{ menuet.Regular{Text: "Hello World"}, } } app.RunApplication() // blocks forever } ``` -------------------------------- ### Basic Shortcut Example Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/api-reference/hotkey.md Example of creating a Regular menu item with a basic Command + Q shortcut to quit the application. ```go menuet.Regular{ Text: "Quit Application", Shortcut: &menuet.Shortcut{ KeyCode: menuet.KeyQ, Modifiers: menuet.ModCmd, }, Clicked: func() { os.Exit(0) }, } ``` -------------------------------- ### Complete Application Setup with Auto-Update Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/api-reference/update.md This Go code demonstrates a complete application setup that includes enabling and configuring the auto-update feature. It sets the application version, repository for updates, and allows for manual update checks. ```go package main import ( "fmt" "github.com/caseymrm/menuet/v2" ) const VERSION = "1.2.3" func main() { app := menuet.App() app.Label = "com.example.myapp" app.Name = "My App" // Enable auto-update app.AutoUpdate.Version = VERSION app.AutoUpdate.Repo = "caseymrm/myapp" app.AutoUpdate.AllowPrerelease = false app.Children = func() []menuet.MenuItem { return []menuet.MenuItem{ menuet.Regular{ Text: fmt.Sprintf("Version %s", VERSION), }, menuet.Separator{}, menuet.Regular{ Text: "Check for Updates", Clicked: func() { // Manual check (in addition to background 24hr checks) app.Alert(menuet.Alert{ MessageText: "Checking for updates...", }) }, }, } } app.RunApplication() } ``` -------------------------------- ### Full Example of UserDefaults Usage in Go Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/api-reference/userdefaults.md This example demonstrates loading, using, and saving application settings with UserDefaults. It includes handling the first run scenario and periodically saving changes. Ensure the 'menuet' package is imported. ```go package main import ( "log" "menuet" ) type AppSettings struct { LastLocation string Notifications bool CheckInterval int } func main() { app := menuet.App() app.Label = "com.example.myapp" // Load settings var settings AppSettings if err := menuet.Defaults().Unmarshal("settings", &settings); err != nil { // First run or corrupted settings — use defaults settings = AppSettings{ LastLocation: "San Francisco", Notifications: true, CheckInterval: 3600, } } // Use settings log.Printf("Last location: %s", settings.LastLocation) // Periodically save changes settings.LastLocation = "New York" if err := menuet.Defaults().Marshal("settings", settings); err != nil { log.Printf("Failed to save settings: %v", err) } app.Children = func() []menuet.MenuItem { return []menuet.MenuItem{ menuet.Regular{ Text: "Location: " + settings.LastLocation, Clicked: func() { settings.LastLocation = "Los Angeles" menuet.Defaults().Marshal("settings", settings) }, }, } } app.RunApplication() } ``` -------------------------------- ### Example: Toggle Mute Shortcut Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/api-reference/hotkey.md Example of creating a Regular menu item with a custom shortcut for toggling mute. ```go menuet.Regular{ Text: "Toggle Mute", Shortcut: &menuet.Shortcut{ KeyCode: menuet.KeyM, Modifiers: menuet.ModCmd | menuet.ModShift, }, Clicked: func() { toggleMute() }, } ``` -------------------------------- ### Basic Shortcut Example Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/api-reference/hotkey.md An example demonstrating how to define a basic shortcut for the 'Quit Application' menu item using `ModCmd` and `KeyQ`. ```APIDOC ### Basic Shortcut ```go menuet.Regular{ Text: "Quit Application", Shortcut: &menuet.Shortcut{ KeyCode: menuet.KeyQ, Modifiers: menuet.ModCmd, }, Clicked: func() { os.Exit(0) }, } ``` ``` -------------------------------- ### Enable Start at Login Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/README.md Set the `app.Label` to enable the 'Start at Login' menu item. This allows users to control whether the app launches automatically on startup. ```go app.Label = "com.example.myapp" // "Start at Login" item is auto-added to the menu ``` -------------------------------- ### Enable Start at Login Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/USAGE-GUIDE.md Automatically add a 'Start at Login' menu item by setting the application's label. You can also customize the text displayed for this menu item. ```go app.Label = "com.example.myapp" // "Start at Login" menu item is auto-added ``` ```go app.StartAtLoginLabel = "Launch on Startup" ``` -------------------------------- ### Custom StartAtLogin Label - Go Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/api-reference/startup.md Customizes the text displayed for the 'Start at Login' menu item. Defaults to 'Start at Login' if empty. ```go menuet.App().StartAtLoginLabel = "Launch on Startup" ``` -------------------------------- ### Example Snapshot Output Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/api-reference/snapshot.md An example of the JSON structure representing a menu snapshot, including schema version, application state, and menu items. ```json { "schema": "menuet-snapshot/v1", "state": { "title": "My App" }, "items": [ { "type": "regular", "text": "Status: ", "runs": [ { "text": "Status: ", "color": {"semantic": "secondaryLabelColor"} }, { "text": "ACTIVE", "fontWeight": 0.4, "color": {"semantic": "systemGreenColor"} } ] }, { "type": "separator" }, { "type": "regular", "text": "Settings", "children": [ { "type": "regular", "text": "Preferences..." }, { "type": "regular", "text": "About" } ] } ] } ``` -------------------------------- ### Modifier Mask Examples Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/api-reference/hotkey.md Examples demonstrating how to combine modifier constants using the bitwise OR operator. ```go // ⌘Q modifiers := menuet.ModCmd // ⌘⇧N modifiers := menuet.ModCmd | menuet.ModShift // ⌥⌃C modifiers := menuet.ModAlt | menuet.ModCtrl ``` -------------------------------- ### Get Application Singleton Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/README.md Access the global Application instance using `menuet.App()`. Configure its label and children, then run the application. ```go app := menuet.App() app.Label = "com.example.myapp" app.Children = func() []menuet.MenuItem { ... } app.RunApplication() ``` -------------------------------- ### Common Shortcut Definitions Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/USAGE-GUIDE.md Examples of common shortcut definitions using `menuet.Shortcut` with different key codes and modifiers. ```go // ⌘Q — Quit Shortcut: &menuet.Shortcut{ KeyCode: menuet.KeyQ, Modifiers: menuet.ModCmd, } ``` ```go // ⌘⇧N — New Shortcut: &menuet.Shortcut{ KeyCode: menuet.KeyN, Modifiers: menuet.ModCmd | menuet.ModShift, } ``` ```go // ⌘⌥S — Save As Shortcut: &menuet.Shortcut{ KeyCode: menuet.KeyS, Modifiers: menuet.ModCmd | menuet.ModAlt, } ``` ```go // F5 — Refresh Shortcut: &menuet.Shortcut{ KeyCode: menuet.KeyF5, Modifiers: 0, } ``` -------------------------------- ### Configure and Run Menuet Application Source: https://github.com/caseymrm/menuet/blob/master/README.md This snippet shows how to configure the application label, set up child menu items, and start the Menuet application. The `RunApplication()` function is blocking and will not return. ```go package main import ( "github.com/caseymrm/menuet" ) func main() { // Start the hourly check, and set the first value go hourlyWeather() // Configure the application menuet.App().Label = "com.github.caseymrm.menuet.weather" // Hook up the on-click to populate the menu menuet.App().Children = menuItems // Run the app (does not return) menuet.App().RunApplication() } ``` -------------------------------- ### Multi-Modifier Shortcut Example Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/api-reference/hotkey.md Example of creating a menu item with a shortcut requiring Command and another modifier (e.g., Command + Comma). Note: KeyComma is not defined, so a direct value might be needed. ```go menuet.Regular{ Text: "Open Settings", Shortcut: &menuet.Shortcut{ KeyCode: menuet.KeyComma, // Not defined; use direct value Modifiers: menuet.ModCmd, }, Clicked: func() { openSettings() }, } ``` -------------------------------- ### Constructing Menu Items and Related Types Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/functions.md Examples demonstrating how to directly construct various menuet types, including Regular menu items, Shortcuts, Alerts, and Colors. ```go // Regular item item := menuet.Regular{ Text: "Hello", Clicked: func() { doSomething() }, } ``` ```go // Shortcut sc := &menuet.Shortcut{ KeyCode: menuet.KeyQ, Modifiers: menuet.ModCmd, } ``` ```go // Alert alert := menuet.Alert{ MessageText: "Are you sure?", Buttons: []string{"Yes", "No"}, } ``` ```go // Color color := menuet.Color{R: 255, G: 0, B: 0, A: 255} // or color := menuet.SystemRed ``` -------------------------------- ### Application.StartAtLoginLabel Customization Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/api-reference/startup.md Allows customization of the label text for the 'Start at Login' menu item. If this field is empty, it defaults to 'Start at Login'. ```APIDOC ## Application.StartAtLoginLabel ### Description Customizes the label text for the 'Start at Login' menu item in the application's menu. ### Configuration ```go menuet.App().StartAtLoginLabel = "Launch on Startup" ``` ### Default Value If empty, defaults to "Start at Login". ``` -------------------------------- ### Basic Regular Menu Item Example Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/api-reference/menuitem.md Creates a simple menu item with text and a click handler. The Clicked callback is invoked when the item is selected. ```go menuet.Regular{ Text: "Open File", Clicked: func() { openFileDialog() }, } ``` -------------------------------- ### Hello World Menuet App Example Source: https://github.com/caseymrm/menuet/blob/master/README.md A basic 'Hello World' application that displays the current time in the menu bar. It requires importing the 'time' and 'menuet' packages. The application runs indefinitely, updating the menu title every second. ```go package main import ( "time" "github.com/caseymrm/menuet/v2" ) func helloClock() { for { menuet.App().SetMenuState(&menuet.MenuState{ Title: "Hello World " + time.Now().Format(":05"), }) time.Sleep(time.Second) } } func main() { go helloClock() menuet.App().RunApplication() } ``` -------------------------------- ### Type Constructors Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/functions.md Examples of how to directly construct Menuet types like Regular items, Shortcuts, Alerts, and Colors. ```APIDOC ## Type Constructors Most types in menuet are simple structs without constructor functions. Construct them directly: ```go // Regular item item := menuet.Regular{ Text: "Hello", Clicked: func() { doSomething() }, } // Shortcut sc := &menuet.Shortcut{ KeyCode: menuet.KeyQ, Modifiers: menuet.ModCmd, } // Alert alert := menuet.Alert{ MessageText: "Are you sure?", Buttons: []string{"Yes", "No"}, } // Color color := menuet.Color{R: 255, G: 0, B: 0, A: 255} // or color := menuet.SystemRed ``` ``` -------------------------------- ### Menu Item with Global Shortcut Example Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/api-reference/menuitem.md Creates a menu item that also registers a global keyboard shortcut. Ensure the shortcut combination is unique and appropriate. ```go menuet.Regular{ Text: "Quit", Shortcut: &menuet.Shortcut{ KeyCode: menuet.KeyQ, Modifiers: menuet.ModCmd, }, Clicked: func() { os.Exit(0) }, } ``` -------------------------------- ### Example: Formatted Text with Semantic Colors Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/api-reference/formatting.md Demonstrates how to combine different semantic colors and text runs to create a styled status message. ```go menuet.Regular{ Runs: []menuet.TextRun{ {Text: "Success", Color: menuet.SystemGreen}, {Text: " • ", Color: menuet.LabelTertiary}, {Text: "All tests passed", Color: menuet.LabelSecondary}, }, } ``` -------------------------------- ### Search Menu Item Example Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/api-reference/menuitem.md Creates a search menu item. The Results callback is triggered on input and returns menu items matching the query. ```go menuet.Search{ Placeholder: "Search files...", Results: func(query string) []menuet.MenuItem { var items []menuet.MenuItem for _, file := range findFiles(query) { items = append(items, menuet.Regular{ Text: file.Name, Clicked: func() { openFile(file) }, }) } return items }, } ``` -------------------------------- ### Separator Usage Example Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/api-reference/menuitem.md Demonstrates how to insert a Separator into a menu's item list to visually divide sections. ```go menuet.App().Children = func() []menuet.MenuItem { return []menuet.MenuItem{ menuet.Regular{Text: "Option 1"}, menuet.Regular{Text: "Option 2"}, menuet.Separator{}, menuet.Regular{Text: "Quit"}, } } ``` -------------------------------- ### Submenu Example Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/api-reference/menuitem.md Creates a menu item that opens a submenu when clicked. The Children callback returns the list of menu items for the submenu. ```go menuet.Regular{ Text: "Settings", Children: func() []menuet.MenuItem { return []menuet.MenuItem{ menuet.Regular{Text: "Preferences..."}, menuet.Regular{Text: "About"}, } }, } ``` -------------------------------- ### HideStartup Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/functions.md Hides the "Start at Login" menu item. This should be called before `RunApplication`. ```APIDOC ## HideStartup ### Description Hides the "Start at Login" menu item. Call before `RunApplication`. ### Method `func (a *Application) HideStartup()` ``` -------------------------------- ### Get Application Singleton Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/functions.md Returns the global Application singleton. The first call creates it; subsequent calls return the same instance. ```go func App() *Application ``` -------------------------------- ### Application.HideStartup Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/api-reference/startup.md Hides the 'Start at Login' menu item from the default menu. This should be called before `RunApplication` if your application manages startup manually or does not support it. ```APIDOC ## Application.HideStartup ### Description Hides the "Start at Login" menu item from the default menu. Call before `RunApplication` if your app manages startup manually or doesn't support it. ### Method `func (a *Application) HideStartup()` ### Example ```go app := menuet.App() app.HideStartup() app.RunApplication() ``` ``` -------------------------------- ### Example: TextRun Emphasis Styling Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/api-reference/formatting.md Demonstrates applying strikethrough and bold font weight to TextRuns to highlight changes or emphasize specific text. ```go menuet.Regular{ Runs: []menuet.TextRun{ { Text: "Price: $50", Strikethrough: true, StrikethroughColor: menuet.SystemRed, }, {Text: " ", Color: menuet.Color{}}, { Text: "$30", Color: menuet.SystemGreen, FontWeight: menuet.WeightBold, }, }, } ``` -------------------------------- ### Settings with Persistence Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/README.md Store and restore user preferences using Menuet's persistence features. This example shows loading settings on startup and saving changes when a setting is modified. ```go type AppSettings struct { Theme string AutoRefresh bool } var settings AppSettings func init() { // Load on startup menuet.Defaults().Unmarshal("settings", &settings) } app.Children = func() []menuet.MenuItem { return []menuet.MenuItem{ menuet.Regular{ Text: "Dark Mode", State: settings.Theme == "dark", Clicked: func() { settings.Theme = "dark" menuet.Defaults().Marshal("settings", settings) }, }, } } ``` -------------------------------- ### Hide Startup Menu Item - Go Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/api-reference/startup.md Hides the 'Start at Login' menu item. Call this before `RunApplication` if your app manages startup manually or does not support it. ```go func (a *Application) HideStartup() { } ``` -------------------------------- ### Dynamic Menu Content Generation Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/USAGE-GUIDE.md This example shows how to dynamically generate menu items each time the menu is opened. It iterates over a list of recent files, creating a menu item for each, and includes a 'Quit' option. Ensure 'recentFiles()' and 'openFile()' are defined. ```go app.Children = func() []menuet.MenuItem { var items []menuet.MenuItem for _, file := range recentFiles() { f := file // capture for closure items = append(items, menuet.Regular{ Text: f.Name, Clicked: func() { openFile(f) }, }) } items = append(items, menuet.Separator{}) items = append(items, menuet.Regular{ Text: "Quit", Clicked: func() { os.Exit(0) }, }) return items } ``` -------------------------------- ### Example: Mixed TextRun Styling Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/api-reference/formatting.md Illustrates combining various TextRun fields like color, font weight, and monospaced settings to style different parts of a text string. ```go menuet.Regular{ Runs: []menuet.TextRun{ {Text: "Status: ", Color: menuet.LabelSecondary}, {Text: "ACTIVE", FontWeight: menuet.WeightBold, Color: menuet.SystemGreen}, {Text: " (monospaced: ", Monospaced: false}, {Text: "192.168.1.1", Monospaced: true, FontSize: 12}, {Text: ")"}, }, } ``` -------------------------------- ### HideStartup Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/api-reference/application.md Hides the "Start at Login" menu item from the default menu. Call this before `RunApplication` if your app manages startup manually. ```APIDOC ## HideStartup ### Description Hides the "Start at Login" menu item from the default menu. Call this before `RunApplication` if your app manages startup manually. ### Example ```go app := menuet.App() app.HideStartup() app.RunApplication() ``` ``` -------------------------------- ### Handle User Interaction with Callbacks Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/INDEX.md Implement user interaction logic using Go function values for callbacks. This example shows how to define an action for a menu item's click event. ```go menuet.Regular{ Clicked: func() { doSomething() }, Children: func() []menuet.MenuItem { ... }, } ``` -------------------------------- ### Stateful Toggle Menu Item Example Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/api-reference/menuitem.md Creates a menu item that displays a checkmark based on its State. The Clicked callback is used to toggle the state. ```go menuet.Regular{ Text: "Mute Audio", State: isMuted(), Clicked: func() { toggleMute() }, } ``` -------------------------------- ### Common Shortcut Definitions Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/api-reference/hotkey.md Examples of defining common shortcuts like New, Save, Undo, Redo, and Save As using specific key codes and modifier combinations. ```go // ⌘N — New New: &menuet.Shortcut{KeyCode: menuet.KeyN, Modifiers: menuet.ModCmd} // ⌘S — Save Save: &menuet.Shortcut{KeyCode: menuet.KeyS, Modifiers: menuet.ModCmd} // ⌘Z — Undo Undo: &menuet.Shortcut{KeyCode: menuet.KeyZ, Modifiers: menuet.ModCmd} // ⌘⇧Z — Redo Redo: &menuet.Shortcut{KeyCode: menuet.KeyZ, Modifiers: menuet.ModCmd | menuet.ModShift} // ⌘⌥S — Save As SaveAs: &menuet.Shortcut{KeyCode: menuet.KeyS, Modifiers: menuet.ModCmd | menuet.ModAlt} ``` -------------------------------- ### Multi-Modifier Shortcut Example Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/api-reference/hotkey.md Illustrates creating a shortcut that requires multiple modifier keys, such as Command and Shift, for actions like 'Open Settings'. ```APIDOC ### Multi-Modifier Shortcut ```go menuet.Regular{ Text: "Open Settings", Shortcut: &menuet.Shortcut{ KeyCode: menuet.KeyComma, // Not defined; use direct value Modifiers: menuet.ModCmd, }, Clicked: func() { openSettings() }, } ``` ``` -------------------------------- ### Example: TextRun Badge Styling Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/api-reference/formatting.md Shows how to use the 'Badge' field in TextRun to render text as a colored pill, often used for counts or tags. ```go menuet.Regular{ Runs: []menuet.TextRun{ {Text: "New Updates ", Badge: false}, {Text: "5", Badge: true, Color: menuet.SystemOrange}, }, } ``` -------------------------------- ### Get Singleton Application Instance Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/api-reference/application.md Retrieves the singleton Application instance. The first call creates it; subsequent calls return the same object. This is the main entry point for interacting with Menuet. ```go app := menuet.App() app.Label = "com.example.myapp" app.Children = func() []menuet.MenuItem { return []menuet.MenuItem{ menuet.Regular{Text: "Hello"}, } } app.RunApplication() ``` -------------------------------- ### Menu Item with Rich Text Formatting Example Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/api-reference/menuitem.md Creates a menu item using TextRun slices for per-segment text styling, allowing different colors and weights within the same item. ```go menuet.Regular{ Runs: []menuet.TextRun{ {Text: "Status: ", Color: menuet.LabelSecondary}, {Text: "ACTIVE", FontWeight: menuet.WeightBold, Color: menuet.SystemGreen}, }, } ``` -------------------------------- ### LaunchAgent Plist Format - XML Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/api-reference/startup.md Example structure of a LaunchAgent plist file generated by Menuet for older macOS versions or unsigned builds. This file manages automatic app launching via launchd. ```xml Labelcom.example.myapp Program/path/to/MyApp.app/Contents/MacOS/myapp StandardOutPath/tmp/com.example.myapp-out.log StandardErrorPath/tmp/com.example.myapp-err.log RunAtLoad ``` -------------------------------- ### Build and Run App Bundle Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/api-reference/notification.md After configuring the Makefile, run this command to build and launch your application as a bundle, which is necessary for notifications. ```bash make run ``` -------------------------------- ### Build and Run Menuet App with Makefile Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/USAGE-GUIDE.md Instructions for building and running a Menuet application using the provided Makefile. 'make run' compiles and launches the app, while 'make clean' removes build artifacts. ```makefile APP=My App IDENTIFIER=com.example.myapp include $(GOPATH)/src/github.com/caseymrm/menuet/menuet.mk ``` ```bash make run # Build and launch make clean # Clean artifacts ``` -------------------------------- ### Basic Menuet Application Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/00-START-HERE.md This Go code demonstrates the fundamental structure of a Menuet application. It initializes the app, sets a unique identifier, defines a simple menu with a 'Hello World' item, and runs the application. Ensure the app identifier is unique for your application. ```go package main import "github.com/caseymrm/menuet/v2" func main() { app := menuet.App() app.Label = "com.example.myapp" app.Children = func() []menuet.MenuItem { return []menuet.MenuItem{ menuet.Regular{Text: "Hello World"}, } } app.RunApplication() // blocks forever } ``` -------------------------------- ### Manage Preferences with Defaults() Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/USAGE-GUIDE.md Use `menuet.Defaults()` for simple preference retrieval (e.g., strings) and `Unmarshal` for complex configuration structures. ```go // Simple token := menuet.Defaults().String("api_token") // Complex type Config struct { Servers []string Options map[string]interface{} } var config Config menuet.Defaults().Unmarshal("config", &config) ``` -------------------------------- ### Get Boolean from UserDefaults Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/api-reference/userdefaults.md Retrieves a boolean value from user defaults using its key. Returns false if the key is not found. ```go darkMode := menuet.Defaults().Boolean("dark_mode") if darkMode { applyDarkTheme() } ``` -------------------------------- ### Get Integer from UserDefaults Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/api-reference/userdefaults.md Retrieves an integer value from user defaults using its key. Returns 0 if the key is not found. ```go width := menuet.Defaults().Integer("window_width") if width == 0 { width = 400 // default } ``` -------------------------------- ### App Constructor Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/api-reference/application.md Returns the singleton Application instance. This is the primary entry point for interacting with menuet. ```APIDOC ## App Constructor ### Description Returns the singleton `Application` instance. The first call creates the instance; subsequent calls return the same object. This is the primary entry point for interacting with menuet. ### Returns `*Application` — the application singleton ### Example ```go app := menuet.App() app.Label = "com.example.myapp" app.Children = func() []menuet.MenuItem { return []menuet.MenuItem{ menuet.Regular{Text: "Hello"}, } } app.RunApplication() ``` ``` -------------------------------- ### Get String from UserDefaults Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/api-reference/userdefaults.md Retrieves a string value from user defaults using its key. Returns an empty string if the key is not found. ```go token := menuet.Defaults().String("api_token") if token == "" { // Not set yet } ``` -------------------------------- ### Get UserDefaults Singleton Instance Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/api-reference/userdefaults.md Access the singleton instance of UserDefaults. The first call creates it; subsequent calls return the same instance. ```go prefs := menuet.Defaults() prefs.SetString("last_location", "San Francisco") ``` -------------------------------- ### Generate Snapshot Locally Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/api-reference/snapshot.md Command-line instructions to build an application and generate a snapshot to a specified file path with an optional delay. The generated JSON can then be viewed using `jq`. ```bash # Build your app make clean && make # Generate snapshot MENUET_SNAPSHOT_PATH=/tmp/menu.json MENUET_SNAPSHOT_DELAY=3s \ ./My\ App.app/Contents/MacOS/myapp # View the result cat /tmp/menu.json | jq . ``` -------------------------------- ### Build and Run Menuet Application Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/00-START-HERE.md These Makefile and bash commands are used to build and run a Menuet application. Ensure the `APP` and `IDENTIFIER` variables in the Makefile are set correctly for your project. The `menuet.mk` file must be included from your GOPATH. ```makefile # Makefile APP=My App IDENTIFIER=com.example.myapp include $(GOPATH)/src/github.com/caseymrm/menuet/menuet.mk ``` ```bash make run ``` -------------------------------- ### Get Graceful Shutdown Handles Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/functions.md Returns handles for coordinating the graceful shutdown of background goroutines. Provides a WaitGroup and a Context for managing shutdown. ```go func (a *Application) GracefulShutdownHandles() (*sync.WaitGroup, context.Context) ``` -------------------------------- ### Generate Snapshot for Testing Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/USAGE-GUIDE.md Create a menu preview JSON file without launching the application by setting the `MENUET_SNAPSHOT_PATH` environment variable. An optional delay can be specified using `MENUET_SNAPSHOT_DELAY` for startup goroutines. ```bash MENUET_SNAPSHOT_PATH=/tmp/menu.json ./My\ App.app/Contents/MacOS/myapp ``` ```bash MENUET_SNAPSHOT_DELAY=5s MENUET_SNAPSHOT_PATH=/tmp/menu.json ./app ``` -------------------------------- ### Verify Go Code Types and Build Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/USAGE-GUIDE.md Use `go vet` to perform static analysis and detect type errors. Run `go build` to ensure the application compiles successfully. ```bash go vet ./... go build ``` -------------------------------- ### RunApplication Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/api-reference/application.md Enters the AppKit event loop and displays the menubar application. This function does not return unless MENUET_SNAPSHOT_PATH is set. ```APIDOC ## RunApplication ### Description Enters the AppKit event loop and displays the menubar application. This function does not return unless `MENUET_SNAPSHOT_PATH` is set (used for testing/preview mode). In snapshot mode, `RunApplication` waits `MENUET_SNAPSHOT_DELAY` (default 2 seconds) for startup goroutines to populate state, then writes a JSON snapshot and returns. This allows apps to generate menu mockups without running the full event loop. **Special behavior:** - If `AutoUpdate.Version` and `AutoUpdate.Repo` are set, spawns a background goroutine that checks for updates every 24 hours. - Respects `MENUET_SNAPSHOT_PATH` and `MENUET_SNAPSHOT_DELAY` environment variables for testing. ### Example ```go func main() { menuet.App().Label = "com.example.app" menuet.App().RunApplication() // blocks forever } ``` ``` -------------------------------- ### Configure Auto-Update Settings Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/api-reference/application.md Set the current application version, the GitHub repository for updates, and whether to allow prerelease versions. Ensure the repository is in 'owner/repo' format. ```go menuet.App().AutoUpdate.Version = "1.0.0" menuet.App().AutoUpdate.Repo = "caseymrm/myapp" menuet.App().AutoUpdate.AllowPrerelease = false ``` -------------------------------- ### Accessing UserDefaults Singleton Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/api-reference/userdefaults.md Get the singleton instance of UserDefaults to interact with the user defaults system. This instance is created on the first call to Defaults() and reused for all subsequent calls. ```APIDOC ## Defaults Function ```go func Defaults() *UserDefaults ``` Returns the singleton `UserDefaults` instance. The first call creates it; subsequent calls return the same instance. **Returns:** `*UserDefaults` — the user defaults singleton **Example:** ```go prefs := menuet.Defaults() prefs.SetString("last_location", "San Francisco") ``` ``` -------------------------------- ### App() Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/functions.md Returns the global Application singleton. The first call creates it; subsequent calls return the same instance. ```APIDOC ## App() ### Description Returns the global Application singleton. First call creates it; subsequent calls return the same instance. ### Returns - `*Application` - The global Application singleton instance. ``` -------------------------------- ### Apply Type-Safe Styling with TextRuns Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/INDEX.md Format text within menu items using typed field values for properties like color. This example demonstrates setting text to red. ```go menuet.Regular{ Runs: []menuet.TextRun{ {Text: "Red", Color: menuet.SystemRed}, }, } ``` -------------------------------- ### Create a Simple Menuet App Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/README.md This Go code creates a basic menu bar application that updates its title every second and displays a 'Quit' option. Ensure the `os` package is imported if using `os.Exit`. ```go package main import ( "time" "github.com/caseymrm/menuet/v2" "os" ) func main() { app := menuet.App() app.Label = "com.example.myapp" // Update title every second go func() { for { menuet.App().SetMenuState(&menuet.MenuState{ Title: time.Now().Format("15:04:05"), }) time.Sleep(time.Second) } }() // Return menu items app.Children = func() []menuet.MenuItem { return []menuet.MenuItem{ menuet.Regular{ Text: "Time: " + time.Now().Format("15:04:05"), }, menuet.Separator{}, menuet.Regular{ Text: "Quit", Clicked: func() { os.Exit(0) }, }, } } app.RunApplication() // blocks forever } ``` -------------------------------- ### Run Menuet Application Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/api-reference/application.md Enters the AppKit event loop to display the menubar application. This function typically blocks indefinitely unless in snapshot mode (controlled by environment variables for testing). ```go func main() { menuet.App().Label = "com.example.app" menuet.App().RunApplication() // blocks forever } ``` -------------------------------- ### Store and Load String Preferences Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/README.md Use `menuet.Defaults()` to persist simple string values. `SetString` saves a value, and `String` retrieves it. ```go // Save menuet.Defaults().SetString("api_token", token) menuet.Defaults().SetBoolean("notifications_enabled", true) // Load token := menuet.Defaults().String("api_token") enabled := menuet.Defaults().Boolean("notifications_enabled") ``` -------------------------------- ### RunApplication Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/functions.md Enters the AppKit event loop. This method does not return unless MENUET_SNAPSHOT_PATH is set, in which case it returns after writing JSON. ```APIDOC ## RunApplication ### Description Enters the AppKit event loop. Does not return unless `MENUET_SNAPSHOT_PATH` is set (snapshot mode returns after writing JSON). ### Method `func (a *Application) RunApplication()` ``` -------------------------------- ### Create GitHub Release with Git Tag Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/api-reference/update.md Manually create a Git tag and push it to your repository. Then, manually upload a .zip file containing your application bundle to the corresponding GitHub release. ```bash git tag v1.2.3 git push origin v1.2.3 # Then manually upload a .zip containing your .app bundle to the release ``` -------------------------------- ### Generate Snapshot for Documentation Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/api-reference/snapshot.md Command to generate a menu snapshot using a catalog application, which can then be used for creating website previews or README screenshots. ```bash ./cmd/catalog/Catalog.app/Contents/MacOS/catalog > /tmp/snapshot.json # Use the JSON to generate website previews, README screenshots, etc. ``` -------------------------------- ### Run Menuet Application in Background Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/USAGE-GUIDE.md Execute the `make run` command in the background using `&` for development purposes. The application will continue to run, allowing you to attach or kill it as needed. ```bash make run & # App continues to run; attach or kill as needed ``` -------------------------------- ### Show Alerts to User Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/README.md Display an alert box with a message and custom buttons using `menuet.App().Alert()`. The response indicates which button was clicked. ```go response := menuet.App().Alert(menuet.Alert{ MessageText: "Save changes?", Buttons: []string{"Save", "Discard"}, }) if response.Button == 0 { save() } ``` -------------------------------- ### Generate Snapshot JSON for Debugging Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/USAGE-GUIDE.md Run the application in snapshot mode to capture menu structure as JSON. Set `MENUET_SNAPSHOT_PATH` to specify the output file and `MENUET_SNAPSHOT_DELAY` to control the delay before snapshotting. Pipe the output to `jq` for pretty-printing. ```bash MENUET_SNAPSHOT_PATH=/tmp/debug.json MENUET_SNAPSHOT_DELAY=3s ./app cat /tmp/debug.json | jq . ``` -------------------------------- ### Application Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/types.md The main application controller, accessed via the App() singleton. It manages application-level settings and menu structure. ```APIDOC ## Type: Application ### Description The main application controller. Accessed via `App()` singleton. ### Fields - **Name** (string) - The name of the application. - **Label** (string) - The display label for the application. - **Children** (func() []MenuItem) - A function that returns the top-level menu items. - **AutoUpdate** (struct) - Configuration for automatic updates. - **Version** (string) - The current version. - **Repo** (string) - The repository URL for updates. - **AllowPrerelease** (bool) - Whether to allow pre-release versions. - **NotificationResponder** (func(id, response string)) - Callback for handling notifications. - **Clicked** (func()) - Callback for when the application is clicked (e.g., in the dock). - **StartAtLoginLabel** (string) - The label for the 'Start at Login' option. - **QuitLabel** (string) - The label for the 'Quit' option. ``` -------------------------------- ### Run Application in Snapshot Mode for Testing Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/api-reference/update.md Execute the application in snapshot mode for testing purposes. This mode allows for testing without the event loop and requires specifying a snapshot path and delay. ```bash MENUET_SNAPSHOT_PATH=/tmp/menu.json MENUET_SNAPSHOT_DELAY=5s ./myapp ``` -------------------------------- ### Run Application Event Loop Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/functions.md Enters the AppKit event loop. This function does not return unless MENUET_SNAPSHOT_PATH is set, in which case it returns after writing a snapshot. ```go func (a *Application) RunApplication() ``` -------------------------------- ### Implement Stateful Menu Items Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/USAGE-GUIDE.md Create menu items with dynamic states (e.g., checked/unchecked) and associated click handlers. The `State` property controls the visual state, and `Clicked` defines the action performed when the item is selected. ```go app.Children = func() []menuet.MenuItem { return []menuet.MenuItem{ menuet.Regular{ Text: "Dark Mode", State: isDarkMode, Clicked: func() { isDarkMode = !isDarkMode applyTheme(isDarkMode) }, }, menuet.Regular{ Text: "Notifications", State: notificationsEnabled, Clicked: func() { notificationsEnabled = !notificationsEnabled }, }, } } ``` -------------------------------- ### Create a Recent Items List Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/USAGE-GUIDE.md Dynamically generate a list of recent files in the menu bar. Each item is clickable, opening the respective file. Includes an option to clear the list and a separator. ```go app.Children = func() []menuet.MenuItem { var items []menuet.MenuItem for _, file := range recentFiles() { f := file items = append(items, menuet.Regular{ Text: f.Name, Clicked: func() { openFile(f) }, }) } if len(items) > 0 { items = append(items, menuet.Separator{}) } items = append(items, menuet.Regular{ Text: "Clear Recent", Clicked: clearRecent, }) return items } ``` -------------------------------- ### Application Type Definition Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/types.md Defines the structure for the main application controller, accessed via the App() singleton. Used for initialization and menu management. ```go type Application struct { Name string Label string Children func() []MenuItem AutoUpdate struct { Version string Repo string AllowPrerelease bool } NotificationResponder func(id, response string) Clicked func() StartAtLoginLabel string QuitLabel string } ``` -------------------------------- ### Sign App for Production Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/README.md Command to sign the application for production distribution. This requires a Developer ID. ```bash make sign ``` -------------------------------- ### Snapshot Structure Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/types.md Represents a JSON-serializable snapshot of the application's menu state. Used for testing and previewing menu configurations. It includes schema information and the menu's state. ```go type Snapshot struct { Schema string State *MenuState Items []SnapshotItem } ``` -------------------------------- ### Basic Menu Items with Click Handlers Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/USAGE-GUIDE.md Defines basic menu items, including a separator. The 'Clicked' function is executed when a menu item is selected. Ensure 'handleClick()' is defined elsewhere. ```go app.Children = func() []menuet.MenuItem { return []menuet.MenuItem{ menuet.Regular{ Text: "Item 1", Clicked: func() { handleClick() }, }, menuet.Separator{}, menuet.Regular{ Text: "Item 2", }, } } ``` -------------------------------- ### Application.Label Configuration Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/api-reference/startup.md The `Label` field must be set for startup management to function correctly. It is used as a reverse-domain bundle identifier and for naming LaunchAgent plist files. ```APIDOC ## Application.Label ### Description The `Label` field must be set for startup management to work. Without it, the 'Start at Login' menu item is hidden, and startup toggling becomes a no-op. ### Configuration ```go menuet.App().Label = "com.example.myapp" ``` ### Notes - The label is a reverse-domain bundle identifier. - It's used as the base name for LaunchAgent plist files (e.g., `~/Library/LaunchAgents/com.example.myapp.plist`). - If the Label is not set, a warning is logged. ``` -------------------------------- ### Enable Custom Logging in Go Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/USAGE-GUIDE.md Configure the Go log package to include timestamps and file names for better debugging. Use `log.Println` to output custom debug information. ```go log.SetFlags(log.LstdFlags | log.Lshortfile) log.Println("Debug info:", someValue) ``` -------------------------------- ### Constructing a Menu with Menu Items Source: https://github.com/caseymrm/menuet/blob/master/README.md Define the application's menu structure by returning a slice of menuet.MenuItem. This includes regular menu items and separators. ```go menuet.App().Children = func() []menuet.MenuItem { return []menuet.MenuItem{ menuet.Regular{Text: "Status: Active"}, menuet.Separator{}, menuet.Regular{Text: "Refresh", Clicked: refresh}, menuet.Regular{Text: "Submenu", Children: subItems}, } } ``` -------------------------------- ### Set Application Label - Go Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/api-reference/startup.md Sets the `Label` field, which is required for startup management to function correctly. This label is also used for LaunchAgent plist filenames. ```go menuet.App().Label = "com.example.myapp" ``` -------------------------------- ### Creating Submenus Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/USAGE-GUIDE.md Demonstrates how to create nested menus (submenus) by assigning a function returning a slice of menu items to the 'Children' field of a menu item. The 'exitApp' function should be defined elsewhere. ```go menuet.Regular{ Text: "File", Children: func() []menuet.MenuItem { return []menuet.MenuItem{ menuet.Regular{Text: "New"}, menuet.Regular{Text: "Open"}, menuet.Separator{}, menuet.Regular{Text: "Exit", Clicked: exitApp}, } }, } ``` -------------------------------- ### Search Menu with Filtering Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/USAGE-GUIDE.md Implements a search menu that allows users to filter items dynamically. The 'Results' function takes a query string and returns a slice of menu items matching the search criteria. Ensure 'allItems', 'selectItem()', and 'strings' package are available. ```go menuet.Search{ Placeholder: "Search...", Results: func(query string) []menuet.MenuItem { var results []menuet.MenuItem for _, item := range allItems { if strings.Contains(item.Name, query) { i := item // capture for closure results = append(results, menuet.Regular{ Text: i.Name, Clicked: func() { selectItem(i) }, }) } } return results }, } ``` -------------------------------- ### Configure Auto-Update Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/README.md Enable automatic updates by setting the `Version` and `Repo` fields for the `app.AutoUpdate` configuration. `AllowPrerelease` controls whether pre-release versions are considered. ```go app.AutoUpdate.Version = "1.2.3" app.AutoUpdate.Repo = "owner/myapp" app.AutoUpdate.AllowPrerelease = false ``` -------------------------------- ### Set Auto-Update Version and Repository Source: https://github.com/caseymrm/menuet/blob/master/_autodocs/api-reference/update.md Configure the application's auto-update settings by specifying the current version and the GitHub repository to check for new releases. This is typically done during application initialization. ```go app.AutoUpdate.Version = "0.1.0" app.AutoUpdate.Repo = "caseymrm/myapp" ```