package main import ( "fmt" "os" "strings" "fyne.io/fyne/v2" "fyne.io/fyne/v2/app" "github.com/urfave/cli/v2" ) // Configuration. const ( DefaultIcon = "attention" DefaultTitle = "Error" DefaultMessage = "Something went wrong." ) var MainWindow fyne.Window func main() { LoadIcons() // The command line interface. (&cli.App{ Name: "errorgen", Usage: "make fun and custom error messages.", Authors: []*cli.Author{ {Name: "Noah Petherbridge, https://www.kirsle.net"}, }, Flags: []cli.Flag{ &cli.BoolFlag{ Name: "version", Aliases: []string{"v"}, Usage: "Show program version and build information and exit.", }, // Easy shortcut flags. &cli.BoolFlag{ Name: "error", Aliases: []string{"e"}, Usage: `Make the dialog box be of type 'error' by default. An info box has these default attributes unless overridden by other options: Title: Error Text: An error has occurred. Icon: error Buttons: Ok`, }, &cli.BoolFlag{ Name: "alert", Aliases: []string{"a"}, Usage: `Make the dialog box be of type 'alert' by default. An alert box has these default attributes unless overridden by other options: Title: Warning Text: Are you sure you want to proceed? Icon: attention Buttons: Ok`, }, &cli.BoolFlag{ Name: "info", Aliases: []string{"i"}, Usage: `Make the dialog box be of type 'info' by default. An info box has these default attributes unless overridden by other options: Title: Information Text: All updates are complete. Icon: info Buttons: Ok`, }, &cli.BoolFlag{ Name: "question", Aliases: []string{"q"}, Usage: `Make the dialog box be of type 'question' by default. A question box has these default attributes unless overridden by other options: Title: Question Text: Are you sure you want to proceed? Icon: question Buttons: Ok, Cancel`, }, // Customized flags. &cli.StringFlag{ Name: "title", Aliases: []string{"n"}, Usage: `Set the title for the dialog box. If no title is set, a default is used based on the type of dialog box requested (which is --info by default; see also --error, --info, --question)`, }, &cli.StringFlag{ Name: "text", Aliases: []string{"t"}, Usage: `The text displayed inside the dialog box. Use \n where you want line breaks. Important: the text does NOT have automatic word wrapping applied. Insert your own line breaks or else the dialog can be VERY wide for longer messages!`, }, &cli.StringSliceFlag{ Name: "button", Aliases: []string{"b"}, Usage: `Add a button to the dialog. Use this option as many times as you want to add multiple buttons. The one the user chooses will be printed to standard output. If no buttons, default is an Ok button.`, }, &cli.StringFlag{ Name: "default", Aliases: []string{"m"}, Usage: `Set the default button by its label. The matching --button will be made the default/primary button.`, }, &cli.StringFlag{ Name: "cancel", Aliases: []string{"c"}, Usage: `Set the 'cancel button'. This value should match one of your --buttons and will be the value 'selected' if the user closes the window or hits the Escape key.`, }, &cli.IntSliceFlag{ Name: "disabled", Aliases: []string{"d", "g"}, Usage: `Mark buttons (by index) disabled Specify a --button number (from 0 to n) that should be disabled, or greyed out. The user can not click on this button.`, }, &cli.StringFlag{ Name: "icon", Aliases: []string{"o"}, Usage: fmt.Sprintf(` Set the icon to be displayed in the dialog box. Use either a built-in icon by name (e.g. "aim_guy") or name your own custom PNG image from disk. Built-in icon names include the following: %s`, strings.Join(iconNames, "\n "), ), }, }, Action: func(c *cli.Context) error { if c.Bool("version") { fmt.Printf("Version: %s\nBuild: %s\nBuilt on: %s\n", Version, Build, BuildDate) return nil } // If run with no flags: show the nice GUI. if c.NumFlags() == 0 { RunGUI() return nil } // Build up the dialog. d := NewDialog() d.Buttons = []*Button{ { Label: "Ok", }, } // Easy setting templates. if c.Bool("error") { d.Title = "Error" d.Message = "An error has occurred." d.Icon = icons["error"] } else if c.Bool("alert") { d.Title = "Warning" d.Message = "Are you sure you want to proceed?" d.Icon = icons["attention"] } else if c.Bool("question") { d.Title = "Question" d.Message = "Are you sure you want to proceed?" d.Icon = icons["bubble_q"] d.Buttons = []*Button{ { Label: "Ok", }, { Label: "Cancel", }, } } else { d.Title = "Information" d.Message = "All updates are complete." d.Icon = icons["bubble_i"] } // Other customizations. if v := c.String("title"); v != "" { d.Title = v } if v := c.String("text"); v != "" { d.Message = v } if v := c.String("icon"); v != "" { if icon, ok := icons[v]; ok { d.Icon = icon } else { if name, err := LoadCustomIcon(v); err == nil { d.Icon = icons[name] } } } if buttons := c.StringSlice("button"); len(buttons) > 0 { d.Buttons = []*Button{} for _, label := range buttons { d.Buttons = append(d.Buttons, &Button{ Label: label, }) } } if disabled := c.IntSlice("disabled"); len(disabled) > 0 { for _, idx := range disabled { if idx >= 0 && idx < len(d.Buttons) { d.Buttons[idx].Disabled = true } } } if cancel := c.String("cancel"); cancel != "" { d.Cancel = cancel } // If there were trailing args, use that as the message. if args := c.Args(); args.Len() > 0 { d.Message = strings.Join(args.Slice(), " ") } a := app.New() d.Show(a) a.Run() return nil }, }).Run(os.Args) }