-
Notifications
You must be signed in to change notification settings - Fork 24
/
flex.go
142 lines (122 loc) · 3.22 KB
/
flex.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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
// Copyright (c) 2019, The Emergent Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package params
import (
"bytes"
"encoding/json"
"io"
"io/ioutil"
"log"
"github.com/goki/gi/gi"
)
// FlexVal is a specific flexible value for the Flex parameter map
// that implements the StylerObj interface for CSS-style selection logic
type FlexVal struct {
Nm string `desc:"name of this specific object -- matches #Name selections"`
Type string `desc:"type name of this object -- matches plain TypeName selections"`
Cls string `desc:"space-separated list of class name(s) -- match the .Class selections"`
Obj interface{} `desc:"actual object with data that is set by the parameters"`
}
func (fv *FlexVal) TypeName() string {
return fv.Type
}
func (fv *FlexVal) Class() string {
return fv.Cls
}
func (fv *FlexVal) Name() string {
return fv.Nm
}
func (fv *FlexVal) Object() interface{} {
return fv.Obj
}
func (fv *FlexVal) CopyFrom(cp *FlexVal) {
fv.Nm = cp.Nm // these should be the same, but copy anyway
fv.Type = cp.Type
fv.Cls = cp.Cls
if hyp, ok := fv.Obj.(Hypers); ok { // this is the main use-case
if cph, ok := cp.Obj.(Hypers); ok {
hyp.CopyFrom(cph)
}
}
}
// Flex supports arbitrary named parameter values that can be set
// by a Set of parameters, as a map of interface{} objects.
// First initialize the map with set of names and a type to create
// blank values, then apply the Set to it.
type Flex map[string]*FlexVal
// Make makes the map if it is nil (otherwise does nothing)
func (fl *Flex) Make() {
if *fl != nil {
return
}
*fl = make(Flex)
}
func (fl *Flex) TypeName() string { // note: assuming all same type for this purpose
for _, fv := range *fl {
return fv.TypeName()
}
return "Flex"
}
func (fl *Flex) Class() string {
return ""
}
func (fl *Flex) Name() string {
return ""
}
// Init initializes the Flex map with given set of flex values.
func (fl *Flex) Init(vals []FlexVal) {
*fl = make(Flex, len(vals))
for _, vl := range vals {
inst := vl
(*fl)[vl.Nm] = &inst
}
}
// ApplySheet applies given sheet of parameters to each element in Flex
func (fl *Flex) ApplySheet(sheet *Sheet, setMsg bool) {
for _, vl := range *fl {
sheet.Apply(vl, setMsg)
}
}
// CopyFrom copies hyper vals from source
func (fl *Flex) CopyFrom(cp Flex) {
fl.Make()
for nm, fv := range cp {
if sfv, has := (*fl)[nm]; has {
sfv.CopyFrom(fv)
} else {
sfv := &FlexVal{}
sfv.CopyFrom(fv)
(*fl)[nm] = sfv
}
}
}
// WriteJSON saves hypers to a JSON-formatted file.
func (fl *Flex) WriteJSON(w io.Writer) error {
b, err := json.MarshalIndent(fl, "", " ")
if err != nil {
log.Println(err) // unlikely
return err
}
w.Write(b)
return err
}
// JSONString returns a string representation of Flex params
func (fl *Flex) JSONString() string {
var buf bytes.Buffer
fl.WriteJSON(&buf)
return string(buf.Bytes())
}
// SaveJSON saves hypers to a JSON-formatted file.
func (fl *Flex) SaveJSON(filename gi.FileName) error {
b, err := json.MarshalIndent(fl, "", " ")
if err != nil {
log.Println(err) // unlikely
return err
}
err = ioutil.WriteFile(string(filename), b, 0644)
if err != nil {
log.Println(err)
}
return err
}