rui_orig/colorPicker.go

260 lines
6.4 KiB
Go

package rui
import (
"fmt"
"strings"
)
const (
ColorChangedEvent = "color-changed"
ColorPickerValue = "color-picker-value"
)
// ColorPicker - ColorPicker view
type ColorPicker interface {
View
}
type colorPickerData struct {
viewData
colorChangedListeners []func(ColorPicker, Color)
}
// 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 NewColorPicker(session, nil)
}
func (picker *colorPickerData) Init(session Session) {
picker.viewData.Init(session)
picker.tag = "ColorPicker"
picker.colorChangedListeners = []func(ColorPicker, Color){}
picker.properties[Padding] = Px(0)
}
func (picker *colorPickerData) normalizeTag(tag string) string {
tag = strings.ToLower(tag)
switch tag {
case Value, ColorTag:
return ColorPickerValue
}
return tag
}
func (picker *colorPickerData) Remove(tag string) {
picker.remove(picker.normalizeTag(tag))
}
func (picker *colorPickerData) remove(tag string) {
switch tag {
case ColorChangedEvent:
if len(picker.colorChangedListeners) > 0 {
picker.colorChangedListeners = []func(ColorPicker, Color){}
picker.propertyChangedEvent(tag)
}
case ColorPickerValue:
oldColor := GetColorPickerValue(picker, "")
delete(picker.properties, ColorPickerValue)
picker.colorChanged(oldColor)
default:
picker.viewData.remove(tag)
}
}
func (picker *colorPickerData) Set(tag string, value interface{}) bool {
return picker.set(picker.normalizeTag(tag), value)
}
func (picker *colorPickerData) set(tag string, value interface{}) bool {
if value == nil {
picker.remove(tag)
return true
}
switch tag {
case ColorChangedEvent:
switch value := value.(type) {
case func(ColorPicker, Color):
picker.colorChangedListeners = []func(ColorPicker, Color){value}
case func(Color):
fn := func(view ColorPicker, date Color) {
value(date)
}
picker.colorChangedListeners = []func(ColorPicker, Color){fn}
case []func(ColorPicker, Color):
picker.colorChangedListeners = value
case []func(Color):
listeners := make([]func(ColorPicker, Color), len(value))
for i, val := range value {
if val == nil {
notCompatibleType(tag, val)
return false
}
listeners[i] = func(view ColorPicker, date Color) {
val(date)
}
}
picker.colorChangedListeners = listeners
case []interface{}:
listeners := make([]func(ColorPicker, Color), len(value))
for i, val := range value {
if val == nil {
notCompatibleType(tag, val)
return false
}
switch val := val.(type) {
case func(ColorPicker, Color):
listeners[i] = val
case func(Color):
listeners[i] = func(view ColorPicker, date Color) {
val(date)
}
default:
notCompatibleType(tag, val)
return false
}
}
picker.colorChangedListeners = listeners
}
picker.propertyChangedEvent(tag)
return true
case ColorPickerValue:
oldColor := GetColorPickerValue(picker, "")
if picker.setColorProperty(ColorPickerValue, value) {
picker.colorChanged(oldColor)
return true
}
default:
return picker.viewData.set(tag, value)
}
return false
}
func (picker *colorPickerData) colorChanged(oldColor Color) {
if newColor := GetColorPickerValue(picker, ""); oldColor != newColor {
if picker.created {
picker.session.runScript(fmt.Sprintf(`setInputValue('%s', '%s')`, picker.htmlID(), newColor.rgbString()))
}
for _, listener := range picker.colorChangedListeners {
listener(picker, newColor)
}
picker.propertyChangedEvent(ColorTag)
}
}
func (picker *colorPickerData) Get(tag string) interface{} {
return picker.get(picker.normalizeTag(tag))
}
func (picker *colorPickerData) get(tag string) interface{} {
switch tag {
case ColorChangedEvent:
return picker.colorChangedListeners
default:
return picker.viewData.get(tag)
}
}
func (picker *colorPickerData) htmlTag() string {
return "input"
}
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)"`)
}
}
func (picker *colorPickerData) htmlDisabledProperties(self View, buffer *strings.Builder) {
if IsDisabled(self, "") {
buffer.WriteString(` disabled`)
}
picker.viewData.htmlDisabledProperties(self, buffer)
}
func (picker *colorPickerData) handleCommand(self View, command string, data DataObject) bool {
switch command {
case "textChanged":
if text, ok := data.PropertyValue("text"); ok {
oldColor := GetColorPickerValue(picker, "")
if color, ok := StringToColor(text); ok {
picker.properties[ColorPickerValue] = color
if color != oldColor {
for _, listener := range picker.colorChangedListeners {
listener(picker, color)
}
}
}
}
return true
}
return picker.viewData.handleCommand(self, command, data)
}
// GetColorPickerValue returns the value of ColorPicker subview.
// If the second argument (subviewID) is "" then a value from the first argument (view) is returned.
func GetColorPickerValue(view View, subviewID string) Color {
if subviewID != "" {
view = ViewByID(view, subviewID)
}
if view != nil {
if result, ok := colorStyledProperty(view, ColorPickerValue); ok {
return result
}
for _, tag := range []string{Value, ColorTag} {
if value, ok := valueFromStyle(view, tag); ok {
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 "" then a value from the first argument (view) is returned.
func GetColorChangedListeners(view View, subviewID string) []func(ColorPicker, Color) {
if subviewID != "" {
view = ViewByID(view, subviewID)
}
if view != nil {
if value := view.Get(ColorChangedEvent); value != nil {
if listeners, ok := value.([]func(ColorPicker, Color)); ok {
return listeners
}
}
}
return []func(ColorPicker, Color){}
}