-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathcolorPicker.go
197 lines (169 loc) · 5.58 KB
/
colorPicker.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
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
package rui
import (
"strings"
)
// Constants for [ColorPicker] specific properties and events.
const (
// ColorChangedEvent is the constant for "color-changed" property tag.
//
// Used by `ColorPicker`.
// Event generated when color picker value has been changed.
//
// General listener format:
// func(picker rui.ColorPicker, newColor, oldColor rui.Color)
//
// where:
// - picker - Interface of a color picker which generated this event,
// - newColor - New color value,
// - oldColor - Old color value.
//
// Allowed listener formats:
// func(picker rui.ColorPicker, newColor rui.Color)
// func(newColor, oldColor rui.Color)
// func(newColor rui.Color)
// func(picker rui.ColorPicker)
// func()
ColorChangedEvent PropertyName = "color-changed"
// ColorPickerValue is the constant for "color-picker-value" property tag.
//
// Used by `ColorPicker`.
// Define current color picker value.
//
// Supported types: `Color`, `string`.
//
// Internal type is `Color`, other types converted to it during assignment.
// See `Color` description for more details.
ColorPickerValue PropertyName = "color-picker-value"
)
// ColorPicker represent a ColorPicker view
type ColorPicker interface {
View
}
type colorPickerData struct {
viewData
}
// NewColorPicker create new ColorPicker object and return it
func NewColorPicker(session Session, params Params) ColorPicker {
view := new(colorPickerData)
view.init(session)
setInitParams(view, params)
return view
}
func newColorPicker(session Session) View {
return new(colorPickerData)
}
func (picker *colorPickerData) init(session Session) {
picker.viewData.init(session)
picker.tag = "ColorPicker"
picker.hasHtmlDisabled = true
picker.properties[Padding] = Px(0)
picker.normalize = normalizeColorPickerTag
picker.set = picker.setFunc
picker.changed = picker.propertyChanged
}
func normalizeColorPickerTag(tag PropertyName) PropertyName {
tag = defaultNormalize(tag)
switch tag {
case Value, ColorTag:
return ColorPickerValue
}
return normalizeDataListTag(tag)
}
func (picker *colorPickerData) setFunc(tag PropertyName, value any) []PropertyName {
switch tag {
case ColorChangedEvent:
return setTwoArgEventListener[ColorPicker, Color](picker, tag, value)
case ColorPickerValue:
oldColor := GetColorPickerValue(picker)
result := setColorProperty(picker, ColorPickerValue, value)
if result != nil {
picker.setRaw("old-color", oldColor)
}
return result
case DataList:
return setDataList(picker, value, "")
}
return picker.viewData.setFunc(tag, value)
}
func (picker *colorPickerData) propertyChanged(tag PropertyName) {
switch tag {
case ColorPickerValue:
color := GetColorPickerValue(picker)
picker.Session().callFunc("setInputValue", picker.htmlID(), color.rgbString())
if listeners := GetColorChangedListeners(picker); len(listeners) > 0 {
oldColor := Color(0)
if value := picker.getRaw("old-color"); value != nil {
oldColor = value.(Color)
}
for _, listener := range listeners {
listener(picker, color, oldColor)
}
}
default:
picker.viewData.propertyChanged(tag)
}
}
func (picker *colorPickerData) htmlTag() string {
return "input"
}
func (picker *colorPickerData) htmlSubviews(self View, buffer *strings.Builder) {
dataListHtmlSubviews(self, buffer, func(text string, session Session) string {
text, _ = session.resolveConstants(text)
return text
})
}
func (picker *colorPickerData) htmlProperties(self View, buffer *strings.Builder) {
picker.viewData.htmlProperties(self, buffer)
buffer.WriteString(` type="color" value="`)
buffer.WriteString(GetColorPickerValue(picker).rgbString())
buffer.WriteByte('"')
buffer.WriteString(` oninput="editViewInputEvent(this)"`)
if picker.getRaw(ClickEvent) == nil {
buffer.WriteString(` onclick="stopEventPropagation(this, event)"`)
}
dataListHtmlProperties(picker, buffer)
}
func (picker *colorPickerData) handleCommand(self View, command PropertyName, data DataObject) bool {
switch command {
case "textChanged":
if text, ok := data.PropertyValue("text"); ok {
if color, ok := StringToColor(text); ok {
oldColor := GetColorPickerValue(picker)
picker.properties[ColorPickerValue] = color
if color != oldColor {
for _, listener := range GetColorChangedListeners(picker) {
listener(picker, color, oldColor)
}
if listener, ok := picker.changeListener[ColorPickerValue]; ok {
listener(picker, ColorPickerValue)
}
}
}
}
return true
}
return picker.viewData.handleCommand(self, command, data)
}
// GetColorPickerValue returns the value of ColorPicker subview.
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is returned.
func GetColorPickerValue(view View, subviewID ...string) Color {
if view = getSubview(view, subviewID); view != nil {
if value, ok := colorProperty(view, ColorPickerValue, view.Session()); ok {
return value
}
for _, tag := range []PropertyName{ColorPickerValue, Value, ColorTag} {
if value := valueFromStyle(view, tag); value != nil {
if result, ok := valueToColor(value, view.Session()); ok {
return result
}
}
}
}
return 0
}
// GetColorChangedListeners returns the ColorChangedListener list of an ColorPicker subview.
// If there are no listeners then the empty list is returned
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is returned.
func GetColorChangedListeners(view View, subviewID ...string) []func(ColorPicker, Color, Color) {
return getTwoArgEventListeners[ColorPicker, Color](view, subviewID, ColorChangedEvent)
}