mirror of
https://github.com/diamondburned/cchat-gtk.git
synced 2024-11-17 03:32:56 +00:00
123 lines
2.9 KiB
Go
123 lines
2.9 KiB
Go
// Package config contains UI widgets and renderers for cchat's Configurator
|
|
// interface.
|
|
package config
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/diamondburned/cchat"
|
|
"github.com/diamondburned/cchat-gtk/internal/gts"
|
|
"github.com/diamondburned/cchat-gtk/internal/ui/config"
|
|
"github.com/diamondburned/cchat-gtk/internal/ui/primitives/menu"
|
|
"github.com/diamondburned/cchat-gtk/internal/ui/rich"
|
|
"github.com/gotk3/gotk3/gtk"
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
type Configurator struct {
|
|
cchat.Service
|
|
cchat.Configurator
|
|
}
|
|
|
|
func MenuItem(conf Configurator) menu.Item {
|
|
return menu.SimpleItem("Configure", func() { Spawn(conf) })
|
|
}
|
|
|
|
// Restore restores the config in the background.
|
|
func Restore(conf Configurator) {
|
|
gts.Async(func() (func(), error) {
|
|
c, err := conf.Configuration()
|
|
if err != nil {
|
|
return nil, errors.Wrapf(err, "failed to get %s config", conf.ID())
|
|
}
|
|
|
|
file := serviceFile(conf)
|
|
|
|
if err := config.UnmarshalFromFile(file, &c); err != nil {
|
|
return nil, errors.Wrapf(err, "failed to unmarshal %s config", conf.ID())
|
|
}
|
|
|
|
if err := conf.SetConfiguration(c); err != nil {
|
|
return nil, errors.Wrapf(err, "failed to set %s config", conf.ID())
|
|
}
|
|
|
|
return nil, nil
|
|
})
|
|
}
|
|
|
|
func Spawn(conf Configurator) error {
|
|
gts.Async(func() (func(), error) {
|
|
c, err := conf.Configuration()
|
|
if err != nil {
|
|
return nil, errors.Wrapf(err, "failed to get %s config", conf.ID())
|
|
}
|
|
|
|
file := serviceFile(conf)
|
|
|
|
err = config.UnmarshalFromFile(file, &c)
|
|
err = errors.Wrapf(err, "failed to unmarshal %s config", conf.ID())
|
|
|
|
return func() {
|
|
spawn(conf, c, func(finalized bool) error {
|
|
if err := conf.SetConfiguration(c); err != nil {
|
|
return err
|
|
}
|
|
|
|
if finalized {
|
|
gts.Async(func() (func(), error) {
|
|
return nil, config.MarshalToFile(file, c)
|
|
})
|
|
}
|
|
|
|
return nil
|
|
})
|
|
}, err
|
|
})
|
|
|
|
return nil
|
|
}
|
|
|
|
func serviceFile(conf Configurator) string {
|
|
return fmt.Sprintf("services/%s.json", conf.ID())
|
|
}
|
|
|
|
func spawn(c Configurator, conf map[string]string, apply func(final bool) error) {
|
|
container := newContainer(conf, func() error { return apply(false) })
|
|
container.Grid.SetVAlign(gtk.ALIGN_START)
|
|
|
|
sw, _ := gtk.ScrolledWindowNew(nil, nil)
|
|
sw.Add(container.Grid)
|
|
sw.Show()
|
|
|
|
b, _ := gtk.BoxNew(gtk.ORIENTATION_VERTICAL, vmargin)
|
|
b.SetMarginTop(vmargin)
|
|
b.SetMarginBottom(vmargin)
|
|
b.SetMarginStart(hmargin)
|
|
b.SetMarginEnd(hmargin)
|
|
b.PackStart(sw, true, true, 0)
|
|
b.PackStart(container.ErrHeader, false, false, 0)
|
|
b.Show()
|
|
|
|
h, _ := gtk.HeaderBarNew()
|
|
h.SetTitle("Configure " + c.ID())
|
|
h.SetShowCloseButton(true)
|
|
h.Show()
|
|
|
|
var state rich.NameContainer
|
|
state.OnUpdate(func() {
|
|
h.SetTitle("Configure " + state.String())
|
|
})
|
|
|
|
d, _ := gts.NewEmptyModalDialog()
|
|
d.SetDefaultSize(400, 300)
|
|
d.Add(b)
|
|
d.SetTitlebar(h)
|
|
|
|
// Bind the title.
|
|
state.BindNamer(d, "response", c)
|
|
// Bind the updater.
|
|
d.Connect("response", func(*gtk.Dialog) { apply(true) })
|
|
|
|
d.Show()
|
|
}
|