-
Notifications
You must be signed in to change notification settings - Fork 71
/
cliview.go
81 lines (73 loc) · 2.23 KB
/
cliview.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
// Copyright (c) 2023, Cogent Core. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
// Package cliview extends package cli by generating GUIs.
package cliview
import (
"fmt"
"os"
"cogentcore.org/core/base/logx"
"cogentcore.org/core/base/strcase"
"cogentcore.org/core/cli"
"cogentcore.org/core/core"
"cogentcore.org/core/events"
"cogentcore.org/core/views"
)
// Run runs the given app with the given default
// configuration file paths. It is similar to
// [cli.Run], but it also runs the GUI if no
// arguments were provided. The app should be
// a pointer, and configuration options should
// be defined as fields on the app type. Also,
// commands should be defined as methods on the
// app type with the suffix "Cmd"; for example,
// for a command named "build", there should be
// the method:
//
// func (a *App) BuildCmd() error
//
// Run uses [os.Args] for its arguments.
func Run[T any, C cli.CmdOrFunc[T]](opts *cli.Options, cfg T, cmds ...C) error {
cs, err := cli.CmdsFromCmdOrFuncs[T, C](cmds)
if err != nil {
err := fmt.Errorf("error getting commands from given commands: %w", err)
if opts.Fatal {
logx.PrintlnError(err)
os.Exit(1)
}
return err
}
cs = cli.AddCmd(cs, &cli.Cmd[T]{
Func: func(t T) error {
GUI(opts, t, cs...)
return nil
},
Name: "gui",
Doc: "gui runs the GUI version of the " + opts.AppName + " tool",
Root: true, // if root isn't already taken, we take it
})
return cli.Run(opts, cfg, cs...)
}
// GUI starts the GUI for the given cli app, which must be passed as
// a pointer. It should typically not be called by end-user code; see [Run].
func GUI[T any](opts *cli.Options, cfg T, cmds ...*cli.Cmd[T]) {
b := core.NewBody(opts.AppName)
b.AddAppBar(func(tb *core.Toolbar) {
for _, cmd := range cmds {
if cmd.Name == "gui" { // we are already in GUI so that command is irrelevant
continue
}
core.NewButton(tb, cmd.Name).SetText(strcase.ToSentence(cmd.Name)).SetTooltip(cmd.Doc).
OnClick(func(e events.Event) {
err := cmd.Func(cfg)
if err != nil {
// TODO: snackbar
logx.PrintlnError(err)
}
})
}
})
sv := views.NewStructView(b)
sv.SetStruct(cfg)
b.RunMainWindow()
}