mirror of https://github.com/anoshenko/rui.git
OriginX, OriginY, and OriginZ properties renamed to TransformOriginX, TransformOriginY, and TransformOriginZ. GetOrigin function renamed to GetTransformOrigin
This commit is contained in:
parent
e2775d52f2
commit
0f2e7e55ea
|
@ -1,4 +1,7 @@
|
|||
# v0.18.0
|
||||
|
||||
* OriginX, OriginY, and OriginZ properties renamed to TransformOriginX, TransformOriginY, and TransformOriginZ
|
||||
* GetOrigin function renamed to GetTransformOrigin
|
||||
* Added LineJoin type. Type of constants MiterJoin, RoundJoin, and BevelJoin changed to LineJoin. Type of Canvas.SetLineJoin function argument changed to LineJoin.
|
||||
* Added LineCap type. Type of constants ButtCap, RoundCap, and SquareCap changed to LineCap. Type of Canvas.SetLineCap function argument changed to LineCap.
|
||||
|
||||
|
|
|
@ -157,7 +157,7 @@ const (
|
|||
|
||||
/*
|
||||
func setTransitionListener(properties Properties, tag PropertyName, value any) bool {
|
||||
if listeners, ok := valueToEventListeners[View, string](value); ok {
|
||||
if listeners, ok := valueToOneArgEventListeners[View, string](value); ok {
|
||||
if len(listeners) == 0 {
|
||||
properties.setRaw(tag, nil)
|
||||
} else {
|
||||
|
@ -206,7 +206,7 @@ func (view *viewData) handleTransitionEvents(tag PropertyName, data DataObject)
|
|||
}
|
||||
}
|
||||
|
||||
for _, listener := range getEventListeners[View, PropertyName](view, nil, tag) {
|
||||
for _, listener := range getOneArgEventListeners[View, PropertyName](view, nil, tag) {
|
||||
listener(view, property)
|
||||
}
|
||||
}
|
||||
|
@ -214,7 +214,7 @@ func (view *viewData) handleTransitionEvents(tag PropertyName, data DataObject)
|
|||
|
||||
/*
|
||||
func setAnimationListener(properties Properties, tag PropertyName, value any) bool {
|
||||
if listeners, ok := valueToEventListeners[View, string](value); ok {
|
||||
if listeners, ok := valueToOneArgEventListeners[View, string](value); ok {
|
||||
if len(listeners) == 0 {
|
||||
properties.setRaw(tag, nil)
|
||||
} else {
|
||||
|
@ -252,7 +252,7 @@ func animationEventsHtml(view View, buffer *strings.Builder) {
|
|||
*/
|
||||
|
||||
func (view *viewData) handleAnimationEvents(tag PropertyName, data DataObject) {
|
||||
if listeners := getEventListeners[View, string](view, nil, tag); len(listeners) > 0 {
|
||||
if listeners := getOneArgEventListeners[View, string](view, nil, tag); len(listeners) > 0 {
|
||||
id := ""
|
||||
if name, ok := data.PropertyValue("name"); ok {
|
||||
for _, animation := range GetAnimation(view) {
|
||||
|
@ -271,54 +271,54 @@ func (view *viewData) handleAnimationEvents(tag PropertyName, data DataObject) {
|
|||
// 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 GetTransitionRunListeners(view View, subviewID ...string) []func(View, string) {
|
||||
return getEventListeners[View, string](view, subviewID, TransitionRunEvent)
|
||||
return getOneArgEventListeners[View, string](view, subviewID, TransitionRunEvent)
|
||||
}
|
||||
|
||||
// GetTransitionStartListeners returns the "transition-start-event" listener list.
|
||||
// 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 GetTransitionStartListeners(view View, subviewID ...string) []func(View, string) {
|
||||
return getEventListeners[View, string](view, subviewID, TransitionStartEvent)
|
||||
return getOneArgEventListeners[View, string](view, subviewID, TransitionStartEvent)
|
||||
}
|
||||
|
||||
// GetTransitionEndListeners returns the "transition-end-event" listener list.
|
||||
// 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 GetTransitionEndListeners(view View, subviewID ...string) []func(View, string) {
|
||||
return getEventListeners[View, string](view, subviewID, TransitionEndEvent)
|
||||
return getOneArgEventListeners[View, string](view, subviewID, TransitionEndEvent)
|
||||
}
|
||||
|
||||
// GetTransitionCancelListeners returns the "transition-cancel-event" listener list.
|
||||
// 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 GetTransitionCancelListeners(view View, subviewID ...string) []func(View, string) {
|
||||
return getEventListeners[View, string](view, subviewID, TransitionCancelEvent)
|
||||
return getOneArgEventListeners[View, string](view, subviewID, TransitionCancelEvent)
|
||||
}
|
||||
|
||||
// GetAnimationStartListeners returns the "animation-start-event" listener list.
|
||||
// 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 GetAnimationStartListeners(view View, subviewID ...string) []func(View, string) {
|
||||
return getEventListeners[View, string](view, subviewID, AnimationStartEvent)
|
||||
return getOneArgEventListeners[View, string](view, subviewID, AnimationStartEvent)
|
||||
}
|
||||
|
||||
// GetAnimationEndListeners returns the "animation-end-event" listener list.
|
||||
// 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 GetAnimationEndListeners(view View, subviewID ...string) []func(View, string) {
|
||||
return getEventListeners[View, string](view, subviewID, AnimationEndEvent)
|
||||
return getOneArgEventListeners[View, string](view, subviewID, AnimationEndEvent)
|
||||
}
|
||||
|
||||
// GetAnimationCancelListeners returns the "animation-cancel-event" listener list.
|
||||
// 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 GetAnimationCancelListeners(view View, subviewID ...string) []func(View, string) {
|
||||
return getEventListeners[View, string](view, subviewID, AnimationCancelEvent)
|
||||
return getOneArgEventListeners[View, string](view, subviewID, AnimationCancelEvent)
|
||||
}
|
||||
|
||||
// GetAnimationIterationListeners returns the "animation-iteration-event" listener list.
|
||||
// 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 GetAnimationIterationListeners(view View, subviewID ...string) []func(View, string) {
|
||||
return getEventListeners[View, string](view, subviewID, AnimationIterationEvent)
|
||||
return getOneArgEventListeners[View, string](view, subviewID, AnimationIterationEvent)
|
||||
}
|
||||
|
|
|
@ -623,21 +623,10 @@ function listItemClickEvent(element, event) {
|
|||
return
|
||||
}
|
||||
|
||||
let selected = false;
|
||||
if (element.classList) {
|
||||
const focusStyle = getListFocusedItemStyle(element);
|
||||
const blurStyle = getListSelectedItemStyle(element);
|
||||
selected = (element.classList.contains(focusStyle) || element.classList.contains(blurStyle));
|
||||
}
|
||||
|
||||
const list = element.parentNode.parentNode
|
||||
if (list) {
|
||||
if (!selected) {
|
||||
selectListItem(list, element, true)
|
||||
}
|
||||
|
||||
const message = "itemClick{session=" + sessionID + ",id=" + list.id + "}"
|
||||
sendMessage(message);
|
||||
const number = getListItemNumber(element.id)
|
||||
sendMessage("itemClick{session=" + sessionID + ",id=" + list.id + ",number=" + number + "}");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -664,7 +653,7 @@ function getListSelectedItemStyle(element) {
|
|||
return getStyleAttribute(element, "data-bluritemstyle", "ruiListItemSelected");
|
||||
}
|
||||
|
||||
function selectListItem(element, item, needSendMessage) {
|
||||
function selectListItem(element, item) {
|
||||
const currentId = element.getAttribute("data-current");
|
||||
let message;
|
||||
const focusStyle = getListFocusedItemStyle(element);
|
||||
|
@ -676,9 +665,7 @@ function selectListItem(element, item, needSendMessage) {
|
|||
if (current.classList) {
|
||||
current.classList.remove(focusStyle, blurStyle);
|
||||
}
|
||||
if (sendMessage) {
|
||||
message = "itemUnselected{session=" + sessionID + ",id=" + element.id + "}";
|
||||
}
|
||||
message = "itemUnselected{session=" + sessionID + ",id=" + element.id + "}";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -694,41 +681,20 @@ function selectListItem(element, item, needSendMessage) {
|
|||
}
|
||||
|
||||
element.setAttribute("data-current", item.id);
|
||||
if (sendMessage) {
|
||||
const number = getListItemNumber(item.id)
|
||||
if (number != undefined) {
|
||||
message = "itemSelected{session=" + sessionID + ",id=" + element.id + ",number=" + number + "}";
|
||||
}
|
||||
const number = getListItemNumber(item.id)
|
||||
if (number != undefined) {
|
||||
message = "itemSelected{session=" + sessionID + ",id=" + element.id + ",number=" + number + "}";
|
||||
}
|
||||
|
||||
|
||||
if (item.scrollIntoViewIfNeeded) {
|
||||
item.scrollIntoViewIfNeeded()
|
||||
} else {
|
||||
item.scrollIntoView({block: "nearest", inline: "nearest"});
|
||||
}
|
||||
/*
|
||||
let left = item.offsetLeft - element.offsetLeft;
|
||||
if (left < element.scrollLeft) {
|
||||
element.scrollLeft = left;
|
||||
}
|
||||
|
||||
let top = item.offsetTop - element.offsetTop;
|
||||
if (top < element.scrollTop) {
|
||||
element.scrollTop = top;
|
||||
}
|
||||
|
||||
let right = left + item.offsetWidth;
|
||||
if (right > element.scrollLeft + element.clientWidth) {
|
||||
element.scrollLeft = right - element.clientWidth;
|
||||
}
|
||||
|
||||
let bottom = top + item.offsetHeight
|
||||
if (bottom > element.scrollTop + element.clientHeight) {
|
||||
element.scrollTop = bottom - element.clientHeight;
|
||||
}*/
|
||||
}
|
||||
|
||||
if (needSendMessage && message != undefined) {
|
||||
if (message != undefined) {
|
||||
sendMessage(message);
|
||||
}
|
||||
scanElementsSize();
|
||||
|
@ -857,7 +823,7 @@ function listViewKeyDownEvent(element, event) {
|
|||
switch (key) {
|
||||
case " ":
|
||||
case "Enter":
|
||||
const message = "itemClick{session=" + sessionID + ",id=" + element.id + "}";
|
||||
const message = "itemClick{session=" + sessionID + ",id=" + element.id + ",number=" + getListItemNumber(currentId) + "}";
|
||||
sendMessage(message);
|
||||
break;
|
||||
|
||||
|
@ -897,7 +863,7 @@ function listViewKeyDownEvent(element, event) {
|
|||
return;
|
||||
}
|
||||
if (item && item !== current) {
|
||||
selectListItem(element, item, true);
|
||||
selectListItem(element, item);
|
||||
}
|
||||
} else {
|
||||
switch (key) {
|
||||
|
@ -916,7 +882,7 @@ function listViewKeyDownEvent(element, event) {
|
|||
if (item.getAttribute("data-disabled") == "1") {
|
||||
continue;
|
||||
}
|
||||
selectListItem(element, item, true);
|
||||
selectListItem(element, item);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -37,8 +37,8 @@ func (canvasView *canvasViewData) init(session Session) {
|
|||
canvasView.viewData.init(session)
|
||||
canvasView.tag = "CanvasView"
|
||||
canvasView.normalize = normalizeCanvasViewTag
|
||||
canvasView.set = canvasViewSet
|
||||
canvasView.remove = canvasViewRemove
|
||||
canvasView.set = canvasView.setFunc
|
||||
canvasView.remove = canvasView.removeFunc
|
||||
|
||||
}
|
||||
|
||||
|
@ -51,36 +51,32 @@ func normalizeCanvasViewTag(tag PropertyName) PropertyName {
|
|||
return tag
|
||||
}
|
||||
|
||||
func canvasViewRemove(view View, tag PropertyName) []PropertyName {
|
||||
func (canvasView *canvasViewData) removeFunc(tag PropertyName) []PropertyName {
|
||||
if tag == DrawFunction {
|
||||
if view.getRaw(DrawFunction) != nil {
|
||||
view.setRaw(DrawFunction, nil)
|
||||
if canvasView, ok := view.(CanvasView); ok {
|
||||
canvasView.Redraw()
|
||||
}
|
||||
if canvasView.getRaw(DrawFunction) != nil {
|
||||
canvasView.setRaw(DrawFunction, nil)
|
||||
canvasView.Redraw()
|
||||
return []PropertyName{DrawFunction}
|
||||
}
|
||||
return []PropertyName{}
|
||||
}
|
||||
|
||||
return viewRemove(view, tag)
|
||||
return canvasView.viewData.removeFunc(tag)
|
||||
}
|
||||
|
||||
func canvasViewSet(view View, tag PropertyName, value any) []PropertyName {
|
||||
func (canvasView *canvasViewData) setFunc(tag PropertyName, value any) []PropertyName {
|
||||
if tag == DrawFunction {
|
||||
if fn, ok := value.(func(Canvas)); ok {
|
||||
view.setRaw(DrawFunction, fn)
|
||||
canvasView.setRaw(DrawFunction, fn)
|
||||
} else {
|
||||
notCompatibleType(tag, value)
|
||||
return nil
|
||||
}
|
||||
if canvasView, ok := view.(CanvasView); ok {
|
||||
canvasView.Redraw()
|
||||
}
|
||||
canvasView.Redraw()
|
||||
return []PropertyName{DrawFunction}
|
||||
}
|
||||
|
||||
return viewSet(view, tag, value)
|
||||
return canvasView.viewData.setFunc(tag, value)
|
||||
}
|
||||
|
||||
func (canvasView *canvasViewData) htmlTag() string {
|
||||
|
|
87
checkbox.go
87
checkbox.go
|
@ -49,117 +49,98 @@ func (button *checkboxData) init(session Session) {
|
|||
button.systemClass = "ruiGridLayout ruiCheckbox"
|
||||
button.set = button.setFunc
|
||||
button.remove = button.removeFunc
|
||||
button.changed = checkboxPropertyChanged
|
||||
button.changed = button.propertyChanged
|
||||
|
||||
button.setRaw(ClickEvent, checkboxClickListener)
|
||||
button.setRaw(KeyDownEvent, checkboxKeyListener)
|
||||
button.setRaw(ClickEvent, []func(View, MouseEvent){checkboxClickListener})
|
||||
button.setRaw(KeyDownEvent, []func(View, KeyEvent){checkboxKeyListener})
|
||||
}
|
||||
|
||||
func (button *checkboxData) Focusable() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func checkboxPropertyChanged(view View, tag PropertyName) {
|
||||
func (button *checkboxData) propertyChanged(tag PropertyName) {
|
||||
switch tag {
|
||||
|
||||
case Checked:
|
||||
session := view.Session()
|
||||
checked := IsCheckboxChecked(view)
|
||||
if listeners := GetCheckboxChangedListeners(view); len(listeners) > 0 {
|
||||
if checkbox, ok := view.(Checkbox); ok {
|
||||
for _, listener := range listeners {
|
||||
listener(checkbox, checked)
|
||||
}
|
||||
session := button.Session()
|
||||
checked := IsCheckboxChecked(button)
|
||||
if listeners := GetCheckboxChangedListeners(button); len(listeners) > 0 {
|
||||
for _, listener := range listeners {
|
||||
listener(button, checked)
|
||||
}
|
||||
}
|
||||
|
||||
buffer := allocStringBuilder()
|
||||
defer freeStringBuilder(buffer)
|
||||
|
||||
checkboxHtml(view, buffer, checked)
|
||||
session.updateInnerHTML(view.htmlID()+"checkbox", buffer.String())
|
||||
checkboxHtml(button, buffer, checked)
|
||||
session.updateInnerHTML(button.htmlID()+"checkbox", buffer.String())
|
||||
|
||||
case CheckboxHorizontalAlign, CheckboxVerticalAlign:
|
||||
htmlID := view.htmlID()
|
||||
session := view.Session()
|
||||
htmlID := button.htmlID()
|
||||
session := button.Session()
|
||||
updateCSSStyle(htmlID, session)
|
||||
updateInnerHTML(htmlID, session)
|
||||
|
||||
case VerticalAlign:
|
||||
view.Session().updateCSSProperty(view.htmlID()+"content", "align-items", checkboxVerticalAlignCSS(view))
|
||||
button.Session().updateCSSProperty(button.htmlID()+"content", "align-items", checkboxVerticalAlignCSS(button))
|
||||
|
||||
case HorizontalAlign:
|
||||
view.Session().updateCSSProperty(view.htmlID()+"content", "justify-items", checkboxHorizontalAlignCSS(view))
|
||||
button.Session().updateCSSProperty(button.htmlID()+"content", "justify-items", checkboxHorizontalAlignCSS(button))
|
||||
|
||||
case AccentColor:
|
||||
updateInnerHTML(view.htmlID(), view.Session())
|
||||
updateInnerHTML(button.htmlID(), button.Session())
|
||||
|
||||
default:
|
||||
viewsContainerPropertyChanged(view, tag)
|
||||
button.viewsContainerData.propertyChanged(tag)
|
||||
}
|
||||
}
|
||||
|
||||
func (button *checkboxData) setFunc(view View, tag PropertyName, value any) []PropertyName {
|
||||
func (button *checkboxData) setFunc(tag PropertyName, value any) []PropertyName {
|
||||
switch tag {
|
||||
case ClickEvent:
|
||||
if button.viewsContainerData.setFunc(view, ClickEvent, value) != nil {
|
||||
if value := view.getRaw(ClickEvent); value != nil {
|
||||
if listeners, ok := value.([]func(View, MouseEvent)); ok {
|
||||
listeners = append(listeners, checkboxClickListener)
|
||||
view.setRaw(ClickEvent, listeners)
|
||||
return []PropertyName{ClickEvent}
|
||||
}
|
||||
}
|
||||
|
||||
return button.viewsContainerData.setFunc(view, ClickEvent, checkboxClickListener)
|
||||
if listeners, ok := valueToOneArgEventListeners[View, MouseEvent](value); ok && listeners != nil {
|
||||
listeners = append(listeners, checkboxClickListener)
|
||||
button.setRaw(tag, listeners)
|
||||
return []PropertyName{tag}
|
||||
}
|
||||
return nil
|
||||
|
||||
case KeyDownEvent:
|
||||
if button.viewsContainerData.setFunc(view, KeyDownEvent, value) != nil {
|
||||
if value := view.getRaw(KeyDownEvent); value != nil {
|
||||
if listeners, ok := value.([]func(View, KeyEvent)); ok {
|
||||
listeners = append(listeners, checkboxKeyListener)
|
||||
view.setRaw(KeyDownEvent, listeners)
|
||||
return []PropertyName{KeyDownEvent}
|
||||
}
|
||||
}
|
||||
|
||||
return button.viewsContainerData.setFunc(view, KeyDownEvent, checkboxKeyListener)
|
||||
if listeners, ok := valueToOneArgEventListeners[View, KeyEvent](value); ok && listeners != nil {
|
||||
listeners = append(listeners, checkboxKeyListener)
|
||||
button.setRaw(tag, listeners)
|
||||
return []PropertyName{tag}
|
||||
}
|
||||
return nil
|
||||
|
||||
case CheckboxChangedEvent:
|
||||
return setViewEventListener[Checkbox, bool](view, tag, value)
|
||||
return setOneArgEventListener[Checkbox, bool](button, tag, value)
|
||||
|
||||
case Checked:
|
||||
return setBoolProperty(view, Checked, value)
|
||||
return setBoolProperty(button, Checked, value)
|
||||
|
||||
case CellVerticalAlign, CellHorizontalAlign, CellWidth, CellHeight:
|
||||
ErrorLogF(`"%s" property is not compatible with the BoundsProperty`, string(tag))
|
||||
return nil
|
||||
}
|
||||
|
||||
return button.viewsContainerData.setFunc(view, tag, value)
|
||||
return button.viewsContainerData.setFunc(tag, value)
|
||||
}
|
||||
|
||||
func (button *checkboxData) removeFunc(view View, tag PropertyName) []PropertyName {
|
||||
func (button *checkboxData) removeFunc(tag PropertyName) []PropertyName {
|
||||
switch tag {
|
||||
case ClickEvent:
|
||||
button.setRaw(ClickEvent, checkboxClickListener)
|
||||
button.setRaw(ClickEvent, []func(View, MouseEvent){checkboxClickListener})
|
||||
return []PropertyName{ClickEvent}
|
||||
|
||||
case KeyDownEvent:
|
||||
button.setRaw(KeyDownEvent, checkboxKeyListener)
|
||||
button.setRaw(KeyDownEvent, []func(View, KeyEvent){checkboxKeyListener})
|
||||
return []PropertyName{ClickEvent}
|
||||
}
|
||||
|
||||
return button.viewsContainerData.removeFunc(view, tag)
|
||||
}
|
||||
|
||||
func (button *checkboxData) checked() bool {
|
||||
checked, _ := boolProperty(button, Checked, button.Session())
|
||||
return checked
|
||||
return button.viewsContainerData.removeFunc(tag)
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -340,5 +321,5 @@ func GetCheckboxHorizontalAlign(view View, subviewID ...string) int {
|
|||
// 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 GetCheckboxChangedListeners(view View, subviewID ...string) []func(Checkbox, bool) {
|
||||
return getEventListeners[Checkbox, bool](view, subviewID, CheckboxChangedEvent)
|
||||
return getOneArgEventListeners[Checkbox, bool](view, subviewID, CheckboxChangedEvent)
|
||||
}
|
||||
|
|
|
@ -66,8 +66,8 @@ func (picker *colorPickerData) init(session Session) {
|
|||
picker.hasHtmlDisabled = true
|
||||
picker.properties[Padding] = Px(0)
|
||||
picker.normalize = normalizeColorPickerTag
|
||||
picker.set = colorPickerSet
|
||||
picker.changed = colorPickerPropertyChanged
|
||||
picker.set = picker.setFunc
|
||||
picker.changed = picker.propertyChanged
|
||||
}
|
||||
|
||||
func normalizeColorPickerTag(tag PropertyName) PropertyName {
|
||||
|
@ -80,44 +80,44 @@ func normalizeColorPickerTag(tag PropertyName) PropertyName {
|
|||
return normalizeDataListTag(tag)
|
||||
}
|
||||
|
||||
func colorPickerSet(view View, tag PropertyName, value any) []PropertyName {
|
||||
func (picker *colorPickerData) setFunc(tag PropertyName, value any) []PropertyName {
|
||||
switch tag {
|
||||
case ColorChangedEvent:
|
||||
return setEventWithOldListener[ColorPicker, Color](view, tag, value)
|
||||
return setTwoArgEventListener[ColorPicker, Color](picker, tag, value)
|
||||
|
||||
case ColorPickerValue:
|
||||
oldColor := GetColorPickerValue(view)
|
||||
result := setColorProperty(view, ColorPickerValue, value)
|
||||
oldColor := GetColorPickerValue(picker)
|
||||
result := setColorProperty(picker, ColorPickerValue, value)
|
||||
if result != nil {
|
||||
view.setRaw("old-color", oldColor)
|
||||
picker.setRaw("old-color", oldColor)
|
||||
}
|
||||
return result
|
||||
|
||||
case DataList:
|
||||
return setDataList(view, value, "")
|
||||
return setDataList(picker, value, "")
|
||||
}
|
||||
|
||||
return viewSet(view, tag, value)
|
||||
return picker.viewData.setFunc(tag, value)
|
||||
}
|
||||
|
||||
func colorPickerPropertyChanged(view View, tag PropertyName) {
|
||||
func (picker *colorPickerData) propertyChanged(tag PropertyName) {
|
||||
switch tag {
|
||||
case ColorPickerValue:
|
||||
color := GetColorPickerValue(view)
|
||||
view.Session().callFunc("setInputValue", view.htmlID(), color.rgbString())
|
||||
color := GetColorPickerValue(picker)
|
||||
picker.Session().callFunc("setInputValue", picker.htmlID(), color.rgbString())
|
||||
|
||||
if listeners := GetColorChangedListeners(view); len(listeners) > 0 {
|
||||
if listeners := GetColorChangedListeners(picker); len(listeners) > 0 {
|
||||
oldColor := Color(0)
|
||||
if value := view.getRaw("old-color"); value != nil {
|
||||
if value := picker.getRaw("old-color"); value != nil {
|
||||
oldColor = value.(Color)
|
||||
}
|
||||
for _, listener := range listeners {
|
||||
listener(view, color, oldColor)
|
||||
listener(picker, color, oldColor)
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
viewPropertyChanged(view, tag)
|
||||
picker.viewData.propertyChanged(tag)
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -196,5 +196,5 @@ func GetColorPickerValue(view View, subviewID ...string) Color {
|
|||
// 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 getEventWithOldListeners[ColorPicker, Color](view, subviewID, ColorChangedEvent)
|
||||
return getTwoArgEventListeners[ColorPicker, Color](view, subviewID, ColorChangedEvent)
|
||||
}
|
||||
|
|
|
@ -141,7 +141,7 @@ func (columnLayout *columnLayoutData) init(session Session) {
|
|||
columnLayout.viewsContainerData.init(session)
|
||||
columnLayout.tag = "ColumnLayout"
|
||||
columnLayout.normalize = normalizeColumnLayoutTag
|
||||
columnLayout.changed = columnLayoutPropertyChanged
|
||||
columnLayout.changed = columnLayout.propertyChanged
|
||||
//columnLayout.systemClass = "ruiColumnLayout"
|
||||
}
|
||||
|
||||
|
@ -154,27 +154,27 @@ func normalizeColumnLayoutTag(tag PropertyName) PropertyName {
|
|||
return tag
|
||||
}
|
||||
|
||||
func columnLayoutPropertyChanged(view View, tag PropertyName) {
|
||||
func (columnLayout *columnLayoutData) propertyChanged(tag PropertyName) {
|
||||
switch tag {
|
||||
case ColumnSeparator:
|
||||
css := ""
|
||||
session := view.Session()
|
||||
if value := view.getRaw(ColumnSeparator); value != nil {
|
||||
session := columnLayout.Session()
|
||||
if value := columnLayout.getRaw(ColumnSeparator); value != nil {
|
||||
separator := value.(ColumnSeparatorProperty)
|
||||
css = separator.cssValue(view.Session())
|
||||
css = separator.cssValue(session)
|
||||
}
|
||||
session.updateCSSProperty(view.htmlID(), "column-rule", css)
|
||||
session.updateCSSProperty(columnLayout.htmlID(), "column-rule", css)
|
||||
|
||||
case ColumnCount:
|
||||
session := view.Session()
|
||||
if count, ok := intProperty(view, tag, session, 0); ok && count > 0 {
|
||||
session.updateCSSProperty(view.htmlID(), string(ColumnCount), strconv.Itoa(count))
|
||||
session := columnLayout.Session()
|
||||
if count := GetColumnCount(columnLayout); count > 0 {
|
||||
session.updateCSSProperty(columnLayout.htmlID(), string(ColumnCount), strconv.Itoa(count))
|
||||
} else {
|
||||
session.updateCSSProperty(view.htmlID(), string(ColumnCount), "auto")
|
||||
session.updateCSSProperty(columnLayout.htmlID(), string(ColumnCount), "auto")
|
||||
}
|
||||
|
||||
default:
|
||||
viewsContainerPropertyChanged(view, tag)
|
||||
columnLayout.viewsContainerData.propertyChanged(tag)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -82,6 +82,7 @@ func NewColumnSeparator(params Params) ColumnSeparatorProperty {
|
|||
func (separator *columnSeparatorProperty) init() {
|
||||
separator.dataProperty.init()
|
||||
separator.normalize = normalizeVolumnSeparatorTag
|
||||
separator.set = columnSeparatorSet
|
||||
separator.supportedProperties = []PropertyName{Style, Width, ColorTag}
|
||||
}
|
||||
|
||||
|
@ -171,3 +172,10 @@ func (separator *columnSeparatorProperty) cssValue(session Session) string {
|
|||
|
||||
return buffer.String()
|
||||
}
|
||||
|
||||
func columnSeparatorSet(properties Properties, tag PropertyName, value any) []PropertyName {
|
||||
if tag == Style {
|
||||
return setEnumProperty(properties, Style, value, enumProperties[BorderStyle].values)
|
||||
}
|
||||
return propertiesSet(properties, tag, value)
|
||||
}
|
||||
|
|
|
@ -120,7 +120,7 @@ func normalizeDataListTag(tag PropertyName) PropertyName {
|
|||
}
|
||||
|
||||
func setDataList(properties Properties, value any, dateTimeFormat string) []PropertyName {
|
||||
if items, ok := anyToStringArray(value, timeFormat); ok {
|
||||
if items, ok := anyToStringArray(value, dateTimeFormat); ok {
|
||||
properties.setRaw(DataList, items)
|
||||
return []PropertyName{DataList}
|
||||
}
|
||||
|
|
|
@ -138,8 +138,8 @@ func (picker *datePickerData) init(session Session) {
|
|||
picker.tag = "DatePicker"
|
||||
picker.hasHtmlDisabled = true
|
||||
picker.normalize = normalizeDatePickerTag
|
||||
picker.set = datePickerSet
|
||||
picker.changed = datePickerPropertyChanged
|
||||
picker.set = picker.setFunc
|
||||
picker.changed = picker.propertyChanged
|
||||
}
|
||||
|
||||
func (picker *datePickerData) Focusable() bool {
|
||||
|
@ -198,22 +198,22 @@ func stringToDate(value string) (time.Time, bool) {
|
|||
return time.Now(), false
|
||||
}
|
||||
|
||||
func datePickerSet(view View, tag PropertyName, value any) []PropertyName {
|
||||
func (picker *datePickerData) setFunc(tag PropertyName, value any) []PropertyName {
|
||||
|
||||
setDateValue := func(tag PropertyName) []PropertyName {
|
||||
switch value := value.(type) {
|
||||
case time.Time:
|
||||
view.setRaw(tag, value)
|
||||
picker.setRaw(tag, value)
|
||||
return []PropertyName{tag}
|
||||
|
||||
case string:
|
||||
if isConstantName(value) {
|
||||
view.setRaw(tag, value)
|
||||
picker.setRaw(tag, value)
|
||||
return []PropertyName{tag}
|
||||
}
|
||||
|
||||
if date, ok := stringToDate(value); ok {
|
||||
view.setRaw(tag, date)
|
||||
picker.setRaw(tag, date)
|
||||
return []PropertyName{tag}
|
||||
}
|
||||
}
|
||||
|
@ -227,67 +227,67 @@ func datePickerSet(view View, tag PropertyName, value any) []PropertyName {
|
|||
return setDateValue(tag)
|
||||
|
||||
case DatePickerStep:
|
||||
return setIntProperty(view, DatePickerStep, value)
|
||||
return setIntProperty(picker, DatePickerStep, value)
|
||||
|
||||
case DatePickerValue:
|
||||
view.setRaw("old-date", GetDatePickerValue(view))
|
||||
picker.setRaw("old-date", GetDatePickerValue(picker))
|
||||
return setDateValue(tag)
|
||||
|
||||
case DateChangedEvent:
|
||||
return setEventWithOldListener[DatePicker, time.Time](view, tag, value)
|
||||
return setTwoArgEventListener[DatePicker, time.Time](picker, tag, value)
|
||||
|
||||
case DataList:
|
||||
return setDataList(view, value, dateFormat)
|
||||
return setDataList(picker, value, dateFormat)
|
||||
}
|
||||
|
||||
return viewSet(view, tag, value)
|
||||
return picker.viewData.setFunc(tag, value)
|
||||
}
|
||||
|
||||
func datePickerPropertyChanged(view View, tag PropertyName) {
|
||||
func (picker *datePickerData) propertyChanged(tag PropertyName) {
|
||||
|
||||
session := view.Session()
|
||||
session := picker.Session()
|
||||
|
||||
switch tag {
|
||||
|
||||
case DatePickerMin:
|
||||
if date, ok := GetDatePickerMin(view); ok {
|
||||
session.updateProperty(view.htmlID(), "min", date.Format(dateFormat))
|
||||
if date, ok := GetDatePickerMin(picker); ok {
|
||||
session.updateProperty(picker.htmlID(), "min", date.Format(dateFormat))
|
||||
} else {
|
||||
session.removeProperty(view.htmlID(), "min")
|
||||
session.removeProperty(picker.htmlID(), "min")
|
||||
}
|
||||
|
||||
case DatePickerMax:
|
||||
if date, ok := GetDatePickerMax(view); ok {
|
||||
session.updateProperty(view.htmlID(), "max", date.Format(dateFormat))
|
||||
if date, ok := GetDatePickerMax(picker); ok {
|
||||
session.updateProperty(picker.htmlID(), "max", date.Format(dateFormat))
|
||||
} else {
|
||||
session.removeProperty(view.htmlID(), "max")
|
||||
session.removeProperty(picker.htmlID(), "max")
|
||||
}
|
||||
|
||||
case DatePickerStep:
|
||||
if step := GetDatePickerStep(view); step > 0 {
|
||||
session.updateProperty(view.htmlID(), "step", strconv.Itoa(step))
|
||||
if step := GetDatePickerStep(picker); step > 0 {
|
||||
session.updateProperty(picker.htmlID(), "step", strconv.Itoa(step))
|
||||
} else {
|
||||
session.removeProperty(view.htmlID(), "step")
|
||||
session.removeProperty(picker.htmlID(), "step")
|
||||
}
|
||||
|
||||
case DatePickerValue:
|
||||
date := GetDatePickerValue(view)
|
||||
session.callFunc("setInputValue", view.htmlID(), date.Format(dateFormat))
|
||||
date := GetDatePickerValue(picker)
|
||||
session.callFunc("setInputValue", picker.htmlID(), date.Format(dateFormat))
|
||||
|
||||
if listeners := GetDateChangedListeners(view); len(listeners) > 0 {
|
||||
if listeners := GetDateChangedListeners(picker); len(listeners) > 0 {
|
||||
oldDate := time.Now()
|
||||
if value := view.getRaw("old-date"); value != nil {
|
||||
if value := picker.getRaw("old-date"); value != nil {
|
||||
if date, ok := value.(time.Time); ok {
|
||||
oldDate = date
|
||||
}
|
||||
}
|
||||
for _, listener := range listeners {
|
||||
listener(view, date, oldDate)
|
||||
listener(picker, date, oldDate)
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
viewPropertyChanged(view, tag)
|
||||
picker.viewData.propertyChanged(tag)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -447,5 +447,5 @@ func GetDatePickerValue(view View, subviewID ...string) time.Time {
|
|||
// 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 GetDateChangedListeners(view View, subviewID ...string) []func(DatePicker, time.Time, time.Time) {
|
||||
return getEventWithOldListeners[DatePicker, time.Time](view, subviewID, DateChangedEvent)
|
||||
return getTwoArgEventListeners[DatePicker, time.Time](view, subviewID, DateChangedEvent)
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ func (detailsView *detailsViewData) init(session Session) {
|
|||
detailsView.viewsContainerData.init(session)
|
||||
detailsView.tag = "DetailsView"
|
||||
detailsView.set = detailsView.setFunc
|
||||
detailsView.changed = detailsViewPropertyChanged
|
||||
detailsView.changed = detailsView.propertyChanged
|
||||
//detailsView.systemClass = "ruiDetailsView"
|
||||
}
|
||||
|
||||
|
@ -69,7 +69,7 @@ func (detailsView *detailsViewData) Views() []View {
|
|||
return views
|
||||
}
|
||||
|
||||
func (detailsView *detailsViewData) setFunc(self View, tag PropertyName, value any) []PropertyName {
|
||||
func (detailsView *detailsViewData) setFunc(tag PropertyName, value any) []PropertyName {
|
||||
switch tag {
|
||||
case Summary:
|
||||
switch value := value.(type) {
|
||||
|
@ -95,26 +95,26 @@ func (detailsView *detailsViewData) setFunc(self View, tag PropertyName, value a
|
|||
return []PropertyName{tag}
|
||||
}
|
||||
|
||||
return detailsView.viewsContainerData.setFunc(detailsView, tag, value)
|
||||
return detailsView.viewsContainerData.setFunc(tag, value)
|
||||
}
|
||||
|
||||
func detailsViewPropertyChanged(view View, tag PropertyName) {
|
||||
func (detailsView *detailsViewData) propertyChanged(tag PropertyName) {
|
||||
switch tag {
|
||||
case Summary:
|
||||
updateInnerHTML(view.htmlID(), view.Session())
|
||||
updateInnerHTML(detailsView.htmlID(), detailsView.Session())
|
||||
|
||||
case Expanded:
|
||||
if IsDetailsExpanded(view) {
|
||||
view.Session().updateProperty(view.htmlID(), "open", "")
|
||||
if IsDetailsExpanded(detailsView) {
|
||||
detailsView.Session().updateProperty(detailsView.htmlID(), "open", "")
|
||||
} else {
|
||||
view.Session().removeProperty(view.htmlID(), "open")
|
||||
detailsView.Session().removeProperty(detailsView.htmlID(), "open")
|
||||
}
|
||||
|
||||
case NotTranslate:
|
||||
updateInnerHTML(view.htmlID(), view.Session())
|
||||
updateInnerHTML(detailsView.htmlID(), detailsView.Session())
|
||||
|
||||
default:
|
||||
viewsContainerPropertyChanged(view, tag)
|
||||
detailsView.viewsContainerData.propertyChanged(tag)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -155,8 +155,8 @@ func (detailsView *detailsViewData) handleCommand(self View, command PropertyNam
|
|||
if command == "details-open" {
|
||||
if n, ok := dataIntProperty(data, "open"); ok {
|
||||
detailsView.properties[Expanded] = (n != 0)
|
||||
if listener, ok := detailsView.changeListener[Current]; ok {
|
||||
listener(detailsView, Current)
|
||||
if listener, ok := detailsView.changeListener[Expanded]; ok {
|
||||
listener(detailsView, Expanded)
|
||||
}
|
||||
}
|
||||
return true
|
||||
|
|
|
@ -46,8 +46,8 @@ func (list *dropDownListData) init(session Session) {
|
|||
list.tag = "DropDownList"
|
||||
list.hasHtmlDisabled = true
|
||||
list.normalize = normalizeDropDownListTag
|
||||
list.set = dropDownListSet
|
||||
list.changed = dropDownListPropertyChanged
|
||||
list.set = list.setFunc
|
||||
list.changed = list.propertyChanged
|
||||
}
|
||||
|
||||
func (list *dropDownListData) Focusable() bool {
|
||||
|
@ -62,59 +62,49 @@ func normalizeDropDownListTag(tag PropertyName) PropertyName {
|
|||
return tag
|
||||
}
|
||||
|
||||
func dropDownListSet(view View, tag PropertyName, value any) []PropertyName {
|
||||
func (list *dropDownListData) setFunc(tag PropertyName, value any) []PropertyName {
|
||||
switch tag {
|
||||
case Items:
|
||||
if items, ok := anyToStringArray(value, ""); ok {
|
||||
return setArrayPropertyValue(view, tag, items)
|
||||
return setArrayPropertyValue(list, tag, items)
|
||||
}
|
||||
notCompatibleType(Items, value)
|
||||
return nil
|
||||
|
||||
case DisabledItems, ItemSeparators:
|
||||
if items, ok := parseIndicesArray(value); ok {
|
||||
return setArrayPropertyValue(view, tag, items)
|
||||
return setArrayPropertyValue(list, tag, items)
|
||||
}
|
||||
notCompatibleType(tag, value)
|
||||
return nil
|
||||
|
||||
case DropDownEvent:
|
||||
return setEventWithOldListener[DropDownList, int](view, tag, value)
|
||||
return setTwoArgEventListener[DropDownList, int](list, tag, value)
|
||||
|
||||
case Current:
|
||||
if view, ok := view.(View); ok {
|
||||
view.setRaw("old-current", GetCurrent(view))
|
||||
}
|
||||
return setIntProperty(view, Current, value)
|
||||
list.setRaw("old-current", GetCurrent(list))
|
||||
return setIntProperty(list, Current, value)
|
||||
}
|
||||
|
||||
return viewSet(view, tag, value)
|
||||
return list.viewData.setFunc(tag, value)
|
||||
}
|
||||
|
||||
func dropDownListPropertyChanged(view View, tag PropertyName) {
|
||||
func (list *dropDownListData) propertyChanged(tag PropertyName) {
|
||||
switch tag {
|
||||
case Items, DisabledItems, ItemSeparators:
|
||||
updateInnerHTML(view.htmlID(), view.Session())
|
||||
updateInnerHTML(list.htmlID(), list.Session())
|
||||
|
||||
case Current:
|
||||
current := GetCurrent(view)
|
||||
view.Session().callFunc("selectDropDownListItem", view.htmlID(), current)
|
||||
current := GetCurrent(list)
|
||||
list.Session().callFunc("selectDropDownListItem", list.htmlID(), current)
|
||||
|
||||
if list, ok := view.(DropDownList); ok {
|
||||
oldCurrent := -1
|
||||
if value := view.getRaw("old-current"); value != nil {
|
||||
if n, ok := value.(int); ok {
|
||||
oldCurrent = n
|
||||
}
|
||||
}
|
||||
|
||||
for _, listener := range GetDropDownListeners(view) {
|
||||
listener(list, current, oldCurrent)
|
||||
}
|
||||
oldCurrent, _ := intProperty(list, "old-current", list.Session(), -1)
|
||||
for _, listener := range GetDropDownListeners(list) {
|
||||
listener(list, current, oldCurrent)
|
||||
}
|
||||
|
||||
default:
|
||||
viewPropertyChanged(view, tag)
|
||||
list.viewData.propertyChanged(tag)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -253,6 +243,9 @@ func (list *dropDownListData) handleCommand(self View, command PropertyName, dat
|
|||
for _, listener := range GetDropDownListeners(list) {
|
||||
listener(list, number, old)
|
||||
}
|
||||
if listener, ok := list.changeListener[Current]; ok {
|
||||
listener(list, Current)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
ErrorLog(err.Error())
|
||||
|
@ -268,7 +261,7 @@ func (list *dropDownListData) handleCommand(self View, command PropertyName, dat
|
|||
// GetDropDownListeners returns the "drop-down-event" listener list. 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 GetDropDownListeners(view View, subviewID ...string) []func(DropDownList, int, int) {
|
||||
return getEventWithOldListeners[DropDownList, int](view, subviewID, DropDownEvent)
|
||||
return getTwoArgEventListeners[DropDownList, int](view, subviewID, DropDownEvent)
|
||||
}
|
||||
|
||||
// GetDropDownItems return the DropDownList items list.
|
||||
|
|
80
editView.go
80
editView.go
|
@ -121,8 +121,8 @@ func (edit *editViewData) init(session Session) {
|
|||
edit.hasHtmlDisabled = true
|
||||
edit.tag = "EditView"
|
||||
edit.normalize = normalizeEditViewTag
|
||||
edit.set = editViewSet
|
||||
edit.changed = editViewPropertyChanged
|
||||
edit.set = edit.setFunc
|
||||
edit.changed = edit.propertyChanged
|
||||
}
|
||||
|
||||
func (edit *editViewData) Focusable() bool {
|
||||
|
@ -148,18 +148,18 @@ func normalizeEditViewTag(tag PropertyName) PropertyName {
|
|||
return normalizeDataListTag(tag)
|
||||
}
|
||||
|
||||
func editViewSet(view View, tag PropertyName, value any) []PropertyName {
|
||||
func (edit *editViewData) setFunc(tag PropertyName, value any) []PropertyName {
|
||||
switch tag {
|
||||
case Text:
|
||||
if text, ok := value.(string); ok {
|
||||
old := ""
|
||||
if val := view.getRaw(Text); val != nil {
|
||||
if val := edit.getRaw(Text); val != nil {
|
||||
if txt, ok := val.(string); ok {
|
||||
old = txt
|
||||
}
|
||||
}
|
||||
view.setRaw("old-text", old)
|
||||
view.setRaw(tag, text)
|
||||
edit.setRaw("old-text", old)
|
||||
edit.setRaw(tag, text)
|
||||
return []PropertyName{tag}
|
||||
}
|
||||
|
||||
|
@ -168,85 +168,83 @@ func editViewSet(view View, tag PropertyName, value any) []PropertyName {
|
|||
|
||||
case Hint:
|
||||
if text, ok := value.(string); ok {
|
||||
return setStringPropertyValue(view, tag, strings.Trim(text, " \t\n"))
|
||||
return setStringPropertyValue(edit, tag, strings.Trim(text, " \t\n"))
|
||||
}
|
||||
notCompatibleType(tag, value)
|
||||
return nil
|
||||
|
||||
case DataList:
|
||||
setDataList(view, value, "")
|
||||
setDataList(edit, value, "")
|
||||
|
||||
case EditTextChangedEvent:
|
||||
return setEventWithOldListener[EditView, string](view, tag, value)
|
||||
return setTwoArgEventListener[EditView, string](edit, tag, value)
|
||||
}
|
||||
|
||||
return viewSet(view, tag, value)
|
||||
return edit.viewData.setFunc(tag, value)
|
||||
}
|
||||
|
||||
func editViewPropertyChanged(view View, tag PropertyName) {
|
||||
session := view.Session()
|
||||
func (edit *editViewData) propertyChanged(tag PropertyName) {
|
||||
session := edit.Session()
|
||||
|
||||
switch tag {
|
||||
case Text:
|
||||
text := GetText(view)
|
||||
session.callFunc("setInputValue", view.htmlID(), text)
|
||||
text := GetText(edit)
|
||||
session.callFunc("setInputValue", edit.htmlID(), text)
|
||||
|
||||
if edit, ok := view.(EditView); ok {
|
||||
old := ""
|
||||
if val := view.getRaw("old-text"); val != nil {
|
||||
if txt, ok := val.(string); ok {
|
||||
old = txt
|
||||
}
|
||||
old := ""
|
||||
if val := edit.getRaw("old-text"); val != nil {
|
||||
if txt, ok := val.(string); ok {
|
||||
old = txt
|
||||
}
|
||||
edit.textChanged(text, old)
|
||||
}
|
||||
edit.textChanged(text, old)
|
||||
|
||||
case Hint:
|
||||
if text := GetHint(view); text != "" {
|
||||
session.updateProperty(view.htmlID(), "placeholder", text)
|
||||
if text := GetHint(edit); text != "" {
|
||||
session.updateProperty(edit.htmlID(), "placeholder", text)
|
||||
} else {
|
||||
session.removeProperty(view.htmlID(), "placeholder")
|
||||
session.removeProperty(edit.htmlID(), "placeholder")
|
||||
}
|
||||
|
||||
case MaxLength:
|
||||
if maxLength := GetMaxLength(view); maxLength > 0 {
|
||||
session.updateProperty(view.htmlID(), "maxlength", strconv.Itoa(maxLength))
|
||||
if maxLength := GetMaxLength(edit); maxLength > 0 {
|
||||
session.updateProperty(edit.htmlID(), "maxlength", strconv.Itoa(maxLength))
|
||||
} else {
|
||||
session.removeProperty(view.htmlID(), "maxlength")
|
||||
session.removeProperty(edit.htmlID(), "maxlength")
|
||||
}
|
||||
|
||||
case ReadOnly:
|
||||
if IsReadOnly(view) {
|
||||
session.updateProperty(view.htmlID(), "readonly", "")
|
||||
if IsReadOnly(edit) {
|
||||
session.updateProperty(edit.htmlID(), "readonly", "")
|
||||
} else {
|
||||
session.removeProperty(view.htmlID(), "readonly")
|
||||
session.removeProperty(edit.htmlID(), "readonly")
|
||||
}
|
||||
|
||||
case Spellcheck:
|
||||
session.updateProperty(view.htmlID(), "spellcheck", IsSpellcheck(view))
|
||||
session.updateProperty(edit.htmlID(), "spellcheck", IsSpellcheck(edit))
|
||||
|
||||
case EditViewPattern:
|
||||
if text := GetEditViewPattern(view); text != "" {
|
||||
session.updateProperty(view.htmlID(), "pattern", text)
|
||||
if text := GetEditViewPattern(edit); text != "" {
|
||||
session.updateProperty(edit.htmlID(), "pattern", text)
|
||||
} else {
|
||||
session.removeProperty(view.htmlID(), "pattern")
|
||||
session.removeProperty(edit.htmlID(), "pattern")
|
||||
}
|
||||
|
||||
case EditViewType:
|
||||
updateInnerHTML(view.parentHTMLID(), session)
|
||||
updateInnerHTML(edit.parentHTMLID(), session)
|
||||
|
||||
case EditWrap:
|
||||
if wrap := IsEditViewWrap(view); wrap {
|
||||
session.updateProperty(view.htmlID(), "wrap", "soft")
|
||||
if wrap := IsEditViewWrap(edit); wrap {
|
||||
session.updateProperty(edit.htmlID(), "wrap", "soft")
|
||||
} else {
|
||||
session.updateProperty(view.htmlID(), "wrap", "off")
|
||||
session.updateProperty(edit.htmlID(), "wrap", "off")
|
||||
}
|
||||
|
||||
case DataList:
|
||||
updateInnerHTML(view.htmlID(), session)
|
||||
updateInnerHTML(edit.htmlID(), session)
|
||||
|
||||
default:
|
||||
viewPropertyChanged(view, tag)
|
||||
edit.viewData.propertyChanged(tag)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -467,7 +465,7 @@ func IsSpellcheck(view View, subviewID ...string) bool {
|
|||
// 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 GetTextChangedListeners(view View, subviewID ...string) []func(EditView, string, string) {
|
||||
return getEventWithOldListeners[EditView, string](view, subviewID, EditTextChangedEvent)
|
||||
return getTwoArgEventListeners[EditView, string](view, subviewID, EditTextChangedEvent)
|
||||
}
|
||||
|
||||
// GetEditViewType returns a value of the Type property of EditView.
|
||||
|
|
26
events.go
26
events.go
|
@ -35,7 +35,7 @@ var eventJsFunc = map[PropertyName]struct{ jsEvent, jsFunc string }{
|
|||
AnimationCancelEvent: {jsEvent: "onanimationcancel", jsFunc: "animationCancelEvent"},
|
||||
}
|
||||
|
||||
func valueToNoParamListeners[V any](value any) ([]func(V), bool) {
|
||||
func valueToNoArgEventListeners[V any](value any) ([]func(V), bool) {
|
||||
if value == nil {
|
||||
return nil, true
|
||||
}
|
||||
|
@ -106,7 +106,7 @@ func valueToNoParamListeners[V any](value any) ([]func(V), bool) {
|
|||
return nil, false
|
||||
}
|
||||
|
||||
func valueToEventListeners[V View, E any](value any) ([]func(V, E), bool) {
|
||||
func valueToOneArgEventListeners[V View, E any](value any) ([]func(V, E), bool) {
|
||||
if value == nil {
|
||||
return nil, true
|
||||
}
|
||||
|
@ -231,7 +231,7 @@ func valueToEventListeners[V View, E any](value any) ([]func(V, E), bool) {
|
|||
return nil, false
|
||||
}
|
||||
|
||||
func valueToEventWithOldListeners[V View, E any](value any) ([]func(V, E, E), bool) {
|
||||
func valueToTwoArgEventListeners[V View, E any](value any) ([]func(V, E, E), bool) {
|
||||
if value == nil {
|
||||
return nil, true
|
||||
}
|
||||
|
@ -410,7 +410,7 @@ func valueToEventWithOldListeners[V View, E any](value any) ([]func(V, E, E), bo
|
|||
return nil, false
|
||||
}
|
||||
|
||||
func getNoParamEventListeners[V View](view View, subviewID []string, tag PropertyName) []func(V) {
|
||||
func getNoArgEventListeners[V View](view View, subviewID []string, tag PropertyName) []func(V) {
|
||||
if len(subviewID) > 0 && subviewID[0] != "" {
|
||||
view = ViewByID(view, subviewID[0])
|
||||
}
|
||||
|
@ -424,7 +424,7 @@ func getNoParamEventListeners[V View](view View, subviewID []string, tag Propert
|
|||
return []func(V){}
|
||||
}
|
||||
|
||||
func getEventListeners[V View, E any](view View, subviewID []string, tag PropertyName) []func(V, E) {
|
||||
func getOneArgEventListeners[V View, E any](view View, subviewID []string, tag PropertyName) []func(V, E) {
|
||||
if len(subviewID) > 0 && subviewID[0] != "" {
|
||||
view = ViewByID(view, subviewID[0])
|
||||
}
|
||||
|
@ -438,7 +438,7 @@ func getEventListeners[V View, E any](view View, subviewID []string, tag Propert
|
|||
return []func(V, E){}
|
||||
}
|
||||
|
||||
func getEventWithOldListeners[V View, E any](view View, subviewID []string, tag PropertyName) []func(V, E, E) {
|
||||
func getTwoArgEventListeners[V View, E any](view View, subviewID []string, tag PropertyName) []func(V, E, E) {
|
||||
if len(subviewID) > 0 && subviewID[0] != "" {
|
||||
view = ViewByID(view, subviewID[0])
|
||||
}
|
||||
|
@ -452,8 +452,8 @@ func getEventWithOldListeners[V View, E any](view View, subviewID []string, tag
|
|||
return []func(V, E, E){}
|
||||
}
|
||||
|
||||
func setNoParamEventListener[V View](properties Properties, tag PropertyName, value any) []PropertyName {
|
||||
if listeners, ok := valueToNoParamListeners[V](value); ok {
|
||||
func setNoArgEventListener[V View](properties Properties, tag PropertyName, value any) []PropertyName {
|
||||
if listeners, ok := valueToNoArgEventListeners[V](value); ok {
|
||||
if len(listeners) > 0 {
|
||||
properties.setRaw(tag, listeners)
|
||||
} else if properties.getRaw(tag) != nil {
|
||||
|
@ -467,8 +467,8 @@ func setNoParamEventListener[V View](properties Properties, tag PropertyName, va
|
|||
return nil
|
||||
}
|
||||
|
||||
func setViewEventListener[V View, T any](properties Properties, tag PropertyName, value any) []PropertyName {
|
||||
if listeners, ok := valueToEventListeners[V, T](value); ok {
|
||||
func setOneArgEventListener[V View, T any](properties Properties, tag PropertyName, value any) []PropertyName {
|
||||
if listeners, ok := valueToOneArgEventListeners[V, T](value); ok {
|
||||
if len(listeners) > 0 {
|
||||
properties.setRaw(tag, listeners)
|
||||
} else if properties.getRaw(tag) != nil {
|
||||
|
@ -482,8 +482,8 @@ func setViewEventListener[V View, T any](properties Properties, tag PropertyName
|
|||
return nil
|
||||
}
|
||||
|
||||
func setEventWithOldListener[V View, T any](properties Properties, tag PropertyName, value any) []PropertyName {
|
||||
listeners, ok := valueToEventWithOldListeners[V, T](value)
|
||||
func setTwoArgEventListener[V View, T any](properties Properties, tag PropertyName, value any) []PropertyName {
|
||||
listeners, ok := valueToTwoArgEventListeners[V, T](value)
|
||||
if !ok {
|
||||
notCompatibleType(tag, value)
|
||||
return nil
|
||||
|
@ -498,7 +498,7 @@ func setEventWithOldListener[V View, T any](properties Properties, tag PropertyN
|
|||
}
|
||||
|
||||
func viewEventsHtml[T any](view View, events []PropertyName, buffer *strings.Builder) {
|
||||
for _, tag := range []PropertyName{AnimationStartEvent, AnimationEndEvent, AnimationIterationEvent, AnimationCancelEvent} {
|
||||
for _, tag := range events {
|
||||
if value := view.getRaw(tag); value != nil {
|
||||
if js, ok := eventJsFunc[tag]; ok {
|
||||
if listeners, ok := value.([]func(View, T)); ok && len(listeners) > 0 {
|
||||
|
|
|
@ -123,8 +123,8 @@ func (picker *filePickerData) init(session Session) {
|
|||
picker.hasHtmlDisabled = true
|
||||
picker.files = []FileInfo{}
|
||||
picker.loader = map[int]func(FileInfo, []byte){}
|
||||
picker.set = filePickerSet
|
||||
picker.changed = filePickerPropertyChanged
|
||||
picker.set = picker.setFunc
|
||||
picker.changed = picker.propertyChanged
|
||||
|
||||
}
|
||||
|
||||
|
@ -150,27 +150,16 @@ func (picker *filePickerData) LoadFile(file FileInfo, result func(FileInfo, []by
|
|||
}
|
||||
}
|
||||
|
||||
func filePickerSet(view View, tag PropertyName, value any) []PropertyName {
|
||||
|
||||
setAccept := func(value string) []PropertyName {
|
||||
if value != "" {
|
||||
view.setRaw(tag, value)
|
||||
} else if view.getRaw(tag) != nil {
|
||||
view.setRaw(tag, nil)
|
||||
} else {
|
||||
return []PropertyName{}
|
||||
}
|
||||
return []PropertyName{Accept}
|
||||
}
|
||||
func (picker *filePickerData) setFunc(tag PropertyName, value any) []PropertyName {
|
||||
|
||||
switch tag {
|
||||
case FileSelectedEvent:
|
||||
return setViewEventListener[FilePicker, []FileInfo](view, tag, value)
|
||||
return setOneArgEventListener[FilePicker, []FileInfo](picker, tag, value)
|
||||
|
||||
case Accept:
|
||||
switch value := value.(type) {
|
||||
case string:
|
||||
return setAccept(strings.Trim(value, " \t\n"))
|
||||
return setStringPropertyValue(picker, Accept, strings.Trim(value, " \t\n"))
|
||||
|
||||
case []string:
|
||||
buffer := allocStringBuilder()
|
||||
|
@ -184,27 +173,27 @@ func filePickerSet(view View, tag PropertyName, value any) []PropertyName {
|
|||
buffer.WriteString(val)
|
||||
}
|
||||
}
|
||||
return setAccept(buffer.String())
|
||||
return setStringPropertyValue(picker, Accept, buffer.String())
|
||||
}
|
||||
notCompatibleType(tag, value)
|
||||
return nil
|
||||
}
|
||||
|
||||
return viewSet(view, tag, value)
|
||||
return picker.viewData.setFunc(tag, value)
|
||||
}
|
||||
|
||||
func filePickerPropertyChanged(view View, tag PropertyName) {
|
||||
func (picker *filePickerData) propertyChanged(tag PropertyName) {
|
||||
switch tag {
|
||||
case Accept:
|
||||
session := view.Session()
|
||||
if css := acceptPropertyCSS(view); css != "" {
|
||||
session.updateProperty(view.htmlID(), "accept", css)
|
||||
session := picker.Session()
|
||||
if css := acceptPropertyCSS(picker); css != "" {
|
||||
session.updateProperty(picker.htmlID(), "accept", css)
|
||||
} else {
|
||||
session.removeProperty(view.htmlID(), "accept")
|
||||
session.removeProperty(picker.htmlID(), "accept")
|
||||
}
|
||||
|
||||
default:
|
||||
viewPropertyChanged(view, tag)
|
||||
picker.viewData.propertyChanged(tag)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -381,5 +370,5 @@ func GetFilePickerAccept(view View, subviewID ...string) []string {
|
|||
// 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 GetFileSelectedListeners(view View, subviewID ...string) []func(FilePicker, []FileInfo) {
|
||||
return getEventListeners[FilePicker, []FileInfo](view, subviewID, FileSelectedEvent)
|
||||
return getOneArgEventListeners[FilePicker, []FileInfo](view, subviewID, FileSelectedEvent)
|
||||
}
|
||||
|
|
|
@ -51,11 +51,11 @@ func focusEventsHtml(view View, buffer *strings.Builder) {
|
|||
// GetFocusListeners returns a FocusListener list. 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 GetFocusListeners(view View, subviewID ...string) []func(View) {
|
||||
return getNoParamEventListeners[View](view, subviewID, FocusEvent)
|
||||
return getNoArgEventListeners[View](view, subviewID, FocusEvent)
|
||||
}
|
||||
|
||||
// GetLostFocusListeners returns a LostFocusListener list. 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 GetLostFocusListeners(view View, subviewID ...string) []func(View) {
|
||||
return getNoParamEventListeners[View](view, subviewID, LostFocusEvent)
|
||||
return getNoArgEventListeners[View](view, subviewID, LostFocusEvent)
|
||||
}
|
||||
|
|
|
@ -137,10 +137,10 @@ func (gridLayout *gridLayoutData) init(session Session) {
|
|||
gridLayout.systemClass = "ruiGridLayout"
|
||||
gridLayout.adapter = nil
|
||||
gridLayout.normalize = normalizeGridLayoutTag
|
||||
gridLayout.getFunc = gridLayout.get
|
||||
gridLayout.get = gridLayout.getFunc
|
||||
gridLayout.set = gridLayout.setFunc
|
||||
gridLayout.remove = gridLayout.removeFunc
|
||||
|
||||
gridLayout.changed = gridLayout.propertyChanged
|
||||
}
|
||||
|
||||
func setGridCellSize(properties Properties, tag PropertyName, value any) []PropertyName {
|
||||
|
@ -303,7 +303,7 @@ func normalizeGridLayoutTag(tag PropertyName) PropertyName {
|
|||
return tag
|
||||
}
|
||||
|
||||
func (gridLayout *gridLayoutData) get(self View, tag PropertyName) any {
|
||||
func (gridLayout *gridLayoutData) getFunc(tag PropertyName) any {
|
||||
switch tag {
|
||||
case Gap:
|
||||
rowGap := GetGridRowGap(gridLayout)
|
||||
|
@ -319,10 +319,10 @@ func (gridLayout *gridLayoutData) get(self View, tag PropertyName) any {
|
|||
}
|
||||
}
|
||||
|
||||
return gridLayout.viewsContainerData.get(gridLayout, tag)
|
||||
return gridLayout.viewsContainerData.getFunc(tag)
|
||||
}
|
||||
|
||||
func (gridLayout *gridLayoutData) removeFunc(self View, tag PropertyName) []PropertyName {
|
||||
func (gridLayout *gridLayoutData) removeFunc(tag PropertyName) []PropertyName {
|
||||
switch tag {
|
||||
case Gap:
|
||||
result := []PropertyName{}
|
||||
|
@ -343,13 +343,13 @@ func (gridLayout *gridLayoutData) removeFunc(self View, tag PropertyName) []Prop
|
|||
return []PropertyName{}
|
||||
}
|
||||
|
||||
return gridLayout.viewsContainerData.removeFunc(gridLayout, tag)
|
||||
return gridLayout.viewsContainerData.removeFunc(tag)
|
||||
}
|
||||
|
||||
func (gridLayout *gridLayoutData) setFunc(self View, tag PropertyName, value any) []PropertyName {
|
||||
func (gridLayout *gridLayoutData) setFunc(tag PropertyName, value any) []PropertyName {
|
||||
switch tag {
|
||||
case Gap:
|
||||
result := gridLayout.setFunc(gridLayout, GridRowGap, value)
|
||||
result := gridLayout.setFunc(GridRowGap, value)
|
||||
if result != nil {
|
||||
if gap := gridLayout.getRaw(GridRowGap); gap != nil {
|
||||
gridLayout.setRaw(GridColumnGap, gap)
|
||||
|
@ -370,21 +370,23 @@ func (gridLayout *gridLayoutData) setFunc(self View, tag PropertyName, value any
|
|||
return []PropertyName{Content}
|
||||
}
|
||||
|
||||
return gridLayout.viewsContainerData.setFunc(gridLayout, tag, value)
|
||||
return gridLayout.viewsContainerData.setFunc(tag, value)
|
||||
}
|
||||
|
||||
func gridLayoutPropertyChanged(view View, tag PropertyName) {
|
||||
func (gridLayout *gridLayoutData) propertyChanged(tag PropertyName) {
|
||||
switch tag {
|
||||
case CellWidth:
|
||||
view.Session().updateCSSProperty(view.htmlID(), `grid-template-columns`,
|
||||
gridCellSizesCSS(view, CellWidth, view.Session()))
|
||||
session := gridLayout.Session()
|
||||
session.updateCSSProperty(gridLayout.htmlID(), `grid-template-columns`,
|
||||
gridCellSizesCSS(gridLayout, CellWidth, session))
|
||||
|
||||
case CellHeight:
|
||||
view.Session().updateCSSProperty(view.htmlID(), `grid-template-rows`,
|
||||
gridCellSizesCSS(view, CellHeight, view.Session()))
|
||||
session := gridLayout.Session()
|
||||
session.updateCSSProperty(gridLayout.htmlID(), `grid-template-rows`,
|
||||
gridCellSizesCSS(gridLayout, CellHeight, session))
|
||||
|
||||
default:
|
||||
viewsContainerPropertyChanged(view, tag)
|
||||
gridLayout.viewsContainerData.propertyChanged(tag)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
30
imageView.go
30
imageView.go
|
@ -97,8 +97,8 @@ func (imageView *imageViewData) init(session Session) {
|
|||
imageView.tag = "ImageView"
|
||||
imageView.systemClass = "ruiImageView"
|
||||
imageView.normalize = normalizeImageViewTag
|
||||
imageView.set = imageViewSet
|
||||
imageView.changed = imageViewPropertyChanged
|
||||
imageView.set = imageView.setFunc
|
||||
imageView.changed = imageView.propertyChanged
|
||||
}
|
||||
|
||||
func normalizeImageViewTag(tag PropertyName) PropertyName {
|
||||
|
@ -122,30 +122,30 @@ func normalizeImageViewTag(tag PropertyName) PropertyName {
|
|||
return tag
|
||||
}
|
||||
|
||||
func imageViewSet(view View, tag PropertyName, value any) []PropertyName {
|
||||
func (imageView *imageViewData) setFunc(tag PropertyName, value any) []PropertyName {
|
||||
|
||||
switch tag {
|
||||
case Source, SrcSet, AltText:
|
||||
if text, ok := value.(string); ok {
|
||||
return setStringPropertyValue(view, tag, text)
|
||||
return setStringPropertyValue(imageView, tag, text)
|
||||
}
|
||||
notCompatibleType(tag, value)
|
||||
return nil
|
||||
|
||||
case LoadedEvent, ErrorEvent:
|
||||
return setNoParamEventListener[ImageView](view, tag, value)
|
||||
return setNoArgEventListener[ImageView](imageView, tag, value)
|
||||
}
|
||||
|
||||
return viewSet(view, tag, value)
|
||||
return imageView.viewData.setFunc(tag, value)
|
||||
}
|
||||
|
||||
func imageViewPropertyChanged(view View, tag PropertyName) {
|
||||
session := view.Session()
|
||||
htmlID := view.htmlID()
|
||||
func (imageView *imageViewData) propertyChanged(tag PropertyName) {
|
||||
session := imageView.Session()
|
||||
htmlID := imageView.htmlID()
|
||||
|
||||
switch tag {
|
||||
case Source:
|
||||
src, srcset := imageViewSrc(view, GetImageViewSource(view))
|
||||
src, srcset := imageViewSrc(imageView, GetImageViewSource(imageView))
|
||||
session.updateProperty(htmlID, "src", src)
|
||||
if srcset != "" {
|
||||
session.updateProperty(htmlID, "srcset", srcset)
|
||||
|
@ -154,7 +154,7 @@ func imageViewPropertyChanged(view View, tag PropertyName) {
|
|||
}
|
||||
|
||||
case SrcSet:
|
||||
_, srcset := imageViewSrc(view, GetImageViewSource(view))
|
||||
_, srcset := imageViewSrc(imageView, GetImageViewSource(imageView))
|
||||
if srcset != "" {
|
||||
session.updateProperty(htmlID, "srcset", srcset)
|
||||
} else {
|
||||
|
@ -168,7 +168,7 @@ func imageViewPropertyChanged(view View, tag PropertyName) {
|
|||
updateCSSStyle(htmlID, session)
|
||||
|
||||
default:
|
||||
viewPropertyChanged(view, tag)
|
||||
imageView.viewData.propertyChanged(tag)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -256,7 +256,7 @@ func (imageView *imageViewData) htmlProperties(self View, buffer *strings.Builde
|
|||
|
||||
buffer.WriteString(` onload="imageLoaded(this, event)"`)
|
||||
|
||||
if len(getNoParamEventListeners[ImageView](imageView, nil, ErrorEvent)) > 0 {
|
||||
if len(getNoArgEventListeners[ImageView](imageView, nil, ErrorEvent)) > 0 {
|
||||
buffer.WriteString(` onerror="imageError(this, event)"`)
|
||||
}
|
||||
}
|
||||
|
@ -299,7 +299,7 @@ func (imageView *imageViewData) cssStyle(self View, builder cssBuilder) {
|
|||
func (imageView *imageViewData) handleCommand(self View, command PropertyName, data DataObject) bool {
|
||||
switch command {
|
||||
case "imageViewError":
|
||||
for _, listener := range getNoParamEventListeners[ImageView](imageView, nil, ErrorEvent) {
|
||||
for _, listener := range getNoArgEventListeners[ImageView](imageView, nil, ErrorEvent) {
|
||||
listener(imageView)
|
||||
}
|
||||
|
||||
|
@ -308,7 +308,7 @@ func (imageView *imageViewData) handleCommand(self View, command PropertyName, d
|
|||
imageView.naturalHeight = dataFloatProperty(data, "natural-height")
|
||||
imageView.currentSrc, _ = data.PropertyValue("current-src")
|
||||
|
||||
for _, listener := range getNoParamEventListeners[ImageView](imageView, nil, LoadedEvent) {
|
||||
for _, listener := range getNoArgEventListeners[ImageView](imageView, nil, LoadedEvent) {
|
||||
listener(imageView)
|
||||
}
|
||||
|
||||
|
|
16
keyEvents.go
16
keyEvents.go
|
@ -431,7 +431,7 @@ func (event *KeyEvent) init(data DataObject) {
|
|||
|
||||
/*
|
||||
func setKeyListener(properties Properties, tag PropertyName, value any) bool {
|
||||
if listeners, ok := valueToEventListeners[View, KeyEvent](value); ok {
|
||||
if listeners, ok := valueToOneArgEventListeners[View, KeyEvent](value); ok {
|
||||
if len(listeners) == 0 {
|
||||
properties.setRaw(tag, nil)
|
||||
} else {
|
||||
|
@ -460,15 +460,15 @@ func (view *viewData) removeKeyListener(tag PropertyName) {
|
|||
*/
|
||||
|
||||
func keyEventsHtml(view View, buffer *strings.Builder) {
|
||||
if len(getEventListeners[View, KeyEvent](view, nil, KeyDownEvent)) > 0 {
|
||||
if len(getOneArgEventListeners[View, KeyEvent](view, nil, KeyDownEvent)) > 0 {
|
||||
buffer.WriteString(`onkeydown="keyDownEvent(this, event)" `)
|
||||
} else if view.Focusable() {
|
||||
if len(getEventListeners[View, MouseEvent](view, nil, ClickEvent)) > 0 {
|
||||
if len(getOneArgEventListeners[View, MouseEvent](view, nil, ClickEvent)) > 0 {
|
||||
buffer.WriteString(`onkeydown="keyDownEvent(this, event)" `)
|
||||
}
|
||||
}
|
||||
|
||||
if listeners := getEventListeners[View, KeyEvent](view, nil, KeyUpEvent); len(listeners) > 0 {
|
||||
if listeners := getOneArgEventListeners[View, KeyEvent](view, nil, KeyUpEvent); len(listeners) > 0 {
|
||||
buffer.WriteString(`onkeyup="keyUpEvent(this, event)" `)
|
||||
}
|
||||
}
|
||||
|
@ -476,7 +476,7 @@ func keyEventsHtml(view View, buffer *strings.Builder) {
|
|||
func handleKeyEvents(view View, tag PropertyName, data DataObject) {
|
||||
var event KeyEvent
|
||||
event.init(data)
|
||||
listeners := getEventListeners[View, KeyEvent](view, nil, tag)
|
||||
listeners := getOneArgEventListeners[View, KeyEvent](view, nil, tag)
|
||||
|
||||
if len(listeners) > 0 {
|
||||
for _, listener := range listeners {
|
||||
|
@ -486,7 +486,7 @@ func handleKeyEvents(view View, tag PropertyName, data DataObject) {
|
|||
}
|
||||
|
||||
if tag == KeyDownEvent && view.Focusable() && (event.Key == " " || event.Key == "Enter") && !IsDisabled(view) {
|
||||
if listeners := getEventListeners[View, MouseEvent](view, nil, ClickEvent); len(listeners) > 0 {
|
||||
if listeners := getOneArgEventListeners[View, MouseEvent](view, nil, ClickEvent); len(listeners) > 0 {
|
||||
clickEvent := MouseEvent{
|
||||
TimeStamp: event.TimeStamp,
|
||||
Button: PrimaryMouseButton,
|
||||
|
@ -512,11 +512,11 @@ func handleKeyEvents(view View, tag PropertyName, data DataObject) {
|
|||
// GetKeyDownListeners returns the "key-down-event" listener list. 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 GetKeyDownListeners(view View, subviewID ...string) []func(View, KeyEvent) {
|
||||
return getEventListeners[View, KeyEvent](view, subviewID, KeyDownEvent)
|
||||
return getOneArgEventListeners[View, KeyEvent](view, subviewID, KeyDownEvent)
|
||||
}
|
||||
|
||||
// GetKeyUpListeners returns the "key-up-event" listener list. 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 GetKeyUpListeners(view View, subviewID ...string) []func(View, KeyEvent) {
|
||||
return getEventListeners[View, KeyEvent](view, subviewID, KeyUpEvent)
|
||||
return getOneArgEventListeners[View, KeyEvent](view, subviewID, KeyUpEvent)
|
||||
}
|
||||
|
|
|
@ -64,10 +64,10 @@ func (listLayout *listLayoutData) init(session Session) {
|
|||
listLayout.tag = "ListLayout"
|
||||
listLayout.systemClass = "ruiListLayout"
|
||||
listLayout.normalize = normalizeListLayoutTag
|
||||
listLayout.getFunc = listLayout.get
|
||||
listLayout.get = listLayout.getFunc
|
||||
listLayout.set = listLayout.setFunc
|
||||
listLayout.remove = listLayout.removeFunc
|
||||
listLayout.changed = listLayoutPropertyChanged
|
||||
listLayout.changed = listLayout.propertyChanged
|
||||
|
||||
}
|
||||
|
||||
|
@ -86,7 +86,7 @@ func normalizeListLayoutTag(tag PropertyName) PropertyName {
|
|||
return tag
|
||||
}
|
||||
|
||||
func (listLayout *listLayoutData) get(self View, tag PropertyName) any {
|
||||
func (listLayout *listLayoutData) getFunc(tag PropertyName) any {
|
||||
switch tag {
|
||||
case Gap:
|
||||
if rowGap := GetListRowGap(listLayout); rowGap.Equal(GetListColumnGap(listLayout)) {
|
||||
|
@ -100,10 +100,10 @@ func (listLayout *listLayoutData) get(self View, tag PropertyName) any {
|
|||
}
|
||||
}
|
||||
|
||||
return listLayout.viewsContainerData.get(listLayout, tag)
|
||||
return listLayout.viewsContainerData.getFunc(tag)
|
||||
}
|
||||
|
||||
func (listLayout *listLayoutData) removeFunc(self View, tag PropertyName) []PropertyName {
|
||||
func (listLayout *listLayoutData) removeFunc(tag PropertyName) []PropertyName {
|
||||
switch tag {
|
||||
case Gap:
|
||||
result := []PropertyName{}
|
||||
|
@ -116,18 +116,18 @@ func (listLayout *listLayoutData) removeFunc(self View, tag PropertyName) []Prop
|
|||
return result
|
||||
|
||||
case Content:
|
||||
listLayout.viewsContainerData.removeFunc(listLayout, Content)
|
||||
listLayout.viewsContainerData.removeFunc(Content)
|
||||
listLayout.adapter = nil
|
||||
return []PropertyName{Content}
|
||||
}
|
||||
|
||||
return listLayout.viewsContainerData.removeFunc(listLayout, tag)
|
||||
return listLayout.viewsContainerData.removeFunc(tag)
|
||||
}
|
||||
|
||||
func (listLayout *listLayoutData) setFunc(self View, tag PropertyName, value any) []PropertyName {
|
||||
func (listLayout *listLayoutData) setFunc(tag PropertyName, value any) []PropertyName {
|
||||
switch tag {
|
||||
case Gap:
|
||||
result := listLayout.setFunc(listLayout, ListRowGap, value)
|
||||
result := listLayout.setFunc(ListRowGap, value)
|
||||
if result != nil {
|
||||
if gap := listLayout.getRaw(ListRowGap); gap != nil {
|
||||
listLayout.setRaw(ListColumnGap, gap)
|
||||
|
@ -147,16 +147,16 @@ func (listLayout *listLayoutData) setFunc(self View, tag PropertyName, value any
|
|||
}
|
||||
return []PropertyName{Content}
|
||||
}
|
||||
return listLayout.viewsContainerData.setFunc(listLayout, tag, value)
|
||||
return listLayout.viewsContainerData.setFunc(tag, value)
|
||||
}
|
||||
|
||||
func listLayoutPropertyChanged(view View, tag PropertyName) {
|
||||
func (listLayout *listLayoutData) propertyChanged(tag PropertyName) {
|
||||
switch tag {
|
||||
case Orientation, ListWrap, HorizontalAlign, VerticalAlign:
|
||||
updateCSSStyle(view.htmlID(), view.Session())
|
||||
updateCSSStyle(listLayout.htmlID(), listLayout.Session())
|
||||
|
||||
default:
|
||||
viewsContainerPropertyChanged(view, tag)
|
||||
listLayout.viewsContainerData.propertyChanged(tag)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
137
listView.go
137
listView.go
|
@ -148,11 +148,10 @@ func (listView *listViewData) init(session Session) {
|
|||
listView.items = []View{}
|
||||
listView.itemFrame = []Frame{}
|
||||
listView.normalize = normalizeListViewTag
|
||||
listView.getFunc = listView.get
|
||||
listView.set = listViewSet
|
||||
listView.changed = listViewPropertyChanged
|
||||
listView.remove = listViewRemove
|
||||
|
||||
listView.get = listView.getFunc
|
||||
listView.set = listView.setFunc
|
||||
listView.remove = listView.removeFunc
|
||||
listView.changed = listView.propertyChanged
|
||||
}
|
||||
|
||||
func (listView *listViewData) Views() []View {
|
||||
|
@ -183,36 +182,36 @@ func normalizeListViewTag(tag PropertyName) PropertyName {
|
|||
return tag
|
||||
}
|
||||
|
||||
func listViewRemove(view View, tag PropertyName) []PropertyName {
|
||||
func (listView *listViewData) removeFunc(tag PropertyName) []PropertyName {
|
||||
switch tag {
|
||||
case Gap:
|
||||
result := viewRemove(view, ListRowGap)
|
||||
result := listView.removeFunc(ListRowGap)
|
||||
if result != nil {
|
||||
if result2 := viewRemove(view, ListColumnGap); result2 != nil {
|
||||
if result2 := listView.removeFunc(ListColumnGap); result2 != nil {
|
||||
result = append(result, result2...)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
return viewRemove(view, tag)
|
||||
return listView.viewData.removeFunc(tag)
|
||||
}
|
||||
|
||||
func listViewSet(view View, tag PropertyName, value any) []PropertyName {
|
||||
func (listView *listViewData) setFunc(tag PropertyName, value any) []PropertyName {
|
||||
switch tag {
|
||||
case Gap:
|
||||
result := listViewSet(view, ListRowGap, value)
|
||||
result := listView.setFunc(ListRowGap, value)
|
||||
if result != nil {
|
||||
if result2 := listViewSet(view, ListColumnGap, value); result2 != nil {
|
||||
if result2 := listView.setFunc(ListColumnGap, value); result2 != nil {
|
||||
result = append(result, result2...)
|
||||
}
|
||||
}
|
||||
return result
|
||||
|
||||
case ListItemClickedEvent, ListItemSelectedEvent:
|
||||
return setViewEventListener[ListView, int](view, tag, value)
|
||||
return setOneArgEventListener[ListView, int](listView, tag, value)
|
||||
|
||||
case ListItemCheckedEvent:
|
||||
return setViewEventListener[ListView, []int](view, tag, value)
|
||||
return setOneArgEventListener[ListView, []int](listView, tag, value)
|
||||
|
||||
case Checked:
|
||||
var checked []int
|
||||
|
@ -243,69 +242,65 @@ func listViewSet(view View, tag PropertyName, value any) []PropertyName {
|
|||
return nil
|
||||
}
|
||||
|
||||
return setArrayPropertyValue(view, Checked, checked)
|
||||
return setArrayPropertyValue(listView, Checked, checked)
|
||||
|
||||
case Items:
|
||||
return listViewSetItems(view, value)
|
||||
return listView.setItems(value)
|
||||
|
||||
case ListItemStyle, CurrentStyle, CurrentInactiveStyle:
|
||||
if text, ok := value.(string); ok {
|
||||
return setStringPropertyValue(view, tag, text)
|
||||
return setStringPropertyValue(listView, tag, text)
|
||||
}
|
||||
notCompatibleType(tag, value)
|
||||
return nil
|
||||
|
||||
case Current:
|
||||
return setIntProperty(view, Current, value)
|
||||
return setIntProperty(listView, Current, value)
|
||||
}
|
||||
|
||||
return viewSet(view, tag, value)
|
||||
return listView.viewData.setFunc(tag, value)
|
||||
|
||||
}
|
||||
|
||||
func listViewPropertyChanged(view View, tag PropertyName) {
|
||||
func (listView *listViewData) propertyChanged(tag PropertyName) {
|
||||
switch tag {
|
||||
|
||||
case Current:
|
||||
updateInnerHTML(view.htmlID(), view.Session())
|
||||
if listeners := getEventListeners[ListView, int](view, nil, ListItemSelectedEvent); len(listeners) > 0 {
|
||||
if listView, ok := view.(ListView); ok {
|
||||
current := GetCurrent(view)
|
||||
for _, listener := range listeners {
|
||||
listener(listView, current)
|
||||
}
|
||||
updateInnerHTML(listView.htmlID(), listView.Session())
|
||||
if listeners := getOneArgEventListeners[ListView, int](listView, nil, ListItemSelectedEvent); len(listeners) > 0 {
|
||||
current := GetCurrent(listView)
|
||||
for _, listener := range listeners {
|
||||
listener(listView, current)
|
||||
}
|
||||
}
|
||||
|
||||
case Checked:
|
||||
updateInnerHTML(view.htmlID(), view.Session())
|
||||
if listeners := getEventListeners[ListView, []int](view, nil, ListItemCheckedEvent); len(listeners) > 0 {
|
||||
if listView, ok := view.(ListView); ok {
|
||||
checked := GetListViewCheckedItems(view)
|
||||
for _, listener := range listeners {
|
||||
listener(listView, checked)
|
||||
}
|
||||
updateInnerHTML(listView.htmlID(), listView.Session())
|
||||
if listeners := getOneArgEventListeners[ListView, []int](listView, nil, ListItemCheckedEvent); len(listeners) > 0 {
|
||||
checked := GetListViewCheckedItems(listView)
|
||||
for _, listener := range listeners {
|
||||
listener(listView, checked)
|
||||
}
|
||||
}
|
||||
|
||||
case Items, Orientation, ListWrap, ListRowGap, ListColumnGap, VerticalAlign, HorizontalAlign, Style, StyleDisabled, ItemWidth, ItemHeight,
|
||||
ItemHorizontalAlign, ItemVerticalAlign, ItemCheckbox, CheckboxHorizontalAlign, CheckboxVerticalAlign, ListItemStyle, AccentColor:
|
||||
updateInnerHTML(view.htmlID(), view.Session())
|
||||
updateInnerHTML(listView.htmlID(), listView.Session())
|
||||
|
||||
case CurrentStyle:
|
||||
view.Session().updateProperty(view.htmlID(), "data-focusitemstyle", listViewCurrentStyle(view))
|
||||
updateInnerHTML(view.htmlID(), view.Session())
|
||||
listView.Session().updateProperty(listView.htmlID(), "data-focusitemstyle", listViewCurrentStyle(listView))
|
||||
updateInnerHTML(listView.htmlID(), listView.Session())
|
||||
|
||||
case CurrentInactiveStyle:
|
||||
view.Session().updateProperty(view.htmlID(), "data-bluritemstyle", listViewCurrentInactiveStyle(view))
|
||||
updateInnerHTML(view.htmlID(), view.Session())
|
||||
listView.Session().updateProperty(listView.htmlID(), "data-bluritemstyle", listViewCurrentInactiveStyle(listView))
|
||||
updateInnerHTML(listView.htmlID(), listView.Session())
|
||||
|
||||
default:
|
||||
viewPropertyChanged(view, tag)
|
||||
listView.viewData.propertyChanged(tag)
|
||||
}
|
||||
}
|
||||
|
||||
func (listView *listViewData) get(self View, tag PropertyName) any {
|
||||
func (listView *listViewData) getFunc(tag PropertyName) any {
|
||||
switch tag {
|
||||
case Gap:
|
||||
if rowGap := GetListRowGap(listView); rowGap.Equal(GetListColumnGap(listView)) {
|
||||
|
@ -313,16 +308,13 @@ func (listView *listViewData) get(self View, tag PropertyName) any {
|
|||
}
|
||||
return AutoSize()
|
||||
}
|
||||
return viewGet(self, tag)
|
||||
return listView.viewData.getFunc(tag)
|
||||
}
|
||||
|
||||
func listViewSetItems(properties Properties, value any) []PropertyName {
|
||||
func (listView *listViewData) setItems(value any) []PropertyName {
|
||||
var adapter ListAdapter = nil
|
||||
|
||||
var session Session = nil
|
||||
if view, ok := properties.(View); ok {
|
||||
session = view.Session()
|
||||
}
|
||||
session := listView.session
|
||||
|
||||
switch value := value.(type) {
|
||||
case []string:
|
||||
|
@ -400,7 +392,7 @@ func listViewSetItems(properties Properties, value any) []PropertyName {
|
|||
return nil
|
||||
}
|
||||
|
||||
properties.setRaw(Items, adapter)
|
||||
listView.setRaw(Items, adapter)
|
||||
return []PropertyName{Items}
|
||||
}
|
||||
|
||||
|
@ -951,7 +943,9 @@ func (listView *listViewData) handleCommand(self View, command PropertyName, dat
|
|||
}
|
||||
|
||||
case "itemClick":
|
||||
listView.onItemClick()
|
||||
if number, ok := dataIntProperty(data, `number`); ok {
|
||||
listView.onItemClick(number)
|
||||
}
|
||||
|
||||
default:
|
||||
return listView.viewData.handleCommand(self, command, data)
|
||||
|
@ -962,7 +956,7 @@ func (listView *listViewData) handleCommand(self View, command PropertyName, dat
|
|||
|
||||
func (listView *listViewData) handleCurrent(number int) {
|
||||
listView.properties[Current] = number
|
||||
for _, listener := range getEventListeners[ListView, int](listView, nil, ListItemSelectedEvent) {
|
||||
for _, listener := range getOneArgEventListeners[ListView, int](listView, nil, ListItemSelectedEvent) {
|
||||
listener(listView, number)
|
||||
}
|
||||
if listener, ok := listView.changeListener[Current]; ok {
|
||||
|
@ -970,33 +964,37 @@ func (listView *listViewData) handleCurrent(number int) {
|
|||
}
|
||||
}
|
||||
|
||||
func (listView *listViewData) onItemClick() {
|
||||
checkbox := GetListViewCheckbox(listView)
|
||||
if checkbox == NoneCheckbox {
|
||||
func (listView *listViewData) onItemClick(number int) {
|
||||
|
||||
if IsDisabled(listView) {
|
||||
return
|
||||
}
|
||||
|
||||
if current := GetCurrent(listView); current >= 0 && !IsDisabled(listView) {
|
||||
if current := GetCurrent(listView); current != number {
|
||||
listView.Set(Current, number)
|
||||
}
|
||||
|
||||
if checkbox := GetListViewCheckbox(listView); checkbox != NoneCheckbox {
|
||||
checkedItem := GetListViewCheckedItems(listView)
|
||||
|
||||
switch checkbox {
|
||||
case SingleCheckbox:
|
||||
if len(checkedItem) == 0 {
|
||||
checkedItem = []int{current}
|
||||
listView.updateCheckboxItem(current, true)
|
||||
} else if checkedItem[0] != current {
|
||||
checkedItem = []int{number}
|
||||
listView.updateCheckboxItem(number, true)
|
||||
} else if checkedItem[0] != number {
|
||||
listView.updateCheckboxItem(checkedItem[0], false)
|
||||
checkedItem = []int{current}
|
||||
listView.updateCheckboxItem(current, true)
|
||||
checkedItem = []int{number}
|
||||
listView.updateCheckboxItem(number, true)
|
||||
} else {
|
||||
checkedItem = []int{}
|
||||
listView.updateCheckboxItem(current, false)
|
||||
listView.updateCheckboxItem(number, false)
|
||||
}
|
||||
|
||||
case MultipleCheckbox:
|
||||
uncheck := false
|
||||
for i, index := range checkedItem {
|
||||
if index == current {
|
||||
if index == number {
|
||||
uncheck = true
|
||||
listView.updateCheckboxItem(index, false)
|
||||
count := len(checkedItem)
|
||||
|
@ -1014,8 +1012,8 @@ func (listView *listViewData) onItemClick() {
|
|||
}
|
||||
|
||||
if !uncheck {
|
||||
listView.updateCheckboxItem(current, true)
|
||||
checkedItem = append(checkedItem, current)
|
||||
listView.updateCheckboxItem(number, true)
|
||||
checkedItem = append(checkedItem, number)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1024,10 +1022,15 @@ func (listView *listViewData) onItemClick() {
|
|||
listener(listView, Checked)
|
||||
}
|
||||
|
||||
for _, listener := range getEventListeners[ListView, []int](listView, nil, ListItemCheckedEvent) {
|
||||
for _, listener := range getOneArgEventListeners[ListView, []int](listView, nil, ListItemCheckedEvent) {
|
||||
listener(listView, checkedItem)
|
||||
}
|
||||
}
|
||||
|
||||
for _, listener := range getOneArgEventListeners[ListView, int](listView, nil, ListItemClickedEvent) {
|
||||
listener(listView, number)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (listView *listViewData) onItemResize(self View, index string, x, y, width, height float64) {
|
||||
|
@ -1057,21 +1060,21 @@ func GetHorizontalAlign(view View, subviewID ...string) int {
|
|||
// 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 GetListItemClickedListeners(view View, subviewID ...string) []func(ListView, int) {
|
||||
return getEventListeners[ListView, int](view, subviewID, ListItemClickedEvent)
|
||||
return getOneArgEventListeners[ListView, int](view, subviewID, ListItemClickedEvent)
|
||||
}
|
||||
|
||||
// GetListItemSelectedListeners returns a ListItemSelectedListener of the ListView.
|
||||
// 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 GetListItemSelectedListeners(view View, subviewID ...string) []func(ListView, int) {
|
||||
return getEventListeners[ListView, int](view, subviewID, ListItemSelectedEvent)
|
||||
return getOneArgEventListeners[ListView, int](view, subviewID, ListItemSelectedEvent)
|
||||
}
|
||||
|
||||
// GetListItemCheckedListeners returns a ListItemCheckedListener of the ListView.
|
||||
// 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 GetListItemCheckedListeners(view View, subviewID ...string) []func(ListView, []int) {
|
||||
return getEventListeners[ListView, []int](view, subviewID, ListItemCheckedEvent)
|
||||
return getOneArgEventListeners[ListView, []int](view, subviewID, ListItemCheckedEvent)
|
||||
}
|
||||
|
||||
// GetListItemWidth returns the width of a ListView item.
|
||||
|
|
|
@ -907,46 +907,39 @@ type MediaSource struct {
|
|||
func (player *mediaPlayerData) init(session Session) {
|
||||
player.viewData.init(session)
|
||||
player.tag = "MediaPlayer"
|
||||
player.set = mediaPlayerSet
|
||||
player.changed = mediaPlayerPropertyChanged
|
||||
player.set = player.setFunc
|
||||
player.changed = player.propertyChanged
|
||||
}
|
||||
|
||||
func (player *mediaPlayerData) Focusable() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func mediaPlayerSet(view View, tag PropertyName, value any) []PropertyName {
|
||||
func (player *mediaPlayerData) setFunc(tag PropertyName, value any) []PropertyName {
|
||||
switch tag {
|
||||
|
||||
case AbortEvent, CanPlayEvent, CanPlayThroughEvent, CompleteEvent, EmptiedEvent, LoadStartEvent,
|
||||
EndedEvent, LoadedDataEvent, LoadedMetadataEvent, PauseEvent, PlayEvent, PlayingEvent,
|
||||
ProgressEvent, SeekedEvent, SeekingEvent, StalledEvent, SuspendEvent, WaitingEvent:
|
||||
|
||||
return setNoParamEventListener[MediaPlayer](view, tag, value)
|
||||
return setNoArgEventListener[MediaPlayer](player, tag, value)
|
||||
|
||||
case DurationChangedEvent, RateChangedEvent, TimeUpdateEvent, VolumeChangedEvent:
|
||||
|
||||
return setViewEventListener[MediaPlayer, float64](view, tag, value)
|
||||
return setOneArgEventListener[MediaPlayer, float64](player, tag, value)
|
||||
|
||||
case PlayerErrorEvent:
|
||||
if listeners, ok := valueToPlayerErrorListeners(value); ok {
|
||||
if len(listeners) > 0 {
|
||||
view.setRaw(tag, listeners)
|
||||
} else if view.getRaw(tag) != nil {
|
||||
view.setRaw(tag, nil)
|
||||
} else {
|
||||
return []PropertyName{}
|
||||
}
|
||||
return []PropertyName{tag}
|
||||
return setArrayPropertyValue(player, tag, listeners)
|
||||
}
|
||||
notCompatibleType(tag, value)
|
||||
return nil
|
||||
|
||||
case Source:
|
||||
return setMediaPlayerSource(view, value)
|
||||
return setMediaPlayerSource(player, value)
|
||||
}
|
||||
|
||||
return viewSet(view, tag, value)
|
||||
return player.viewData.setFunc(tag, value)
|
||||
}
|
||||
|
||||
func setMediaPlayerSource(properties Properties, value any) []PropertyName {
|
||||
|
@ -1151,26 +1144,26 @@ func mediaPlayerEvents() map[PropertyName]string {
|
|||
}
|
||||
}
|
||||
|
||||
func mediaPlayerPropertyChanged(view View, tag PropertyName) {
|
||||
session := view.Session()
|
||||
func (player *mediaPlayerData) propertyChanged(tag PropertyName) {
|
||||
session := player.Session()
|
||||
|
||||
switch tag {
|
||||
case Controls, Loop:
|
||||
value, _ := boolProperty(view, tag, session)
|
||||
value, _ := boolProperty(player, tag, session)
|
||||
if value {
|
||||
session.updateProperty(view.htmlID(), string(tag), value)
|
||||
session.updateProperty(player.htmlID(), string(tag), value)
|
||||
} else {
|
||||
session.removeProperty(view.htmlID(), string(tag))
|
||||
session.removeProperty(player.htmlID(), string(tag))
|
||||
}
|
||||
|
||||
case Muted:
|
||||
value, _ := boolProperty(view, Muted, session)
|
||||
session.callFunc("setMediaMuted", view.htmlID(), value)
|
||||
value, _ := boolProperty(player, Muted, session)
|
||||
session.callFunc("setMediaMuted", player.htmlID(), value)
|
||||
|
||||
case Preload:
|
||||
value, _ := enumProperty(view, Preload, session, 0)
|
||||
value, _ := enumProperty(player, Preload, session, 0)
|
||||
values := enumProperties[Preload].values
|
||||
session.updateProperty(view.htmlID(), string(Preload), values[value])
|
||||
session.updateProperty(player.htmlID(), string(Preload), values[value])
|
||||
|
||||
case AbortEvent, CanPlayEvent, CanPlayThroughEvent, CompleteEvent, EmptiedEvent,
|
||||
EndedEvent, LoadedDataEvent, LoadedMetadataEvent, PauseEvent, PlayEvent, PlayingEvent, ProgressEvent,
|
||||
|
@ -1178,54 +1171,54 @@ func mediaPlayerPropertyChanged(view View, tag PropertyName) {
|
|||
|
||||
if cssTag, ok := mediaPlayerEvents()[tag]; ok {
|
||||
fn := ""
|
||||
if value := view.getRaw(tag); value != nil {
|
||||
if value := player.getRaw(tag); value != nil {
|
||||
if listeners, ok := value.([]func(MediaPlayer)); ok && len(listeners) > 0 {
|
||||
fn = fmt.Sprintf(`viewEvent(this, "%s")`, string(tag))
|
||||
}
|
||||
}
|
||||
session.updateProperty(view.htmlID(), cssTag, fn)
|
||||
session.updateProperty(player.htmlID(), cssTag, fn)
|
||||
}
|
||||
|
||||
case TimeUpdateEvent:
|
||||
if value := view.getRaw(tag); value != nil {
|
||||
session.updateProperty(view.htmlID(), "ontimeupdate", "viewTimeUpdatedEvent(this)")
|
||||
if value := player.getRaw(tag); value != nil {
|
||||
session.updateProperty(player.htmlID(), "ontimeupdate", "viewTimeUpdatedEvent(this)")
|
||||
} else {
|
||||
session.updateProperty(view.htmlID(), "ontimeupdate", "")
|
||||
session.updateProperty(player.htmlID(), "ontimeupdate", "")
|
||||
}
|
||||
|
||||
case VolumeChangedEvent:
|
||||
if value := view.getRaw(tag); value != nil {
|
||||
session.updateProperty(view.htmlID(), "onvolumechange", "viewVolumeChangedEvent(this)")
|
||||
if value := player.getRaw(tag); value != nil {
|
||||
session.updateProperty(player.htmlID(), "onvolumechange", "viewVolumeChangedEvent(this)")
|
||||
} else {
|
||||
session.updateProperty(view.htmlID(), "onvolumechange", "")
|
||||
session.updateProperty(player.htmlID(), "onvolumechange", "")
|
||||
}
|
||||
|
||||
case DurationChangedEvent:
|
||||
if value := view.getRaw(tag); value != nil {
|
||||
session.updateProperty(view.htmlID(), "ondurationchange", "viewDurationChangedEvent(this)")
|
||||
if value := player.getRaw(tag); value != nil {
|
||||
session.updateProperty(player.htmlID(), "ondurationchange", "viewDurationChangedEvent(this)")
|
||||
} else {
|
||||
session.updateProperty(view.htmlID(), "ondurationchange", "")
|
||||
session.updateProperty(player.htmlID(), "ondurationchange", "")
|
||||
}
|
||||
|
||||
case RateChangedEvent:
|
||||
if value := view.getRaw(tag); value != nil {
|
||||
session.updateProperty(view.htmlID(), "onratechange", "viewRateChangedEvent(this)")
|
||||
if value := player.getRaw(tag); value != nil {
|
||||
session.updateProperty(player.htmlID(), "onratechange", "viewRateChangedEvent(this)")
|
||||
} else {
|
||||
session.updateProperty(view.htmlID(), "onratechange", "")
|
||||
session.updateProperty(player.htmlID(), "onratechange", "")
|
||||
}
|
||||
|
||||
case PlayerErrorEvent:
|
||||
if value := view.getRaw(tag); value != nil {
|
||||
session.updateProperty(view.htmlID(), "onerror", "viewErrorEvent(this)")
|
||||
if value := player.getRaw(tag); value != nil {
|
||||
session.updateProperty(player.htmlID(), "onerror", "viewErrorEvent(this)")
|
||||
} else {
|
||||
session.updateProperty(view.htmlID(), "onerror", "")
|
||||
session.updateProperty(player.htmlID(), "onerror", "")
|
||||
}
|
||||
|
||||
case Source:
|
||||
updateInnerHTML(view.htmlID(), session)
|
||||
updateInnerHTML(player.htmlID(), session)
|
||||
|
||||
default:
|
||||
viewPropertyChanged(view, tag)
|
||||
player.viewData.propertyChanged(tag)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -230,7 +230,7 @@ type MouseEvent struct {
|
|||
|
||||
/*
|
||||
func setMouseListener(properties Properties, tag PropertyName, value any) bool {
|
||||
if listeners, ok := valueToEventListeners[View, MouseEvent](value); ok {
|
||||
if listeners, ok := valueToOneArgEventListeners[View, MouseEvent](value); ok {
|
||||
if len(listeners) == 0 {
|
||||
properties.setRaw(tag, nil)
|
||||
} else {
|
||||
|
@ -302,7 +302,7 @@ func (event *MouseEvent) init(data DataObject) {
|
|||
}
|
||||
|
||||
func handleMouseEvents(view View, tag PropertyName, data DataObject) {
|
||||
listeners := getEventListeners[View, MouseEvent](view, nil, tag)
|
||||
listeners := getOneArgEventListeners[View, MouseEvent](view, nil, tag)
|
||||
if len(listeners) > 0 {
|
||||
var event MouseEvent
|
||||
event.init(data)
|
||||
|
@ -316,48 +316,48 @@ func handleMouseEvents(view View, tag PropertyName, data DataObject) {
|
|||
// GetClickListeners returns the "click-event" listener list. 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 GetClickListeners(view View, subviewID ...string) []func(View, MouseEvent) {
|
||||
return getEventListeners[View, MouseEvent](view, subviewID, ClickEvent)
|
||||
return getOneArgEventListeners[View, MouseEvent](view, subviewID, ClickEvent)
|
||||
}
|
||||
|
||||
// GetDoubleClickListeners returns the "double-click-event" listener list. 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 GetDoubleClickListeners(view View, subviewID ...string) []func(View, MouseEvent) {
|
||||
return getEventListeners[View, MouseEvent](view, subviewID, DoubleClickEvent)
|
||||
return getOneArgEventListeners[View, MouseEvent](view, subviewID, DoubleClickEvent)
|
||||
}
|
||||
|
||||
// GetContextMenuListeners returns the "context-menu" listener list.
|
||||
// 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 GetContextMenuListeners(view View, subviewID ...string) []func(View, MouseEvent) {
|
||||
return getEventListeners[View, MouseEvent](view, subviewID, ContextMenuEvent)
|
||||
return getOneArgEventListeners[View, MouseEvent](view, subviewID, ContextMenuEvent)
|
||||
}
|
||||
|
||||
// GetMouseDownListeners returns the "mouse-down" listener list. 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 GetMouseDownListeners(view View, subviewID ...string) []func(View, MouseEvent) {
|
||||
return getEventListeners[View, MouseEvent](view, subviewID, MouseDown)
|
||||
return getOneArgEventListeners[View, MouseEvent](view, subviewID, MouseDown)
|
||||
}
|
||||
|
||||
// GetMouseUpListeners returns the "mouse-up" listener list. 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 GetMouseUpListeners(view View, subviewID ...string) []func(View, MouseEvent) {
|
||||
return getEventListeners[View, MouseEvent](view, subviewID, MouseUp)
|
||||
return getOneArgEventListeners[View, MouseEvent](view, subviewID, MouseUp)
|
||||
}
|
||||
|
||||
// GetMouseMoveListeners returns the "mouse-move" listener list. 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 GetMouseMoveListeners(view View, subviewID ...string) []func(View, MouseEvent) {
|
||||
return getEventListeners[View, MouseEvent](view, subviewID, MouseMove)
|
||||
return getOneArgEventListeners[View, MouseEvent](view, subviewID, MouseMove)
|
||||
}
|
||||
|
||||
// GetMouseOverListeners returns the "mouse-over" listener list. 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 GetMouseOverListeners(view View, subviewID ...string) []func(View, MouseEvent) {
|
||||
return getEventListeners[View, MouseEvent](view, subviewID, MouseOver)
|
||||
return getOneArgEventListeners[View, MouseEvent](view, subviewID, MouseOver)
|
||||
}
|
||||
|
||||
// GetMouseOutListeners returns the "mouse-out" listener list. 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 GetMouseOutListeners(view View, subviewID ...string) []func(View, MouseEvent) {
|
||||
return getEventListeners[View, MouseEvent](view, subviewID, MouseOut)
|
||||
return getOneArgEventListeners[View, MouseEvent](view, subviewID, MouseOut)
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package rui
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
@ -79,6 +80,16 @@ const (
|
|||
//
|
||||
// Internal type is `float`, other types converted to it during assignment.
|
||||
NumberPickerValue PropertyName = "number-picker-value"
|
||||
|
||||
// NumberPickerValue is the constant for "number-picker-value" property tag.
|
||||
//
|
||||
// Used by `NumberPicker`.
|
||||
// Precision of displaying fractional part in editor. The default value is 0 (not used).
|
||||
//
|
||||
// Supported types: `int`, `int8`...`int64`, `uint`, `uint8`...`uint64`, `string`.
|
||||
//
|
||||
// Internal type is `float`, other types converted to it during assignment.
|
||||
NumberPickerPrecision PropertyName = "number-picker-precision"
|
||||
)
|
||||
|
||||
// Constants which describe values of the "number-picker-type" property of a [NumberPicker]
|
||||
|
@ -116,8 +127,8 @@ func (picker *numberPickerData) init(session Session) {
|
|||
picker.tag = "NumberPicker"
|
||||
picker.hasHtmlDisabled = true
|
||||
picker.normalize = normalizeNumberPickerTag
|
||||
picker.set = numberPickerSet
|
||||
picker.changed = numberPickerPropertyChanged
|
||||
picker.set = picker.setFunc
|
||||
picker.changed = picker.propertyChanged
|
||||
}
|
||||
|
||||
func (picker *numberPickerData) Focusable() bool {
|
||||
|
@ -127,73 +138,83 @@ func (picker *numberPickerData) Focusable() bool {
|
|||
func normalizeNumberPickerTag(tag PropertyName) PropertyName {
|
||||
tag = defaultNormalize(tag)
|
||||
switch tag {
|
||||
case Type, Min, Max, Step, Value:
|
||||
case Type, Min, Max, Step, Value, "precision":
|
||||
return "number-picker-" + tag
|
||||
}
|
||||
|
||||
return normalizeDataListTag(tag)
|
||||
}
|
||||
|
||||
func numberPickerSet(view View, tag PropertyName, value any) []PropertyName {
|
||||
func (picker *numberPickerData) setFunc(tag PropertyName, value any) []PropertyName {
|
||||
switch tag {
|
||||
case NumberChangedEvent:
|
||||
return setEventWithOldListener[NumberPicker, float64](view, tag, value)
|
||||
return setTwoArgEventListener[NumberPicker, float64](picker, tag, value)
|
||||
|
||||
case NumberPickerValue:
|
||||
view.setRaw("old-number", GetNumberPickerValue(view))
|
||||
min, max := GetNumberPickerMinMax(view)
|
||||
picker.setRaw("old-number", GetNumberPickerValue(picker))
|
||||
min, max := GetNumberPickerMinMax(picker)
|
||||
|
||||
return setFloatProperty(view, NumberPickerValue, value, min, max)
|
||||
return setFloatProperty(picker, NumberPickerValue, value, min, max)
|
||||
|
||||
case DataList:
|
||||
return setDataList(view, value, "")
|
||||
return setDataList(picker, value, "")
|
||||
}
|
||||
|
||||
return viewSet(view, tag, value)
|
||||
return picker.viewData.setFunc(tag, value)
|
||||
}
|
||||
|
||||
func numberPickerPropertyChanged(view View, tag PropertyName) {
|
||||
func (picker *numberPickerData) numberFormat() string {
|
||||
if precission := GetNumberPickerPrecision(picker); precission > 0 {
|
||||
return fmt.Sprintf("%%.%df", precission)
|
||||
}
|
||||
return "%g"
|
||||
}
|
||||
|
||||
func (picker *numberPickerData) propertyChanged(tag PropertyName) {
|
||||
switch tag {
|
||||
case NumberPickerType:
|
||||
if GetNumberPickerType(view) == NumberSlider {
|
||||
view.Session().updateProperty(view.htmlID(), "type", "range")
|
||||
if GetNumberPickerType(picker) == NumberSlider {
|
||||
picker.Session().updateProperty(picker.htmlID(), "type", "range")
|
||||
} else {
|
||||
view.Session().updateProperty(view.htmlID(), "type", "number")
|
||||
picker.Session().updateProperty(picker.htmlID(), "type", "number")
|
||||
}
|
||||
|
||||
case NumberPickerMin:
|
||||
min, _ := GetNumberPickerMinMax(view)
|
||||
view.Session().updateProperty(view.htmlID(), "min", strconv.FormatFloat(min, 'f', -1, 32))
|
||||
min, _ := GetNumberPickerMinMax(picker)
|
||||
picker.Session().updateProperty(picker.htmlID(), "min", fmt.Sprintf(picker.numberFormat(), min))
|
||||
|
||||
case NumberPickerMax:
|
||||
_, max := GetNumberPickerMinMax(view)
|
||||
view.Session().updateProperty(view.htmlID(), "max", strconv.FormatFloat(max, 'f', -1, 32))
|
||||
_, max := GetNumberPickerMinMax(picker)
|
||||
picker.Session().updateProperty(picker.htmlID(), "max", fmt.Sprintf(picker.numberFormat(), max))
|
||||
|
||||
case NumberPickerStep:
|
||||
if step := GetNumberPickerStep(view); step > 0 {
|
||||
view.Session().updateProperty(view.htmlID(), "step", strconv.FormatFloat(step, 'f', -1, 32))
|
||||
if step := GetNumberPickerStep(picker); step > 0 {
|
||||
picker.Session().updateProperty(picker.htmlID(), "step", fmt.Sprintf(picker.numberFormat(), step))
|
||||
} else {
|
||||
view.Session().updateProperty(view.htmlID(), "step", "any")
|
||||
picker.Session().updateProperty(picker.htmlID(), "step", "any")
|
||||
}
|
||||
|
||||
case TimePickerValue:
|
||||
value := GetNumberPickerValue(view)
|
||||
view.Session().callFunc("setInputValue", view.htmlID(), value)
|
||||
case NumberPickerValue:
|
||||
value := GetNumberPickerValue(picker)
|
||||
format := picker.numberFormat()
|
||||
picker.Session().callFunc("setInputValue", picker.htmlID(), fmt.Sprintf(format, value))
|
||||
|
||||
if listeners := GetNumberChangedListeners(view); len(listeners) > 0 {
|
||||
if listeners := GetNumberChangedListeners(picker); len(listeners) > 0 {
|
||||
old := 0.0
|
||||
if val := view.getRaw("old-number"); val != nil {
|
||||
if val := picker.getRaw("old-number"); val != nil {
|
||||
if n, ok := val.(float64); ok {
|
||||
old = n
|
||||
}
|
||||
}
|
||||
for _, listener := range listeners {
|
||||
listener(view, value, old)
|
||||
if old != value {
|
||||
for _, listener := range listeners {
|
||||
listener(picker, value, old)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
viewPropertyChanged(view, tag)
|
||||
picker.viewData.propertyChanged(tag)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -217,30 +238,31 @@ func (picker *numberPickerData) htmlProperties(self View, buffer *strings.Builde
|
|||
buffer.WriteString(` type="number"`)
|
||||
}
|
||||
|
||||
format := picker.numberFormat()
|
||||
min, max := GetNumberPickerMinMax(picker)
|
||||
if min != math.Inf(-1) {
|
||||
buffer.WriteString(` min="`)
|
||||
buffer.WriteString(strconv.FormatFloat(min, 'f', -1, 64))
|
||||
buffer.WriteString(fmt.Sprintf(format, min))
|
||||
buffer.WriteByte('"')
|
||||
}
|
||||
|
||||
if max != math.Inf(1) {
|
||||
buffer.WriteString(` max="`)
|
||||
buffer.WriteString(strconv.FormatFloat(max, 'f', -1, 64))
|
||||
buffer.WriteString(fmt.Sprintf(format, max))
|
||||
buffer.WriteByte('"')
|
||||
}
|
||||
|
||||
step := GetNumberPickerStep(picker)
|
||||
if step != 0 {
|
||||
buffer.WriteString(` step="`)
|
||||
buffer.WriteString(strconv.FormatFloat(step, 'f', -1, 64))
|
||||
buffer.WriteString(fmt.Sprintf(format, step))
|
||||
buffer.WriteByte('"')
|
||||
} else {
|
||||
buffer.WriteString(` step="any"`)
|
||||
}
|
||||
|
||||
buffer.WriteString(` value="`)
|
||||
buffer.WriteString(strconv.FormatFloat(GetNumberPickerValue(picker), 'f', -1, 64))
|
||||
buffer.WriteString(fmt.Sprintf(format, GetNumberPickerValue(picker)))
|
||||
buffer.WriteByte('"')
|
||||
|
||||
buffer.WriteString(` oninput="editViewInputEvent(this)"`)
|
||||
|
@ -342,5 +364,11 @@ func GetNumberPickerValue(view View, subviewID ...string) float64 {
|
|||
// 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 GetNumberChangedListeners(view View, subviewID ...string) []func(NumberPicker, float64, float64) {
|
||||
return getEventWithOldListeners[NumberPicker, float64](view, subviewID, NumberChangedEvent)
|
||||
return getTwoArgEventListeners[NumberPicker, float64](view, subviewID, NumberChangedEvent)
|
||||
}
|
||||
|
||||
// GetNumberPickerPrecision returns the precision of displaying fractional part in editor of NumberPicker subview.
|
||||
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is returned.
|
||||
func GetNumberPickerPrecision(view View, subviewID ...string) int {
|
||||
return intStyledProperty(view, subviewID, NumberPickerPrecision, 0)
|
||||
}
|
||||
|
|
|
@ -156,7 +156,7 @@ type PointerEvent struct {
|
|||
|
||||
/*
|
||||
func setPointerListener(properties Properties, tag PropertyName, value any) bool {
|
||||
if listeners, ok := valueToEventListeners[View, PointerEvent](value); ok {
|
||||
if listeners, ok := valueToOneArgEventListeners[View, PointerEvent](value); ok {
|
||||
if len(listeners) == 0 {
|
||||
properties.setRaw(tag, nil)
|
||||
} else {
|
||||
|
@ -210,7 +210,7 @@ func (event *PointerEvent) init(data DataObject) {
|
|||
}
|
||||
|
||||
func handlePointerEvents(view View, tag PropertyName, data DataObject) {
|
||||
listeners := getEventListeners[View, PointerEvent](view, nil, tag)
|
||||
listeners := getOneArgEventListeners[View, PointerEvent](view, nil, tag)
|
||||
if len(listeners) == 0 {
|
||||
return
|
||||
}
|
||||
|
@ -226,35 +226,35 @@ func handlePointerEvents(view View, tag PropertyName, data DataObject) {
|
|||
// GetPointerDownListeners returns the "pointer-down" listener list. 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 GetPointerDownListeners(view View, subviewID ...string) []func(View, PointerEvent) {
|
||||
return getEventListeners[View, PointerEvent](view, subviewID, PointerDown)
|
||||
return getOneArgEventListeners[View, PointerEvent](view, subviewID, PointerDown)
|
||||
}
|
||||
|
||||
// GetPointerUpListeners returns the "pointer-up" listener list. 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 GetPointerUpListeners(view View, subviewID ...string) []func(View, PointerEvent) {
|
||||
return getEventListeners[View, PointerEvent](view, subviewID, PointerUp)
|
||||
return getOneArgEventListeners[View, PointerEvent](view, subviewID, PointerUp)
|
||||
}
|
||||
|
||||
// GetPointerMoveListeners returns the "pointer-move" listener list. 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 GetPointerMoveListeners(view View, subviewID ...string) []func(View, PointerEvent) {
|
||||
return getEventListeners[View, PointerEvent](view, subviewID, PointerMove)
|
||||
return getOneArgEventListeners[View, PointerEvent](view, subviewID, PointerMove)
|
||||
}
|
||||
|
||||
// GetPointerCancelListeners returns the "pointer-cancel" listener list. 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 GetPointerCancelListeners(view View, subviewID ...string) []func(View, PointerEvent) {
|
||||
return getEventListeners[View, PointerEvent](view, subviewID, PointerCancel)
|
||||
return getOneArgEventListeners[View, PointerEvent](view, subviewID, PointerCancel)
|
||||
}
|
||||
|
||||
// GetPointerOverListeners returns the "pointer-over" listener list. 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 GetPointerOverListeners(view View, subviewID ...string) []func(View, PointerEvent) {
|
||||
return getEventListeners[View, PointerEvent](view, subviewID, PointerOver)
|
||||
return getOneArgEventListeners[View, PointerEvent](view, subviewID, PointerOver)
|
||||
}
|
||||
|
||||
// GetPointerOutListeners returns the "pointer-out" listener list. 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 GetPointerOutListeners(view View, subviewID ...string) []func(View, PointerEvent) {
|
||||
return getEventListeners[View, PointerEvent](view, subviewID, PointerOut)
|
||||
return getOneArgEventListeners[View, PointerEvent](view, subviewID, PointerOut)
|
||||
}
|
||||
|
|
2
popup.go
2
popup.go
|
@ -560,7 +560,7 @@ func (popup *popupData) init(view View, popupParams Params) {
|
|||
}
|
||||
|
||||
case DismissEvent:
|
||||
if listeners, ok := valueToNoParamListeners[Popup](value); ok {
|
||||
if listeners, ok := valueToNoArgEventListeners[Popup](value); ok {
|
||||
if listeners != nil {
|
||||
popup.dismissListener = listeners
|
||||
}
|
||||
|
|
|
@ -53,7 +53,7 @@ func (progress *progressBarData) init(session Session) {
|
|||
progress.viewData.init(session)
|
||||
progress.tag = "ProgressBar"
|
||||
progress.normalize = normalizeProgressBarTag
|
||||
progress.changed = progressBarPropertyChanged
|
||||
progress.changed = progress.propertyChanged
|
||||
}
|
||||
|
||||
func normalizeProgressBarTag(tag PropertyName) PropertyName {
|
||||
|
@ -68,19 +68,19 @@ func normalizeProgressBarTag(tag PropertyName) PropertyName {
|
|||
return tag
|
||||
}
|
||||
|
||||
func progressBarPropertyChanged(view View, tag PropertyName) {
|
||||
func (progress *progressBarData) propertyChanged(tag PropertyName) {
|
||||
|
||||
switch tag {
|
||||
case ProgressBarMax:
|
||||
view.Session().updateProperty(view.htmlID(), "max",
|
||||
strconv.FormatFloat(GetProgressBarMax(view), 'f', -1, 32))
|
||||
progress.Session().updateProperty(progress.htmlID(), "max",
|
||||
strconv.FormatFloat(GetProgressBarMax(progress), 'f', -1, 32))
|
||||
|
||||
case ProgressBarValue:
|
||||
view.Session().updateProperty(view.htmlID(), "value",
|
||||
strconv.FormatFloat(GetProgressBarValue(view), 'f', -1, 32))
|
||||
progress.Session().updateProperty(progress.htmlID(), "value",
|
||||
strconv.FormatFloat(GetProgressBarValue(progress), 'f', -1, 32))
|
||||
|
||||
default:
|
||||
viewPropertyChanged(view, tag)
|
||||
progress.viewData.propertyChanged(tag)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@ var colorProperties = []PropertyName{
|
|||
OutlineColor,
|
||||
TextLineColor,
|
||||
ColorPickerValue,
|
||||
AccentColor,
|
||||
}
|
||||
|
||||
func isPropertyInList(tag PropertyName, list []PropertyName) bool {
|
||||
|
@ -74,6 +75,7 @@ var intProperties = []PropertyName{
|
|||
Order,
|
||||
TabIndex,
|
||||
MaxLength,
|
||||
NumberPickerPrecision,
|
||||
}
|
||||
|
||||
var floatProperties = map[PropertyName]struct{ min, max float64 }{
|
||||
|
@ -136,9 +138,9 @@ var sizeProperties = map[PropertyName]string{
|
|||
Perspective: string(Perspective),
|
||||
PerspectiveOriginX: string(PerspectiveOriginX),
|
||||
PerspectiveOriginY: string(PerspectiveOriginY),
|
||||
OriginX: string(OriginX),
|
||||
OriginY: string(OriginY),
|
||||
OriginZ: string(OriginZ),
|
||||
TransformOriginX: string(TransformOriginX),
|
||||
TransformOriginY: string(TransformOriginY),
|
||||
TransformOriginZ: string(TransformOriginZ),
|
||||
Radius: string(Radius),
|
||||
RadiusX: string(RadiusX),
|
||||
RadiusY: string(RadiusY),
|
||||
|
|
32
resizable.go
32
resizable.go
|
@ -80,8 +80,8 @@ func (resizable *resizableData) init(session Session) {
|
|||
resizable.viewData.init(session)
|
||||
resizable.tag = "Resizable"
|
||||
resizable.systemClass = "ruiGridLayout"
|
||||
resizable.set = resizableSet
|
||||
resizable.changed = resizablePropertyChanged
|
||||
resizable.set = resizable.setFunc
|
||||
resizable.changed = resizable.propertyChanged
|
||||
}
|
||||
|
||||
func (resizable *resizableData) Views() []View {
|
||||
|
@ -100,25 +100,25 @@ func (resizable *resizableData) content() View {
|
|||
return nil
|
||||
}
|
||||
|
||||
func resizableSet(view View, tag PropertyName, value any) []PropertyName {
|
||||
func (resizable *resizableData) setFunc(tag PropertyName, value any) []PropertyName {
|
||||
switch tag {
|
||||
case Side:
|
||||
return resizableSetSide(view, value)
|
||||
return resizableSetSide(resizable, value)
|
||||
|
||||
case ResizeBorderWidth:
|
||||
return setSizeProperty(view, tag, value)
|
||||
return setSizeProperty(resizable, tag, value)
|
||||
|
||||
case Content:
|
||||
var newContent View = nil
|
||||
switch value := value.(type) {
|
||||
case string:
|
||||
newContent = NewTextView(view.Session(), Params{Text: value})
|
||||
newContent = NewTextView(resizable.Session(), Params{Text: value})
|
||||
|
||||
case View:
|
||||
newContent = value
|
||||
|
||||
case DataObject:
|
||||
if newContent = CreateViewFromObject(view.Session(), value); newContent == nil {
|
||||
if newContent = CreateViewFromObject(resizable.Session(), value); newContent == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -127,7 +127,7 @@ func resizableSet(view View, tag PropertyName, value any) []PropertyName {
|
|||
return nil
|
||||
}
|
||||
|
||||
view.setRaw(Content, newContent)
|
||||
resizable.setRaw(Content, newContent)
|
||||
return []PropertyName{}
|
||||
|
||||
case CellWidth, CellHeight, GridRowGap, GridColumnGap, CellVerticalAlign, CellHorizontalAlign:
|
||||
|
@ -135,28 +135,28 @@ func resizableSet(view View, tag PropertyName, value any) []PropertyName {
|
|||
return nil
|
||||
}
|
||||
|
||||
return viewSet(view, tag, value)
|
||||
return resizable.viewData.setFunc(tag, value)
|
||||
}
|
||||
|
||||
func resizablePropertyChanged(view View, tag PropertyName) {
|
||||
func (resizable *resizableData) propertyChanged(tag PropertyName) {
|
||||
switch tag {
|
||||
case Side:
|
||||
updateInnerHTML(view.htmlID(), view.Session())
|
||||
updateInnerHTML(resizable.htmlID(), resizable.Session())
|
||||
fallthrough
|
||||
|
||||
case ResizeBorderWidth:
|
||||
htmlID := view.htmlID()
|
||||
session := view.Session()
|
||||
column, row := resizableCellSizeCSS(view)
|
||||
htmlID := resizable.htmlID()
|
||||
session := resizable.Session()
|
||||
column, row := resizableCellSizeCSS(resizable)
|
||||
|
||||
session.updateCSSProperty(htmlID, "grid-template-columns", column)
|
||||
session.updateCSSProperty(htmlID, "grid-template-rows", row)
|
||||
|
||||
case Content:
|
||||
updateInnerHTML(view.htmlID(), view.Session())
|
||||
updateInnerHTML(resizable.htmlID(), resizable.Session())
|
||||
|
||||
default:
|
||||
viewPropertyChanged(view, tag)
|
||||
resizable.viewData.propertyChanged(tag)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -33,7 +33,7 @@ func (view *viewData) onItemResize(self View, index string, x, y, width, height
|
|||
|
||||
/*
|
||||
func setFrameListener(properties Properties, tag PropertyName, value any) bool {
|
||||
if listeners, ok := valueToEventListeners[View, Frame](value); ok {
|
||||
if listeners, ok := valueToOneArgEventListeners[View, Frame](value); ok {
|
||||
if len(listeners) == 0 {
|
||||
properties.setRaw(tag, nil)
|
||||
} else {
|
||||
|
@ -85,5 +85,5 @@ func GetViewFrame(view View, subviewID ...string) Frame {
|
|||
// GetResizeListeners returns the list of "resize-event" listeners. If there are no listeners then the empty list is returned
|
||||
// If the second argument (subviewID) is not specified or it is "" then the listeners list of the first argument (view) is returned
|
||||
func GetResizeListeners(view View, subviewID ...string) []func(View, Frame) {
|
||||
return getEventListeners[View, Frame](view, subviewID, ResizeEvent)
|
||||
return getOneArgEventListeners[View, Frame](view, subviewID, ResizeEvent)
|
||||
}
|
||||
|
|
|
@ -54,7 +54,7 @@ func GetViewScroll(view View, subviewID ...string) Frame {
|
|||
// GetScrollListeners returns the list of "scroll-event" listeners. If there are no listeners then the empty list is returned
|
||||
// If the second argument (subviewID) is not specified or it is "" then the listeners list of the first argument (view) is returned
|
||||
func GetScrollListeners(view View, subviewID ...string) []func(View, Frame) {
|
||||
return getEventListeners[View, Frame](view, subviewID, ResizeEvent)
|
||||
return getOneArgEventListeners[View, Frame](view, subviewID, ResizeEvent)
|
||||
}
|
||||
|
||||
// ScrollTo scrolls the view's content to the given position.
|
||||
|
|
|
@ -81,9 +81,10 @@ func (layout *stackLayoutData) init(session Session) {
|
|||
layout.tag = "StackLayout"
|
||||
layout.systemClass = "ruiStackLayout"
|
||||
layout.properties[TransitionEndEvent] = []func(View, string){layout.pushFinished, layout.popFinished}
|
||||
layout.getFunc = layout.get
|
||||
layout.get = layout.getFunc
|
||||
layout.set = layout.setFunc
|
||||
layout.remove = layout.removeFunc
|
||||
layout.changed = layout.propertyChanged
|
||||
}
|
||||
|
||||
func (layout *stackLayoutData) pushFinished(view View, tag string) {
|
||||
|
@ -121,14 +122,14 @@ func (layout *stackLayoutData) popFinished(view View, tag string) {
|
|||
}
|
||||
}
|
||||
|
||||
func (layout *stackLayoutData) setFunc(view View, tag PropertyName, value any) []PropertyName {
|
||||
func (layout *stackLayoutData) setFunc(tag PropertyName, value any) []PropertyName {
|
||||
switch tag {
|
||||
case TransitionEndEvent:
|
||||
listeners, ok := valueToEventListeners[View, string](value)
|
||||
listeners, ok := valueToOneArgEventListeners[View, string](value)
|
||||
if ok && listeners != nil {
|
||||
listeners = append(listeners, layout.pushFinished)
|
||||
listeners = append(listeners, layout.popFinished)
|
||||
view.setRaw(TransitionEndEvent, listeners)
|
||||
layout.setRaw(TransitionEndEvent, listeners)
|
||||
return []PropertyName{tag}
|
||||
}
|
||||
return nil
|
||||
|
@ -170,42 +171,42 @@ func (layout *stackLayoutData) setFunc(view View, tag PropertyName, value any) [
|
|||
layout.peek = newCurrent
|
||||
return []PropertyName{tag}
|
||||
}
|
||||
return layout.viewsContainerData.setFunc(view, tag, value)
|
||||
return layout.viewsContainerData.setFunc(tag, value)
|
||||
}
|
||||
|
||||
func (layout *stackLayoutData) propertyChanged(view View, tag PropertyName) {
|
||||
func (layout *stackLayoutData) propertyChanged(tag PropertyName) {
|
||||
switch tag {
|
||||
case Current:
|
||||
if layout.prevPeek != layout.peek {
|
||||
if layout.prevPeek < len(layout.views) {
|
||||
layout.Session().updateCSSProperty(layout.htmlID()+"page"+strconv.Itoa(layout.prevPeek), "visibility", "hidden")
|
||||
}
|
||||
layout.Session().updateCSSProperty(layout.htmlID()+"page"+strconv.Itoa(layout.prevPeek), "visibility", "visible")
|
||||
layout.Session().updateCSSProperty(layout.htmlID()+"page"+strconv.Itoa(layout.peek), "visibility", "visible")
|
||||
layout.prevPeek = layout.peek
|
||||
}
|
||||
default:
|
||||
viewsContainerPropertyChanged(view, tag)
|
||||
layout.viewsContainerData.propertyChanged(tag)
|
||||
}
|
||||
}
|
||||
|
||||
func (layout *stackLayoutData) removeFunc(view View, tag PropertyName) []PropertyName {
|
||||
func (layout *stackLayoutData) removeFunc(tag PropertyName) []PropertyName {
|
||||
switch tag {
|
||||
case TransitionEndEvent:
|
||||
view.setRaw(TransitionEndEvent, []func(View, string){layout.pushFinished, layout.popFinished})
|
||||
layout.setRaw(TransitionEndEvent, []func(View, string){layout.pushFinished, layout.popFinished})
|
||||
return []PropertyName{tag}
|
||||
|
||||
case Current:
|
||||
view.setRaw(Current, 0)
|
||||
layout.setRaw(Current, 0)
|
||||
return []PropertyName{tag}
|
||||
}
|
||||
return layout.viewsContainerData.removeFunc(view, tag)
|
||||
return layout.viewsContainerData.removeFunc(tag)
|
||||
}
|
||||
|
||||
func (layout *stackLayoutData) get(view View, tag PropertyName) any {
|
||||
func (layout *stackLayoutData) getFunc(tag PropertyName) any {
|
||||
if tag == Current {
|
||||
return layout.peek
|
||||
}
|
||||
return layout.viewsContainerData.get(view, tag)
|
||||
return layout.viewsContainerData.getFunc(tag)
|
||||
}
|
||||
|
||||
func (layout *stackLayoutData) Peek() View {
|
||||
|
|
|
@ -34,8 +34,8 @@ func (imageView *svgImageViewData) init(session Session) {
|
|||
imageView.tag = "SvgImageView"
|
||||
imageView.systemClass = "ruiSvgImageView"
|
||||
imageView.normalize = normalizeSvgImageViewTag
|
||||
imageView.set = svgImageViewSet
|
||||
imageView.changed = svgImageViewPropertyChanged
|
||||
imageView.set = imageView.setFunc
|
||||
imageView.changed = imageView.propertyChanged
|
||||
|
||||
}
|
||||
|
||||
|
@ -54,28 +54,28 @@ func normalizeSvgImageViewTag(tag PropertyName) PropertyName {
|
|||
return tag
|
||||
}
|
||||
|
||||
func svgImageViewSet(view View, tag PropertyName, value any) []PropertyName {
|
||||
func (imageView *svgImageViewData) setFunc(tag PropertyName, value any) []PropertyName {
|
||||
switch tag {
|
||||
case Content:
|
||||
if text, ok := value.(string); ok {
|
||||
view.setRaw(Content, text)
|
||||
imageView.setRaw(Content, text)
|
||||
return []PropertyName{tag}
|
||||
}
|
||||
notCompatibleType(Source, value)
|
||||
return nil
|
||||
|
||||
default:
|
||||
return viewSet(view, tag, value)
|
||||
return imageView.viewData.setFunc(tag, value)
|
||||
}
|
||||
}
|
||||
|
||||
func svgImageViewPropertyChanged(view View, tag PropertyName) {
|
||||
func (imageView *svgImageViewData) propertyChanged(tag PropertyName) {
|
||||
switch tag {
|
||||
case Content:
|
||||
updateInnerHTML(view.htmlID(), view.Session())
|
||||
updateInnerHTML(imageView.htmlID(), imageView.Session())
|
||||
|
||||
default:
|
||||
viewPropertyChanged(view, tag)
|
||||
imageView.viewData.propertyChanged(tag)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
98
tableView.go
98
tableView.go
|
@ -593,8 +593,8 @@ func (table *tableViewData) init(session Session) {
|
|||
table.current.Column = -1
|
||||
*/
|
||||
table.normalize = normalizeTableViewTag
|
||||
table.set = tableViewSet
|
||||
table.changed = tableViewPropertyChanged
|
||||
table.set = table.setFunc
|
||||
table.changed = table.propertyChanged
|
||||
}
|
||||
|
||||
func normalizeTableViewTag(tag PropertyName) PropertyName {
|
||||
|
@ -618,7 +618,7 @@ func (table *tableViewData) Focusable() bool {
|
|||
return GetTableSelectionMode(table) != NoneSelection
|
||||
}
|
||||
|
||||
func tableViewSet(view View, tag PropertyName, value any) []PropertyName {
|
||||
func (table *tableViewData) setFunc(tag PropertyName, value any) []PropertyName {
|
||||
|
||||
setLineStyle := func() []PropertyName {
|
||||
params := []Params{}
|
||||
|
@ -637,9 +637,9 @@ func tableViewSet(view View, tag PropertyName, value any) []PropertyName {
|
|||
if len(params) > 0 {
|
||||
style := new(simpleTableLineStyle)
|
||||
style.params = params
|
||||
view.setRaw(tag, style)
|
||||
} else if view.getRaw(tag) != nil {
|
||||
view.setRaw(tag, nil)
|
||||
table.setRaw(tag, style)
|
||||
} else if table.getRaw(tag) != nil {
|
||||
table.setRaw(tag, nil)
|
||||
} else {
|
||||
return []PropertyName{}
|
||||
}
|
||||
|
@ -650,13 +650,13 @@ func tableViewSet(view View, tag PropertyName, value any) []PropertyName {
|
|||
case Content:
|
||||
switch val := value.(type) {
|
||||
case TableAdapter:
|
||||
view.setRaw(Content, value)
|
||||
table.setRaw(Content, value)
|
||||
|
||||
case [][]any:
|
||||
view.setRaw(Content, NewSimpleTableAdapter(val))
|
||||
table.setRaw(Content, NewSimpleTableAdapter(val))
|
||||
|
||||
case [][]string:
|
||||
view.setRaw(Content, NewTextTableAdapter(val))
|
||||
table.setRaw(Content, NewTextTableAdapter(val))
|
||||
|
||||
default:
|
||||
notCompatibleType(tag, value)
|
||||
|
@ -665,14 +665,14 @@ func tableViewSet(view View, tag PropertyName, value any) []PropertyName {
|
|||
return []PropertyName{tag}
|
||||
|
||||
case TableCellClickedEvent, TableCellSelectedEvent:
|
||||
return setEventWithOldListener[TableView, int](view, tag, value)
|
||||
return setTwoArgEventListener[TableView, int](table, tag, value)
|
||||
|
||||
case TableRowClickedEvent, TableRowSelectedEvent:
|
||||
return setViewEventListener[TableView, int](view, tag, value)
|
||||
return setOneArgEventListener[TableView, int](table, tag, value)
|
||||
|
||||
case CellStyle:
|
||||
if style, ok := value.(TableCellStyle); ok {
|
||||
view.setRaw(tag, style)
|
||||
table.setRaw(tag, style)
|
||||
return []PropertyName{tag}
|
||||
}
|
||||
notCompatibleType(tag, value)
|
||||
|
@ -680,14 +680,14 @@ func tableViewSet(view View, tag PropertyName, value any) []PropertyName {
|
|||
|
||||
case RowStyle:
|
||||
if style, ok := value.(TableRowStyle); ok {
|
||||
view.setRaw(tag, style)
|
||||
table.setRaw(tag, style)
|
||||
return []PropertyName{tag}
|
||||
}
|
||||
return setLineStyle()
|
||||
|
||||
case ColumnStyle:
|
||||
if style, ok := value.(TableColumnStyle); ok {
|
||||
view.setRaw(tag, style)
|
||||
table.setRaw(tag, style)
|
||||
return []PropertyName{tag}
|
||||
}
|
||||
return setLineStyle()
|
||||
|
@ -696,9 +696,9 @@ func tableViewSet(view View, tag PropertyName, value any) []PropertyName {
|
|||
switch value := value.(type) {
|
||||
case string:
|
||||
if isConstantName(value) {
|
||||
view.setRaw(tag, value)
|
||||
table.setRaw(tag, value)
|
||||
} else if n, err := strconv.Atoi(value); err == nil {
|
||||
view.setRaw(tag, n)
|
||||
table.setRaw(tag, n)
|
||||
} else {
|
||||
ErrorLog(err.Error())
|
||||
notCompatibleType(tag, value)
|
||||
|
@ -707,7 +707,7 @@ func tableViewSet(view View, tag PropertyName, value any) []PropertyName {
|
|||
|
||||
default:
|
||||
if n, ok := isInt(value); ok {
|
||||
view.setRaw(tag, n)
|
||||
table.setRaw(tag, n)
|
||||
} else {
|
||||
notCompatibleType(tag, value)
|
||||
return nil
|
||||
|
@ -718,13 +718,13 @@ func tableViewSet(view View, tag PropertyName, value any) []PropertyName {
|
|||
case HeadStyle, FootStyle:
|
||||
switch value := value.(type) {
|
||||
case string:
|
||||
view.setRaw(tag, value)
|
||||
table.setRaw(tag, value)
|
||||
|
||||
case Params:
|
||||
if len(value) > 0 {
|
||||
view.setRaw(tag, value)
|
||||
} else if view.getRaw(tag) != nil {
|
||||
view.setRaw(tag, nil)
|
||||
table.setRaw(tag, value)
|
||||
} else if table.getRaw(tag) != nil {
|
||||
table.setRaw(tag, nil)
|
||||
} else {
|
||||
return []PropertyName{}
|
||||
}
|
||||
|
@ -736,15 +736,15 @@ func tableViewSet(view View, tag PropertyName, value any) []PropertyName {
|
|||
params[PropertyName(prop.Tag())] = prop.Text()
|
||||
}
|
||||
}
|
||||
return tableViewSet(view, tag, params)
|
||||
return table.setFunc(tag, params)
|
||||
|
||||
case DataNode:
|
||||
switch value.Type() {
|
||||
case ObjectNode:
|
||||
return tableViewSet(view, tag, value.Object())
|
||||
return table.setFunc(tag, value.Object())
|
||||
|
||||
case TextNode:
|
||||
view.setRaw(tag, value.Text())
|
||||
table.setRaw(tag, value.Text())
|
||||
|
||||
default:
|
||||
notCompatibleType(tag, value)
|
||||
|
@ -760,10 +760,10 @@ func tableViewSet(view View, tag PropertyName, value any) []PropertyName {
|
|||
case AllowSelection:
|
||||
switch value.(type) {
|
||||
case TableAllowCellSelection:
|
||||
view.setRaw(tag, value)
|
||||
table.setRaw(tag, value)
|
||||
|
||||
case TableAllowRowSelection:
|
||||
view.setRaw(tag, value)
|
||||
table.setRaw(tag, value)
|
||||
|
||||
default:
|
||||
notCompatibleType(tag, value)
|
||||
|
@ -819,17 +819,17 @@ func tableViewSet(view View, tag PropertyName, value any) []PropertyName {
|
|||
return nil
|
||||
}
|
||||
}
|
||||
view.setRaw(Current, current)
|
||||
table.setRaw(Current, current)
|
||||
return []PropertyName{tag}
|
||||
}
|
||||
|
||||
return viewSet(view, tag, value)
|
||||
return table.viewData.setFunc(tag, value)
|
||||
}
|
||||
|
||||
func tableViewPropertyChanged(view View, tag PropertyName) {
|
||||
func (table *tableViewData) propertyChanged(tag PropertyName) {
|
||||
|
||||
htmlID := view.htmlID()
|
||||
session := view.Session()
|
||||
htmlID := table.htmlID()
|
||||
session := table.Session()
|
||||
|
||||
switch tag {
|
||||
case Content, TableVerticalAlign, RowStyle, ColumnStyle, CellStyle, CellPadding,
|
||||
|
@ -837,20 +837,20 @@ func tableViewPropertyChanged(view View, tag PropertyName) {
|
|||
CellPaddingTop, CellPaddingRight, CellPaddingBottom, CellPaddingLeft,
|
||||
TableCellClickedEvent, TableCellSelectedEvent, TableRowClickedEvent,
|
||||
TableRowSelectedEvent, AllowSelection, AccentColor:
|
||||
ReloadTableViewData(view)
|
||||
ReloadTableViewData(table)
|
||||
|
||||
case Current:
|
||||
switch GetTableSelectionMode(view) {
|
||||
switch GetTableSelectionMode(table) {
|
||||
case CellSelection:
|
||||
current := tableViewCurrent(view)
|
||||
current := tableViewCurrent(table)
|
||||
session.callFunc("setTableCellCursorByID", htmlID, current.Row, current.Column)
|
||||
|
||||
case RowSelection:
|
||||
session.callFunc("setTableRowCursorByID", htmlID, tableViewCurrent(view).Row)
|
||||
session.callFunc("setTableRowCursorByID", htmlID, tableViewCurrent(table).Row)
|
||||
}
|
||||
|
||||
case Gap:
|
||||
gap, ok := sizeProperty(view, Gap, session)
|
||||
gap, ok := sizeProperty(table, Gap, session)
|
||||
if !ok || gap.Type == Auto || gap.Value <= 0 {
|
||||
session.updateCSSProperty(htmlID, "border-spacing", "0")
|
||||
session.updateCSSProperty(htmlID, "border-collapse", "collapse")
|
||||
|
@ -860,43 +860,43 @@ func tableViewPropertyChanged(view View, tag PropertyName) {
|
|||
}
|
||||
|
||||
case SelectionMode:
|
||||
switch GetTableSelectionMode(view) {
|
||||
switch GetTableSelectionMode(table) {
|
||||
case CellSelection:
|
||||
tabIndex, _ := intProperty(view, TabIndex, session, 0)
|
||||
tabIndex, _ := intProperty(table, TabIndex, session, 0)
|
||||
session.updateProperty(htmlID, "tabindex", tabIndex)
|
||||
session.updateProperty(htmlID, "onfocus", "tableViewFocusEvent(this, event)")
|
||||
session.updateProperty(htmlID, "onblur", "tableViewBlurEvent(this, event)")
|
||||
session.updateProperty(htmlID, "data-selection", "cell")
|
||||
session.updateProperty(htmlID, "data-focusitemstyle", tableViewCurrentStyle(view))
|
||||
session.updateProperty(htmlID, "data-bluritemstyle", tableViewCurrentInactiveStyle(view))
|
||||
session.updateProperty(htmlID, "data-focusitemstyle", tableViewCurrentStyle(table))
|
||||
session.updateProperty(htmlID, "data-bluritemstyle", tableViewCurrentInactiveStyle(table))
|
||||
|
||||
current := tableViewCurrent(view)
|
||||
current := tableViewCurrent(table)
|
||||
if current.Row >= 0 && current.Column >= 0 {
|
||||
session.updateProperty(htmlID, "data-current", tableViewCellID(view, current.Row, current.Column))
|
||||
session.updateProperty(htmlID, "data-current", tableViewCellID(table, current.Row, current.Column))
|
||||
} else {
|
||||
session.removeProperty(htmlID, "data-current")
|
||||
}
|
||||
session.updateProperty(htmlID, "onkeydown", "tableViewCellKeyDownEvent(this, event)")
|
||||
|
||||
case RowSelection:
|
||||
tabIndex, _ := intProperty(view, TabIndex, session, 0)
|
||||
tabIndex, _ := intProperty(table, TabIndex, session, 0)
|
||||
session.updateProperty(htmlID, "tabindex", tabIndex)
|
||||
session.updateProperty(htmlID, "onfocus", "tableViewFocusEvent(this, event)")
|
||||
session.updateProperty(htmlID, "onblur", "tableViewBlurEvent(this, event)")
|
||||
session.updateProperty(htmlID, "data-selection", "row")
|
||||
session.updateProperty(htmlID, "data-focusitemstyle", tableViewCurrentStyle(view))
|
||||
session.updateProperty(htmlID, "data-bluritemstyle", tableViewCurrentInactiveStyle(view))
|
||||
session.updateProperty(htmlID, "data-focusitemstyle", tableViewCurrentStyle(table))
|
||||
session.updateProperty(htmlID, "data-bluritemstyle", tableViewCurrentInactiveStyle(table))
|
||||
|
||||
current := tableViewCurrent(view)
|
||||
current := tableViewCurrent(table)
|
||||
if current.Row >= 0 {
|
||||
session.updateProperty(htmlID, "data-current", tableViewRowID(view, current.Row))
|
||||
session.updateProperty(htmlID, "data-current", tableViewRowID(table, current.Row))
|
||||
} else {
|
||||
session.removeProperty(htmlID, "data-current")
|
||||
}
|
||||
session.updateProperty(htmlID, "onkeydown", "tableViewRowKeyDownEvent(this, event)")
|
||||
|
||||
default: // NoneSelection
|
||||
if tabIndex, ok := intProperty(view, TabIndex, session, -1); !ok || tabIndex < 0 {
|
||||
if tabIndex, ok := intProperty(table, TabIndex, session, -1); !ok || tabIndex < 0 {
|
||||
session.removeProperty(htmlID, "tabindex")
|
||||
}
|
||||
|
||||
|
@ -907,7 +907,7 @@ func tableViewPropertyChanged(view View, tag PropertyName) {
|
|||
updateInnerHTML(htmlID, session)
|
||||
|
||||
default:
|
||||
viewPropertyChanged(view, tag)
|
||||
table.viewData.propertyChanged(tag)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -152,28 +152,28 @@ func GetTableCurrent(view View, subviewID ...string) CellIndex {
|
|||
// 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 GetTableCellClickedListeners(view View, subviewID ...string) []func(TableView, int, int) {
|
||||
return getEventWithOldListeners[TableView, int](view, subviewID, TableCellClickedEvent)
|
||||
return getTwoArgEventListeners[TableView, int](view, subviewID, TableCellClickedEvent)
|
||||
}
|
||||
|
||||
// GetTableCellSelectedListeners returns listeners of event which occurs when a table cell becomes selected.
|
||||
// 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 GetTableCellSelectedListeners(view View, subviewID ...string) []func(TableView, int, int) {
|
||||
return getEventWithOldListeners[TableView, int](view, subviewID, TableCellSelectedEvent)
|
||||
return getTwoArgEventListeners[TableView, int](view, subviewID, TableCellSelectedEvent)
|
||||
}
|
||||
|
||||
// GetTableRowClickedListeners returns listeners of event which occurs when the user clicks on a table row.
|
||||
// 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 GetTableRowClickedListeners(view View, subviewID ...string) []func(TableView, int) {
|
||||
return getEventListeners[TableView, int](view, subviewID, TableRowClickedEvent)
|
||||
return getOneArgEventListeners[TableView, int](view, subviewID, TableRowClickedEvent)
|
||||
}
|
||||
|
||||
// GetTableRowSelectedListeners returns listeners of event which occurs when a table row becomes selected.
|
||||
// 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 GetTableRowSelectedListeners(view View, subviewID ...string) []func(TableView, int) {
|
||||
return getEventListeners[TableView, int](view, subviewID, TableRowSelectedEvent)
|
||||
return getOneArgEventListeners[TableView, int](view, subviewID, TableRowSelectedEvent)
|
||||
}
|
||||
|
||||
// ReloadTableViewData updates TableView
|
||||
|
|
|
@ -168,69 +168,69 @@ func tabsLayoutCurrent(view View, defaultValue int) int {
|
|||
return result
|
||||
}
|
||||
|
||||
func (tabsLayout *tabsLayoutData) setFunc(view View, tag PropertyName, value any) []PropertyName {
|
||||
func (tabsLayout *tabsLayoutData) setFunc(tag PropertyName, value any) []PropertyName {
|
||||
switch tag {
|
||||
case CurrentTabChangedEvent:
|
||||
return setEventWithOldListener[TabsLayout, int](view, tag, value)
|
||||
return setTwoArgEventListener[TabsLayout, int](tabsLayout, tag, value)
|
||||
|
||||
case TabCloseEvent:
|
||||
return setViewEventListener[TabsLayout, int](view, tag, value)
|
||||
return setOneArgEventListener[TabsLayout, int](tabsLayout, tag, value)
|
||||
|
||||
case Current:
|
||||
view.setRaw("old-current", tabsLayoutCurrent(view, -1))
|
||||
tabsLayout.setRaw("old-current", tabsLayoutCurrent(tabsLayout, -1))
|
||||
|
||||
if current, ok := value.(int); ok && current < 0 {
|
||||
view.setRaw(Current, nil)
|
||||
tabsLayout.setRaw(Current, nil)
|
||||
return []PropertyName{tag}
|
||||
}
|
||||
|
||||
return setIntProperty(view, Current, value)
|
||||
return setIntProperty(tabsLayout, Current, value)
|
||||
|
||||
case TabStyle, CurrentTabStyle, TabBarStyle:
|
||||
if text, ok := value.(string); ok {
|
||||
return setStringPropertyValue(view, tag, text)
|
||||
return setStringPropertyValue(tabsLayout, tag, text)
|
||||
}
|
||||
notCompatibleType(tag, value)
|
||||
return nil
|
||||
}
|
||||
|
||||
return tabsLayout.viewsContainerData.setFunc(tabsLayout, tag, value)
|
||||
return tabsLayout.viewsContainerData.setFunc(tag, value)
|
||||
}
|
||||
|
||||
func (tabsLayout *tabsLayoutData) propertyChanged(view View, tag PropertyName) {
|
||||
func (tabsLayout *tabsLayoutData) propertyChanged(tag PropertyName) {
|
||||
switch tag {
|
||||
case Current:
|
||||
session := view.Session()
|
||||
current := GetCurrent(view)
|
||||
session.callFunc("activateTab", view.htmlID(), current)
|
||||
session := tabsLayout.Session()
|
||||
current := GetCurrent(tabsLayout)
|
||||
session.callFunc("activateTab", tabsLayout.htmlID(), current)
|
||||
|
||||
if listeners := getEventWithOldListeners[TabsLayout, int](view, nil, CurrentTabChangedEvent); len(listeners) > 0 {
|
||||
oldCurrent, _ := intProperty(view, "old-current", session, -1)
|
||||
if listeners := getTwoArgEventListeners[TabsLayout, int](tabsLayout, nil, CurrentTabChangedEvent); len(listeners) > 0 {
|
||||
oldCurrent, _ := intProperty(tabsLayout, "old-current", session, -1)
|
||||
for _, listener := range listeners {
|
||||
listener(tabsLayout, current, oldCurrent)
|
||||
}
|
||||
}
|
||||
|
||||
case Tabs:
|
||||
htmlID := view.htmlID()
|
||||
session := view.Session()
|
||||
session.updateProperty(htmlID, inactiveTabStyle, tabsLayoutInactiveTabStyle(view))
|
||||
session.updateProperty(htmlID, activeTabStyle, tabsLayoutActiveTabStyle(view))
|
||||
htmlID := tabsLayout.htmlID()
|
||||
session := tabsLayout.Session()
|
||||
session.updateProperty(htmlID, inactiveTabStyle, tabsLayoutInactiveTabStyle(tabsLayout))
|
||||
session.updateProperty(htmlID, activeTabStyle, tabsLayoutActiveTabStyle(tabsLayout))
|
||||
updateCSSStyle(htmlID, session)
|
||||
updateInnerHTML(htmlID, session)
|
||||
|
||||
case TabStyle, CurrentTabStyle, TabBarStyle:
|
||||
htmlID := view.htmlID()
|
||||
session := view.Session()
|
||||
session.updateProperty(htmlID, inactiveTabStyle, tabsLayoutInactiveTabStyle(view))
|
||||
session.updateProperty(htmlID, activeTabStyle, tabsLayoutActiveTabStyle(view))
|
||||
htmlID := tabsLayout.htmlID()
|
||||
session := tabsLayout.Session()
|
||||
session.updateProperty(htmlID, inactiveTabStyle, tabsLayoutInactiveTabStyle(tabsLayout))
|
||||
session.updateProperty(htmlID, activeTabStyle, tabsLayoutActiveTabStyle(tabsLayout))
|
||||
updateInnerHTML(htmlID, session)
|
||||
|
||||
case TabCloseButton:
|
||||
updateInnerHTML(view.htmlID(), view.Session())
|
||||
updateInnerHTML(tabsLayout.htmlID(), tabsLayout.Session())
|
||||
|
||||
default:
|
||||
viewsContainerPropertyChanged(view, tag)
|
||||
tabsLayout.viewsContainerData.propertyChanged(tag)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -499,7 +499,7 @@ func (tabsLayout *tabsLayoutData) ListItem(index int, session Session) View {
|
|||
Column: 2,
|
||||
Content: "✕",
|
||||
ClickEvent: func() {
|
||||
for _, listener := range getEventListeners[TabsLayout, int](tabsLayout, nil, TabCloseEvent) {
|
||||
for _, listener := range getOneArgEventListeners[TabsLayout, int](tabsLayout, nil, TabCloseEvent) {
|
||||
listener(tabsLayout, index)
|
||||
}
|
||||
},
|
||||
|
@ -565,7 +565,7 @@ func (tabsLayout *tabsLayoutData) Insert(view View, index int) {
|
|||
if view != nil {
|
||||
if current := GetCurrent(tabsLayout); current >= index {
|
||||
tabsLayout.setRaw(Current, current+1)
|
||||
defer tabsLayout.currentChanged()
|
||||
defer tabsLayout.currentChanged(current+1, current)
|
||||
}
|
||||
tabsLayout.viewsContainerData.Insert(view, index)
|
||||
view.SetChangeListener(Title, tabsLayout.updateTitle)
|
||||
|
@ -574,7 +574,10 @@ func (tabsLayout *tabsLayoutData) Insert(view View, index int) {
|
|||
}
|
||||
}
|
||||
|
||||
func (tabsLayout *tabsLayoutData) currentChanged() {
|
||||
func (tabsLayout *tabsLayoutData) currentChanged(newCurrent, oldCurrent int) {
|
||||
for _, listener := range getTwoArgEventListeners[TabsLayout, int](tabsLayout, nil, CurrentTabChangedEvent) {
|
||||
listener(tabsLayout, newCurrent, oldCurrent)
|
||||
}
|
||||
if listener, ok := tabsLayout.changeListener[Current]; ok {
|
||||
listener(tabsLayout, Current)
|
||||
}
|
||||
|
@ -600,7 +603,7 @@ func (tabsLayout *tabsLayoutData) RemoveView(index int) View {
|
|||
|
||||
if newCurrent != oldCurrent {
|
||||
tabsLayout.setRaw(Current, newCurrent)
|
||||
tabsLayout.currentChanged()
|
||||
tabsLayout.currentChanged(newCurrent, oldCurrent)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
|
@ -871,10 +874,8 @@ func (tabsLayout *tabsLayoutData) handleCommand(self View, command PropertyName,
|
|||
current := GetCurrent(tabsLayout)
|
||||
if current != number {
|
||||
tabsLayout.setRaw(Current, number)
|
||||
for _, listener := range getEventWithOldListeners[TabsLayout, int](tabsLayout, nil, CurrentTabChangedEvent) {
|
||||
listener(tabsLayout, number, current)
|
||||
}
|
||||
tabsLayout.currentChanged()
|
||||
|
||||
tabsLayout.currentChanged(number, current)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -883,7 +884,7 @@ func (tabsLayout *tabsLayoutData) handleCommand(self View, command PropertyName,
|
|||
case "tabCloseClick":
|
||||
if numberText, ok := data.PropertyValue("number"); ok {
|
||||
if number, err := strconv.Atoi(numberText); err == nil {
|
||||
for _, listener := range getEventListeners[TabsLayout, int](tabsLayout, nil, TabCloseEvent) {
|
||||
for _, listener := range getOneArgEventListeners[TabsLayout, int](tabsLayout, nil, TabCloseEvent) {
|
||||
listener(tabsLayout, number)
|
||||
}
|
||||
}
|
||||
|
|
40
textView.go
40
textView.go
|
@ -30,63 +30,63 @@ func newTextView(session Session) View {
|
|||
func (textView *textViewData) init(session Session) {
|
||||
textView.viewData.init(session)
|
||||
textView.tag = "TextView"
|
||||
textView.set = textViewSet
|
||||
textView.changed = textViewPropertyChanged
|
||||
textView.set = textView.setFunc
|
||||
textView.changed = textView.propertyChanged
|
||||
}
|
||||
|
||||
func textViewPropertyChanged(view View, tag PropertyName) {
|
||||
func (textView *textViewData) propertyChanged(tag PropertyName) {
|
||||
switch tag {
|
||||
case Text:
|
||||
updateInnerHTML(view.htmlID(), view.Session())
|
||||
updateInnerHTML(textView.htmlID(), textView.Session())
|
||||
|
||||
case TextOverflow:
|
||||
session := view.Session()
|
||||
if n, ok := enumProperty(view, TextOverflow, session, 0); ok {
|
||||
session := textView.Session()
|
||||
if n, ok := enumProperty(textView, TextOverflow, session, 0); ok {
|
||||
values := enumProperties[TextOverflow].cssValues
|
||||
if n >= 0 && n < len(values) {
|
||||
session.updateCSSProperty(view.htmlID(), string(TextOverflow), values[n])
|
||||
session.updateCSSProperty(textView.htmlID(), string(TextOverflow), values[n])
|
||||
return
|
||||
}
|
||||
}
|
||||
session.updateCSSProperty(view.htmlID(), string(TextOverflow), "")
|
||||
session.updateCSSProperty(textView.htmlID(), string(TextOverflow), "")
|
||||
|
||||
case NotTranslate:
|
||||
updateInnerHTML(view.htmlID(), view.Session())
|
||||
updateInnerHTML(textView.htmlID(), textView.Session())
|
||||
|
||||
default:
|
||||
viewPropertyChanged(view, tag)
|
||||
textView.viewData.propertyChanged(tag)
|
||||
}
|
||||
}
|
||||
|
||||
func textViewSet(view View, tag PropertyName, value any) []PropertyName {
|
||||
func (textView *textViewData) setFunc(tag PropertyName, value any) []PropertyName {
|
||||
switch tag {
|
||||
case Text:
|
||||
switch value := value.(type) {
|
||||
case string:
|
||||
view.setRaw(Text, value)
|
||||
textView.setRaw(Text, value)
|
||||
|
||||
case fmt.Stringer:
|
||||
view.setRaw(Text, value.String())
|
||||
textView.setRaw(Text, value.String())
|
||||
|
||||
case float32:
|
||||
view.setRaw(Text, fmt.Sprintf("%g", float64(value)))
|
||||
textView.setRaw(Text, fmt.Sprintf("%g", float64(value)))
|
||||
|
||||
case float64:
|
||||
view.setRaw(Text, fmt.Sprintf("%g", value))
|
||||
textView.setRaw(Text, fmt.Sprintf("%g", value))
|
||||
|
||||
case []rune:
|
||||
view.setRaw(Text, string(value))
|
||||
textView.setRaw(Text, string(value))
|
||||
|
||||
case bool:
|
||||
if value {
|
||||
view.setRaw(Text, "true")
|
||||
textView.setRaw(Text, "true")
|
||||
} else {
|
||||
view.setRaw(Text, "false")
|
||||
textView.setRaw(Text, "false")
|
||||
}
|
||||
|
||||
default:
|
||||
if n, ok := isInt(value); ok {
|
||||
view.setRaw(Text, fmt.Sprintf("%d", n))
|
||||
textView.setRaw(Text, fmt.Sprintf("%d", n))
|
||||
} else {
|
||||
notCompatibleType(tag, value)
|
||||
return nil
|
||||
|
@ -95,7 +95,7 @@ func textViewSet(view View, tag PropertyName, value any) []PropertyName {
|
|||
return []PropertyName{Text}
|
||||
}
|
||||
|
||||
return viewSet(view, tag, value)
|
||||
return textView.viewData.setFunc(tag, value)
|
||||
}
|
||||
|
||||
func (textView *textViewData) htmlSubviews(self View, buffer *strings.Builder) {
|
||||
|
|
|
@ -120,8 +120,8 @@ func (picker *timePickerData) init(session Session) {
|
|||
picker.tag = "TimePicker"
|
||||
picker.hasHtmlDisabled = true
|
||||
picker.normalize = normalizeTimePickerTag
|
||||
picker.set = timePickerSet
|
||||
picker.changed = timePickerPropertyChanged
|
||||
picker.set = picker.setFunc
|
||||
picker.changed = picker.propertyChanged
|
||||
}
|
||||
|
||||
func (picker *timePickerData) Focusable() bool {
|
||||
|
@ -167,22 +167,22 @@ func stringToTime(value string) (time.Time, bool) {
|
|||
return result, true
|
||||
}
|
||||
|
||||
func timePickerSet(view View, tag PropertyName, value any) []PropertyName {
|
||||
func (picker *timePickerData) setFunc(tag PropertyName, value any) []PropertyName {
|
||||
|
||||
setTimeValue := func(tag PropertyName) []PropertyName {
|
||||
switch value := value.(type) {
|
||||
case time.Time:
|
||||
view.setRaw(tag, value)
|
||||
picker.setRaw(tag, value)
|
||||
return []PropertyName{tag}
|
||||
|
||||
case string:
|
||||
if isConstantName(value) {
|
||||
view.setRaw(tag, value)
|
||||
picker.setRaw(tag, value)
|
||||
return []PropertyName{tag}
|
||||
}
|
||||
|
||||
if time, ok := stringToTime(value); ok {
|
||||
view.setRaw(tag, time)
|
||||
picker.setRaw(tag, time)
|
||||
return []PropertyName{tag}
|
||||
}
|
||||
}
|
||||
|
@ -199,67 +199,67 @@ func timePickerSet(view View, tag PropertyName, value any) []PropertyName {
|
|||
return setTimeValue(TimePickerMax)
|
||||
|
||||
case TimePickerStep:
|
||||
return setIntProperty(view, TimePickerStep, value)
|
||||
return setIntProperty(picker, TimePickerStep, value)
|
||||
|
||||
case TimePickerValue:
|
||||
view.setRaw("old-time", GetTimePickerValue(view))
|
||||
picker.setRaw("old-time", GetTimePickerValue(picker))
|
||||
return setTimeValue(tag)
|
||||
|
||||
case TimeChangedEvent:
|
||||
return setEventWithOldListener[TimePicker, time.Time](view, tag, value)
|
||||
return setTwoArgEventListener[TimePicker, time.Time](picker, tag, value)
|
||||
|
||||
case DataList:
|
||||
return setDataList(view, value, timeFormat)
|
||||
return setDataList(picker, value, timeFormat)
|
||||
}
|
||||
|
||||
return viewSet(view, tag, value)
|
||||
return picker.viewData.setFunc(tag, value)
|
||||
}
|
||||
|
||||
func timePickerPropertyChanged(view View, tag PropertyName) {
|
||||
func (picker *timePickerData) propertyChanged(tag PropertyName) {
|
||||
|
||||
session := view.Session()
|
||||
session := picker.Session()
|
||||
|
||||
switch tag {
|
||||
|
||||
case TimePickerMin:
|
||||
if time, ok := GetTimePickerMin(view); ok {
|
||||
session.updateProperty(view.htmlID(), "min", time.Format(timeFormat))
|
||||
if time, ok := GetTimePickerMin(picker); ok {
|
||||
session.updateProperty(picker.htmlID(), "min", time.Format(timeFormat))
|
||||
} else {
|
||||
session.removeProperty(view.htmlID(), "min")
|
||||
session.removeProperty(picker.htmlID(), "min")
|
||||
}
|
||||
|
||||
case TimePickerMax:
|
||||
if time, ok := GetTimePickerMax(view); ok {
|
||||
session.updateProperty(view.htmlID(), "max", time.Format(timeFormat))
|
||||
if time, ok := GetTimePickerMax(picker); ok {
|
||||
session.updateProperty(picker.htmlID(), "max", time.Format(timeFormat))
|
||||
} else {
|
||||
session.removeProperty(view.htmlID(), "max")
|
||||
session.removeProperty(picker.htmlID(), "max")
|
||||
}
|
||||
|
||||
case TimePickerStep:
|
||||
if step := GetTimePickerStep(view); step > 0 {
|
||||
session.updateProperty(view.htmlID(), "step", strconv.Itoa(step))
|
||||
if step := GetTimePickerStep(picker); step > 0 {
|
||||
session.updateProperty(picker.htmlID(), "step", strconv.Itoa(step))
|
||||
} else {
|
||||
session.removeProperty(view.htmlID(), "step")
|
||||
session.removeProperty(picker.htmlID(), "step")
|
||||
}
|
||||
|
||||
case TimePickerValue:
|
||||
value := GetTimePickerValue(view)
|
||||
session.callFunc("setInputValue", view.htmlID(), value.Format(timeFormat))
|
||||
value := GetTimePickerValue(picker)
|
||||
session.callFunc("setInputValue", picker.htmlID(), value.Format(timeFormat))
|
||||
|
||||
if listeners := GetTimeChangedListeners(view); len(listeners) > 0 {
|
||||
if listeners := GetTimeChangedListeners(picker); len(listeners) > 0 {
|
||||
oldTime := time.Now()
|
||||
if val := view.getRaw("old-time"); val != nil {
|
||||
if val := picker.getRaw("old-time"); val != nil {
|
||||
if time, ok := val.(time.Time); ok {
|
||||
oldTime = time
|
||||
}
|
||||
}
|
||||
for _, listener := range listeners {
|
||||
listener(view, value, oldTime)
|
||||
listener(picker, value, oldTime)
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
viewPropertyChanged(view, tag)
|
||||
picker.viewData.propertyChanged(tag)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -420,5 +420,5 @@ func GetTimePickerValue(view View, subviewID ...string) time.Time {
|
|||
// 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 GetTimeChangedListeners(view View, subviewID ...string) []func(TimePicker, time.Time, time.Time) {
|
||||
return getEventWithOldListeners[TimePicker, time.Time](view, subviewID, TimeChangedEvent)
|
||||
return getTwoArgEventListeners[TimePicker, time.Time](view, subviewID, TimeChangedEvent)
|
||||
}
|
||||
|
|
|
@ -144,7 +144,7 @@ type TouchEvent struct {
|
|||
|
||||
/*
|
||||
func setTouchListener(properties Properties, tag PropertyName, value any) bool {
|
||||
if listeners, ok := valueToEventListeners[View, TouchEvent](value); ok {
|
||||
if listeners, ok := valueToOneArgEventListeners[View, TouchEvent](value); ok {
|
||||
if len(listeners) == 0 {
|
||||
properties.setRaw(tag, nil)
|
||||
} else {
|
||||
|
@ -215,7 +215,7 @@ func (event *TouchEvent) init(data DataObject) {
|
|||
}
|
||||
|
||||
func handleTouchEvents(view View, tag PropertyName, data DataObject) {
|
||||
listeners := getEventListeners[View, TouchEvent](view, nil, tag)
|
||||
listeners := getOneArgEventListeners[View, TouchEvent](view, nil, tag)
|
||||
if len(listeners) == 0 {
|
||||
return
|
||||
}
|
||||
|
@ -231,23 +231,23 @@ func handleTouchEvents(view View, tag PropertyName, data DataObject) {
|
|||
// GetTouchStartListeners returns the "touch-start" listener list. 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 GetTouchStartListeners(view View, subviewID ...string) []func(View, TouchEvent) {
|
||||
return getEventListeners[View, TouchEvent](view, subviewID, TouchStart)
|
||||
return getOneArgEventListeners[View, TouchEvent](view, subviewID, TouchStart)
|
||||
}
|
||||
|
||||
// GetTouchEndListeners returns the "touch-end" listener list. 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 GetTouchEndListeners(view View, subviewID ...string) []func(View, TouchEvent) {
|
||||
return getEventListeners[View, TouchEvent](view, subviewID, TouchEnd)
|
||||
return getOneArgEventListeners[View, TouchEvent](view, subviewID, TouchEnd)
|
||||
}
|
||||
|
||||
// GetTouchMoveListeners returns the "touch-move" listener list. 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 GetTouchMoveListeners(view View, subviewID ...string) []func(View, TouchEvent) {
|
||||
return getEventListeners[View, TouchEvent](view, subviewID, TouchMove)
|
||||
return getOneArgEventListeners[View, TouchEvent](view, subviewID, TouchMove)
|
||||
}
|
||||
|
||||
// GetTouchCancelListeners returns the "touch-cancel" listener list. 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 GetTouchCancelListeners(view View, subviewID ...string) []func(View, TouchEvent) {
|
||||
return getEventListeners[View, TouchEvent](view, subviewID, TouchCancel)
|
||||
return getOneArgEventListeners[View, TouchEvent](view, subviewID, TouchCancel)
|
||||
}
|
||||
|
|
|
@ -61,22 +61,22 @@ func newVideoPlayer(session Session) View {
|
|||
func (player *videoPlayerData) init(session Session) {
|
||||
player.mediaPlayerData.init(session)
|
||||
player.tag = "VideoPlayer"
|
||||
player.changed = videoPlayerPropertyChanged
|
||||
player.changed = player.propertyChanged
|
||||
}
|
||||
|
||||
func (player *videoPlayerData) htmlTag() string {
|
||||
return "video"
|
||||
}
|
||||
|
||||
func videoPlayerPropertyChanged(view View, tag PropertyName) {
|
||||
func (player *videoPlayerData) propertyChanged(tag PropertyName) {
|
||||
|
||||
session := view.Session()
|
||||
session := player.Session()
|
||||
updateSize := func(cssTag string) {
|
||||
if size, ok := floatTextProperty(view, tag, session, 0); ok {
|
||||
if size, ok := floatTextProperty(player, tag, session, 0); ok {
|
||||
if size != "0" {
|
||||
session.updateProperty(view.htmlID(), cssTag, size)
|
||||
session.updateProperty(player.htmlID(), cssTag, size)
|
||||
} else {
|
||||
session.removeProperty(view.htmlID(), cssTag)
|
||||
session.removeProperty(player.htmlID(), cssTag)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -89,14 +89,14 @@ func videoPlayerPropertyChanged(view View, tag PropertyName) {
|
|||
updateSize("height")
|
||||
|
||||
case Poster:
|
||||
if url, ok := stringProperty(view, Poster, session); ok {
|
||||
session.updateProperty(view.htmlID(), string(Poster), url)
|
||||
if url, ok := stringProperty(player, Poster, session); ok {
|
||||
session.updateProperty(player.htmlID(), string(Poster), url)
|
||||
} else {
|
||||
session.removeProperty(view.htmlID(), string(Poster))
|
||||
session.removeProperty(player.htmlID(), string(Poster))
|
||||
}
|
||||
|
||||
default:
|
||||
mediaPlayerPropertyChanged(view, tag)
|
||||
player.mediaPlayerData.propertyChanged(tag)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
296
view.go
296
view.go
|
@ -110,10 +110,10 @@ type viewData struct {
|
|||
created bool
|
||||
hasFocus bool
|
||||
hasHtmlDisabled bool
|
||||
getFunc func(view View, tag PropertyName) any
|
||||
set func(view View, tag PropertyName, value any) []PropertyName
|
||||
remove func(view View, tag PropertyName) []PropertyName
|
||||
changed func(view View, tag PropertyName)
|
||||
get func(tag PropertyName) any
|
||||
set func(tag PropertyName, value any) []PropertyName
|
||||
remove func(tag PropertyName) []PropertyName
|
||||
changed func(tag PropertyName)
|
||||
}
|
||||
|
||||
func newView(session Session) View {
|
||||
|
@ -145,10 +145,11 @@ func setInitParams(view View, params Params) {
|
|||
|
||||
func (view *viewData) init(session Session) {
|
||||
view.viewStyle.init()
|
||||
view.getFunc = viewGet
|
||||
view.set = viewSet
|
||||
view.get = view.getFunc
|
||||
view.set = view.setFunc
|
||||
view.remove = view.removeFunc
|
||||
view.normalize = normalizeViewTag
|
||||
view.changed = viewPropertyChanged
|
||||
view.changed = view.propertyChanged
|
||||
view.tag = "View"
|
||||
view.session = session
|
||||
view.changeListener = map[PropertyName]func(View, PropertyName){}
|
||||
|
@ -213,35 +214,11 @@ func (view *viewData) Focusable() bool {
|
|||
}
|
||||
|
||||
func (view *viewData) Remove(tag PropertyName) {
|
||||
tag = view.normalize(tag)
|
||||
var changedTags []PropertyName = nil
|
||||
|
||||
switch tag {
|
||||
case ID:
|
||||
if view.viewID != "" {
|
||||
view.viewID = ""
|
||||
changedTags = []PropertyName{ID}
|
||||
}
|
||||
|
||||
case AnimationTag:
|
||||
if val := view.getRaw(AnimationTag); val != nil {
|
||||
if animations, ok := val.([]Animation); ok {
|
||||
for _, animation := range animations {
|
||||
animation.unused(view.session)
|
||||
}
|
||||
}
|
||||
|
||||
view.setRaw(AnimationTag, nil)
|
||||
changedTags = []PropertyName{AnimationTag}
|
||||
}
|
||||
|
||||
default:
|
||||
changedTags = view.remove(view, tag)
|
||||
}
|
||||
changedTags := view.removeFunc(view.normalize(tag))
|
||||
|
||||
if view.created && len(changedTags) > 0 {
|
||||
for _, tag := range changedTags {
|
||||
view.changed(view, tag)
|
||||
view.changed(tag)
|
||||
}
|
||||
|
||||
for _, tag := range changedTags {
|
||||
|
@ -252,6 +229,15 @@ func (view *viewData) Remove(tag PropertyName) {
|
|||
}
|
||||
}
|
||||
|
||||
func (view *viewData) Get(tag PropertyName) any {
|
||||
switch tag {
|
||||
case ID:
|
||||
return view.ID()
|
||||
}
|
||||
return view.get(view.normalize(tag))
|
||||
|
||||
}
|
||||
|
||||
func (view *viewData) Set(tag PropertyName, value any) bool {
|
||||
if value == nil {
|
||||
view.Remove(tag)
|
||||
|
@ -259,42 +245,11 @@ func (view *viewData) Set(tag PropertyName, value any) bool {
|
|||
}
|
||||
|
||||
tag = view.normalize(tag)
|
||||
var changedTags []PropertyName = nil
|
||||
|
||||
switch tag {
|
||||
case ID:
|
||||
text, ok := value.(string)
|
||||
if !ok {
|
||||
notCompatibleType(ID, value)
|
||||
return false
|
||||
}
|
||||
view.viewID = text
|
||||
changedTags = []PropertyName{ID}
|
||||
|
||||
case AnimationTag:
|
||||
oldAnimations := []Animation{}
|
||||
if val := view.getRaw(AnimationTag); val != nil {
|
||||
if animation, ok := val.([]Animation); ok {
|
||||
oldAnimations = animation
|
||||
}
|
||||
}
|
||||
|
||||
if !setAnimationProperty(view, tag, value) {
|
||||
return false
|
||||
}
|
||||
|
||||
for _, animation := range oldAnimations {
|
||||
animation.unused(view.session)
|
||||
}
|
||||
changedTags = []PropertyName{AnimationTag}
|
||||
|
||||
default:
|
||||
changedTags = viewSet(view, tag, value)
|
||||
}
|
||||
changedTags := view.set(tag, value)
|
||||
|
||||
if view.created && len(changedTags) > 0 {
|
||||
for _, tag := range changedTags {
|
||||
view.changed(view, tag)
|
||||
view.changed(tag)
|
||||
}
|
||||
|
||||
for _, tag := range changedTags {
|
||||
|
@ -316,67 +271,78 @@ func normalizeViewTag(tag PropertyName) PropertyName {
|
|||
return tag
|
||||
}
|
||||
|
||||
/*
|
||||
func (view *viewData) propertyChangedEvent(tag PropertyName) {
|
||||
if listener, ok := view.changeListener[tag]; ok {
|
||||
listener(view, tag)
|
||||
func (view *viewData) getFunc(tag PropertyName) any {
|
||||
if tag == ID {
|
||||
if id := view.ID(); id != "" {
|
||||
return id
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return viewStyleGet(view, tag)
|
||||
}
|
||||
|
||||
func (view *viewData) removeFunc(tag PropertyName) []PropertyName {
|
||||
var changedTags []PropertyName = nil
|
||||
|
||||
switch tag {
|
||||
case BorderLeft, BorderRight, BorderTop, BorderBottom,
|
||||
BorderStyle, BorderLeftStyle, BorderRightStyle, BorderTopStyle, BorderBottomStyle,
|
||||
BorderColor, BorderLeftColor, BorderRightColor, BorderTopColor, BorderBottomColor,
|
||||
BorderWidth, BorderLeftWidth, BorderRightWidth, BorderTopWidth, BorderBottomWidth:
|
||||
tag = Border
|
||||
case ID:
|
||||
if view.viewID != "" {
|
||||
view.viewID = ""
|
||||
changedTags = []PropertyName{ID}
|
||||
} else {
|
||||
changedTags = []PropertyName{}
|
||||
}
|
||||
|
||||
case CellBorderStyle, CellBorderColor, CellBorderWidth,
|
||||
CellBorderLeft, CellBorderLeftStyle, CellBorderLeftColor, CellBorderLeftWidth,
|
||||
CellBorderRight, CellBorderRightStyle, CellBorderRightColor, CellBorderRightWidth,
|
||||
CellBorderTop, CellBorderTopStyle, CellBorderTopColor, CellBorderTopWidth,
|
||||
CellBorderBottom, CellBorderBottomStyle, CellBorderBottomColor, CellBorderBottomWidth:
|
||||
tag = CellBorder
|
||||
case AnimationTag:
|
||||
if val := view.getRaw(AnimationTag); val != nil {
|
||||
if animations, ok := val.([]Animation); ok {
|
||||
for _, animation := range animations {
|
||||
animation.unused(view.session)
|
||||
}
|
||||
}
|
||||
|
||||
case OutlineColor, OutlineStyle, OutlineWidth:
|
||||
tag = Outline
|
||||
|
||||
case RadiusX, RadiusY, RadiusTopLeft, RadiusTopLeftX, RadiusTopLeftY,
|
||||
RadiusTopRight, RadiusTopRightX, RadiusTopRightY,
|
||||
RadiusBottomLeft, RadiusBottomLeftX, RadiusBottomLeftY,
|
||||
RadiusBottomRight, RadiusBottomRightX, RadiusBottomRightY:
|
||||
tag = Radius
|
||||
|
||||
case MarginTop, MarginRight, MarginBottom, MarginLeft,
|
||||
"top-margin", "right-margin", "bottom-margin", "left-margin":
|
||||
tag = Margin
|
||||
|
||||
case PaddingTop, PaddingRight, PaddingBottom, PaddingLeft,
|
||||
"top-padding", "right-padding", "bottom-padding", "left-padding":
|
||||
tag = Padding
|
||||
|
||||
case CellPaddingTop, CellPaddingRight, CellPaddingBottom, CellPaddingLeft:
|
||||
tag = CellPadding
|
||||
|
||||
case ColumnSeparatorStyle, ColumnSeparatorWidth, ColumnSeparatorColor:
|
||||
tag = ColumnSeparator
|
||||
view.setRaw(AnimationTag, nil)
|
||||
changedTags = []PropertyName{AnimationTag}
|
||||
}
|
||||
|
||||
default:
|
||||
return
|
||||
changedTags = viewStyleRemove(view, tag)
|
||||
}
|
||||
|
||||
if listener, ok := view.changeListener[tag]; ok {
|
||||
listener(view, tag)
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
func viewRemove(properties Properties, tag PropertyName) []PropertyName {
|
||||
return viewStyleRemove(properties, tag)
|
||||
return changedTags
|
||||
}
|
||||
|
||||
func viewSet(view View, tag PropertyName, value any) []PropertyName {
|
||||
func (view *viewData) setFunc(tag PropertyName, value any) []PropertyName {
|
||||
|
||||
switch tag {
|
||||
|
||||
case ID:
|
||||
if text, ok := value.(string); ok {
|
||||
view.viewID = text
|
||||
view.setRaw(ID, text)
|
||||
return []PropertyName{ID}
|
||||
}
|
||||
notCompatibleType(ID, value)
|
||||
return nil
|
||||
|
||||
case AnimationTag:
|
||||
oldAnimations := []Animation{}
|
||||
if val := view.getRaw(AnimationTag); val != nil {
|
||||
if animation, ok := val.([]Animation); ok {
|
||||
oldAnimations = animation
|
||||
}
|
||||
}
|
||||
|
||||
if !setAnimationProperty(view, tag, value) {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, animation := range oldAnimations {
|
||||
animation.unused(view.session)
|
||||
}
|
||||
return []PropertyName{AnimationTag}
|
||||
|
||||
case TabIndex, "tab-index":
|
||||
return setIntProperty(view, TabIndex, value)
|
||||
|
||||
|
@ -393,29 +359,46 @@ func viewSet(view View, tag PropertyName, value any) []PropertyName {
|
|||
return nil
|
||||
|
||||
case FocusEvent, LostFocusEvent:
|
||||
return setNoParamEventListener[View](view, tag, value)
|
||||
return setNoArgEventListener[View](view, tag, value)
|
||||
|
||||
case KeyDownEvent, KeyUpEvent:
|
||||
return setViewEventListener[View, KeyEvent](view, tag, value)
|
||||
return setOneArgEventListener[View, KeyEvent](view, tag, value)
|
||||
|
||||
case ClickEvent, DoubleClickEvent, MouseDown, MouseUp, MouseMove, MouseOut, MouseOver, ContextMenuEvent:
|
||||
return setViewEventListener[View, MouseEvent](view, tag, value)
|
||||
return setOneArgEventListener[View, MouseEvent](view, tag, value)
|
||||
|
||||
case PointerDown, PointerUp, PointerMove, PointerOut, PointerOver, PointerCancel:
|
||||
return setViewEventListener[View, PointerEvent](view, tag, value)
|
||||
return setOneArgEventListener[View, PointerEvent](view, tag, value)
|
||||
|
||||
case TouchStart, TouchEnd, TouchMove, TouchCancel:
|
||||
return setViewEventListener[View, TouchEvent](view, tag, value)
|
||||
return setOneArgEventListener[View, TouchEvent](view, tag, value)
|
||||
|
||||
case TransitionRunEvent, TransitionStartEvent, TransitionEndEvent, TransitionCancelEvent,
|
||||
AnimationStartEvent, AnimationEndEvent, AnimationIterationEvent, AnimationCancelEvent:
|
||||
return setViewEventListener[View, string](view, tag, value)
|
||||
//return setTransitionListener(view, tag, value), tag
|
||||
//return setAnimationListener(view, tag, value), tag
|
||||
case TransitionRunEvent, TransitionStartEvent, TransitionEndEvent, TransitionCancelEvent:
|
||||
result := setOneArgEventListener[View, PropertyName](view, tag, value)
|
||||
if result == nil {
|
||||
result = setOneArgEventListener[View, string](view, tag, value)
|
||||
if result != nil {
|
||||
if listeners, ok := view.getRaw(tag).([]func(View, string)); ok {
|
||||
newListeners := make([]func(View, PropertyName), len(listeners))
|
||||
for i, listener := range listeners {
|
||||
newListeners[i] = func(view View, name PropertyName) {
|
||||
listener(view, string(name))
|
||||
}
|
||||
}
|
||||
view.setRaw(tag, newListeners)
|
||||
return result
|
||||
}
|
||||
view.setRaw(tag, nil)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return result
|
||||
|
||||
case AnimationStartEvent, AnimationEndEvent, AnimationIterationEvent, AnimationCancelEvent:
|
||||
return setOneArgEventListener[View, string](view, tag, value)
|
||||
|
||||
case ResizeEvent, ScrollEvent:
|
||||
return setViewEventListener[View, Frame](view, tag, value)
|
||||
//return setFrameListener(view, tag, value), tag
|
||||
return setOneArgEventListener[View, Frame](view, tag, value)
|
||||
}
|
||||
|
||||
return viewStyleSet(view, tag, value)
|
||||
|
@ -439,12 +422,7 @@ func (view *viewData) SetParams(params Params) bool {
|
|||
return result
|
||||
}
|
||||
|
||||
func viewPropertyChanged(view View, tag PropertyName) {
|
||||
/*
|
||||
if view.updateTransformProperty(tag) {
|
||||
return
|
||||
}
|
||||
*/
|
||||
func (view *viewData) propertyChanged(tag PropertyName) {
|
||||
|
||||
htmlID := view.htmlID()
|
||||
session := view.Session()
|
||||
|
@ -645,9 +623,11 @@ func viewPropertyChanged(view View, tag PropertyName) {
|
|||
|
||||
case Strikethrough, Overline, Underline:
|
||||
session.updateCSSProperty(htmlID, "text-decoration", textDecorationCSS(view, session))
|
||||
for _, tag2 := range []PropertyName{TextLineColor, TextLineStyle, TextLineThickness} {
|
||||
viewPropertyChanged(view, tag2)
|
||||
}
|
||||
/*
|
||||
for _, tag2 := range []PropertyName{TextLineColor, TextLineStyle, TextLineThickness} {
|
||||
view.propertyChanged(tag2)
|
||||
}
|
||||
*/
|
||||
|
||||
case Transition:
|
||||
session.updateCSSProperty(htmlID, "transition", transitionCSS(view, session))
|
||||
|
@ -711,34 +691,19 @@ func viewPropertyChanged(view View, tag PropertyName) {
|
|||
}
|
||||
|
||||
case PerspectiveOriginX, PerspectiveOriginY:
|
||||
if getTransform3D(view, session) {
|
||||
x, y := GetPerspectiveOrigin(view)
|
||||
value := ""
|
||||
if x.Type != Auto || y.Type != Auto {
|
||||
value = x.cssString("50%", session) + " " + y.cssString("50%", session)
|
||||
}
|
||||
session.updateCSSProperty(htmlID, "perspective-origin", value)
|
||||
}
|
||||
x, y := GetPerspectiveOrigin(view)
|
||||
session.updateCSSProperty(htmlID, "perspective-origin", transformOriginCSS(x, y, AutoSize(), view.Session()))
|
||||
|
||||
case BackfaceVisible:
|
||||
if getTransform3D(view, session) {
|
||||
if GetBackfaceVisible(view) {
|
||||
session.updateCSSProperty(htmlID, string(BackfaceVisible), "visible")
|
||||
} else {
|
||||
session.updateCSSProperty(htmlID, string(BackfaceVisible), "hidden")
|
||||
}
|
||||
if GetBackfaceVisible(view) {
|
||||
session.updateCSSProperty(htmlID, string(BackfaceVisible), "visible")
|
||||
} else {
|
||||
session.updateCSSProperty(htmlID, string(BackfaceVisible), "hidden")
|
||||
}
|
||||
|
||||
case OriginX, OriginY, OriginZ:
|
||||
x, y, z := getOrigin(view, session)
|
||||
value := ""
|
||||
|
||||
if z.Type != Auto {
|
||||
value = x.cssString("50%", session) + " " + y.cssString("50%", session) + " " + z.cssString("50%", session)
|
||||
} else if x.Type != Auto || y.Type != Auto {
|
||||
value = x.cssString("50%", session) + " " + y.cssString("50%", session)
|
||||
}
|
||||
session.updateCSSProperty(htmlID, "transform-origin", value)
|
||||
case TransformOriginX, TransformOriginY, TransformOriginZ:
|
||||
x, y, z := getTransformOrigin(view, session)
|
||||
session.updateCSSProperty(htmlID, "transform-origin", transformOriginCSS(x, y, z, view.Session()))
|
||||
|
||||
case TransformTag, Perspective, SkewX, SkewY, TranslateX, TranslateY, TranslateZ,
|
||||
ScaleX, ScaleY, ScaleZ, Rotate, RotateX, RotateY, RotateZ:
|
||||
|
@ -803,17 +768,6 @@ func viewPropertyChanged(view View, tag PropertyName) {
|
|||
}
|
||||
}
|
||||
|
||||
func viewGet(view View, tag PropertyName) any {
|
||||
if tag == ID {
|
||||
if id := view.ID(); id != "" {
|
||||
return id
|
||||
} else {
|
||||
return nil
|
||||
}
|
||||
}
|
||||
return viewStyleGet(view, tag)
|
||||
}
|
||||
|
||||
func (view *viewData) htmlTag() string {
|
||||
if semantics := GetSemantics(view); semantics > DefaultSemantics {
|
||||
values := enumProperties[Semantics].cssValues
|
||||
|
@ -999,13 +953,13 @@ func (view *viewData) handleCommand(self View, command PropertyName, data DataOb
|
|||
|
||||
case FocusEvent:
|
||||
view.hasFocus = true
|
||||
for _, listener := range getNoParamEventListeners[View](view, nil, command) {
|
||||
for _, listener := range getNoArgEventListeners[View](view, nil, command) {
|
||||
listener(self)
|
||||
}
|
||||
|
||||
case LostFocusEvent:
|
||||
view.hasFocus = false
|
||||
for _, listener := range getNoParamEventListeners[View](view, nil, command) {
|
||||
for _, listener := range getNoArgEventListeners[View](view, nil, command) {
|
||||
listener(self)
|
||||
}
|
||||
|
||||
|
|
13
viewStyle.go
13
viewStyle.go
|
@ -497,6 +497,16 @@ func normalizeViewStyleTag(tag PropertyName) PropertyName {
|
|||
|
||||
case "left-padding":
|
||||
return PaddingLeft
|
||||
|
||||
case "origin-x":
|
||||
return TransformOriginX
|
||||
|
||||
case "origin-y":
|
||||
return TransformOriginY
|
||||
|
||||
case "origin-z":
|
||||
return TransformOriginZ
|
||||
|
||||
}
|
||||
return tag
|
||||
}
|
||||
|
@ -868,7 +878,8 @@ func writeViewStyle(name string, view Properties, buffer *strings.Builder, inden
|
|||
}
|
||||
|
||||
finalTags := []PropertyName{
|
||||
Perspective, PerspectiveOriginX, PerspectiveOriginY, BackfaceVisible, OriginX, OriginY, OriginZ,
|
||||
PerspectiveOriginX, PerspectiveOriginY, BackfaceVisible,
|
||||
TransformOriginX, TransformOriginY, TransformOriginZ,
|
||||
TransformTag, Clip, Filter, BackdropFilter, Summary, Content, Transition}
|
||||
for _, tag := range finalTags {
|
||||
removeTag(tag)
|
||||
|
|
|
@ -79,7 +79,7 @@ const (
|
|||
//
|
||||
// Internal type is `SizeUnit`, other types converted to it during assignment.
|
||||
// See `SizeUnit` description for more details.
|
||||
OriginX PropertyName = "origin-x"
|
||||
TransformOriginX PropertyName = "transform-origin-x"
|
||||
|
||||
// OriginY is the constant for "origin-y" property tag.
|
||||
//
|
||||
|
@ -90,7 +90,7 @@ const (
|
|||
//
|
||||
// Internal type is `SizeUnit`, other types converted to it during assignment.
|
||||
// See `SizeUnit` description for more details.
|
||||
OriginY PropertyName = "origin-y"
|
||||
TransformOriginY PropertyName = "transform-origin-y"
|
||||
|
||||
// OriginZ is the constant for "origin-z" property tag.
|
||||
//
|
||||
|
@ -101,7 +101,7 @@ const (
|
|||
//
|
||||
// Internal type is `SizeUnit`, other types converted to it during assignment.
|
||||
// See `SizeUnit` description for more details.
|
||||
OriginZ PropertyName = "origin-z"
|
||||
TransformOriginZ PropertyName = "transform-origin-z"
|
||||
|
||||
// TranslateX is the constant for "translate-x" property tag.
|
||||
//
|
||||
|
@ -527,29 +527,31 @@ func getTransformProperty(properties Properties) Transform {
|
|||
func setTransformPropertyElement(properties Properties, tag PropertyName, value any) []PropertyName {
|
||||
switch tag {
|
||||
case Perspective, RotateX, RotateY, RotateZ, Rotate, SkewX, SkewY, ScaleX, ScaleY, ScaleZ, TranslateX, TranslateY, TranslateZ:
|
||||
var result []PropertyName = nil
|
||||
if transform := getTransformProperty(properties); transform != nil {
|
||||
if result := transformSet(transform, tag, value); result != nil {
|
||||
if result = transformSet(transform, tag, value); result != nil {
|
||||
result = append(result, TransformTag)
|
||||
}
|
||||
} else {
|
||||
transform := NewTransform(nil)
|
||||
if result := transformSet(transform, tag, value); result != nil {
|
||||
if result = transformSet(transform, tag, value); result != nil {
|
||||
properties.setRaw(TransformTag, transform)
|
||||
result = append(result, TransformTag)
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
ErrorLogF(`"Transform" interface does not support the "%s" property`, tag)
|
||||
return result
|
||||
}
|
||||
|
||||
ErrorLogF(`"Transform" interface does not support the "%s" property`, tag)
|
||||
return nil
|
||||
}
|
||||
|
||||
/*
|
||||
func getTransform3D(style Properties, session Session) bool {
|
||||
perspective, ok := sizeProperty(style, Perspective, session)
|
||||
return ok && perspective.Type != Auto && perspective.Value != 0
|
||||
}
|
||||
*/
|
||||
|
||||
func getPerspectiveOrigin(style Properties, session Session) (SizeUnit, SizeUnit) {
|
||||
x, _ := sizeProperty(style, PerspectiveOriginX, session)
|
||||
|
@ -557,10 +559,10 @@ func getPerspectiveOrigin(style Properties, session Session) (SizeUnit, SizeUnit
|
|||
return x, y
|
||||
}
|
||||
|
||||
func getOrigin(style Properties, session Session) (SizeUnit, SizeUnit, SizeUnit) {
|
||||
x, _ := sizeProperty(style, OriginX, session)
|
||||
y, _ := sizeProperty(style, OriginY, session)
|
||||
z, _ := sizeProperty(style, OriginZ, session)
|
||||
func getTransformOrigin(style Properties, session Session) (SizeUnit, SizeUnit, SizeUnit) {
|
||||
x, _ := sizeProperty(style, TransformOriginX, session)
|
||||
y, _ := sizeProperty(style, TransformOriginY, session)
|
||||
z, _ := sizeProperty(style, TransformOriginZ, session)
|
||||
return x, y, z
|
||||
}
|
||||
|
||||
|
@ -674,8 +676,9 @@ func (transform *transformData) transformCSS(session Session) string {
|
|||
|
||||
func (style *viewStyle) writeViewTransformCSS(builder cssBuilder, session Session) {
|
||||
x, y := getPerspectiveOrigin(style, session)
|
||||
if x.Type != Auto || y.Type != Auto {
|
||||
builder.addValues(`perspective-origin`, ` `, x.cssString("50%", session), y.cssString("50%", session))
|
||||
z := AutoSize()
|
||||
if css := transformOriginCSS(x, y, z, session); css != "" {
|
||||
builder.add(`perspective-origin`, css)
|
||||
}
|
||||
|
||||
if backfaceVisible, ok := boolProperty(style, BackfaceVisible, session); ok {
|
||||
|
@ -686,11 +689,9 @@ func (style *viewStyle) writeViewTransformCSS(builder cssBuilder, session Sessio
|
|||
}
|
||||
}
|
||||
|
||||
x, y, z := getOrigin(style, session)
|
||||
if z.Type != Auto && z.Value != 0 {
|
||||
builder.addValues(`transform-origin`, ` `, x.cssString("50%", session), y.cssString("50%", session), z.cssString("0", session))
|
||||
} else if x.Type != Auto || y.Type != Auto {
|
||||
builder.addValues(`transform-origin`, ` `, x.cssString("50%", session), y.cssString("50%", session))
|
||||
x, y, z = getTransformOrigin(style, session)
|
||||
if css := transformOriginCSS(x, y, z, session); css != "" {
|
||||
builder.add(`transform-origin`, css)
|
||||
}
|
||||
|
||||
if transform := getTransformProperty(style); transform != nil {
|
||||
|
@ -698,6 +699,56 @@ func (style *viewStyle) writeViewTransformCSS(builder cssBuilder, session Sessio
|
|||
}
|
||||
}
|
||||
|
||||
func transformOriginCSS(x, y, z SizeUnit, session Session) string {
|
||||
if z.Type == Auto && x.Type == Auto && y.Type == Auto {
|
||||
return ""
|
||||
}
|
||||
|
||||
buffer := allocStringBuilder()
|
||||
defer freeStringBuilder(buffer)
|
||||
|
||||
if x.Type == SizeInPercent {
|
||||
switch x.Value {
|
||||
case 0:
|
||||
buffer.WriteString("left")
|
||||
case 50:
|
||||
buffer.WriteString("center")
|
||||
case 100:
|
||||
buffer.WriteString("right")
|
||||
|
||||
default:
|
||||
buffer.WriteString(x.cssString("center", session))
|
||||
}
|
||||
} else {
|
||||
buffer.WriteString(x.cssString("center", session))
|
||||
}
|
||||
|
||||
buffer.WriteRune(' ')
|
||||
|
||||
if y.Type == SizeInPercent {
|
||||
switch y.Value {
|
||||
case 0:
|
||||
buffer.WriteString("top")
|
||||
case 50:
|
||||
buffer.WriteString("center")
|
||||
case 100:
|
||||
buffer.WriteString("bottom")
|
||||
|
||||
default:
|
||||
buffer.WriteString(y.cssString("center", session))
|
||||
}
|
||||
} else {
|
||||
buffer.WriteString(y.cssString("center", session))
|
||||
}
|
||||
|
||||
if z.Type != Auto && z.Value != 0 {
|
||||
buffer.WriteRune(' ')
|
||||
buffer.WriteString(z.cssString("0", session))
|
||||
}
|
||||
|
||||
return buffer.String()
|
||||
}
|
||||
|
||||
/*
|
||||
func (view *viewData) updateTransformProperty(tag PropertyName) bool {
|
||||
htmlID := view.htmlID()
|
||||
|
|
|
@ -613,17 +613,17 @@ func GetBackfaceVisible(view View, subviewID ...string) bool {
|
|||
return boolStyledProperty(view, subviewID, BackfaceVisible, false)
|
||||
}
|
||||
|
||||
// GetOrigin returns a x-, y-, and z-coordinate of the point around which a view transformation is applied.
|
||||
// GetTransformOrigin returns a x-, y-, and z-coordinate of the point around which a view transformation is applied.
|
||||
// The default value is (50%, 50%, 50%).
|
||||
// If the second argument (subviewID) is not specified or it is "" then a value from the first argument (view) is returned.
|
||||
func GetOrigin(view View, subviewID ...string) (SizeUnit, SizeUnit, SizeUnit) {
|
||||
func GetTransformOrigin(view View, subviewID ...string) (SizeUnit, SizeUnit, SizeUnit) {
|
||||
if len(subviewID) > 0 && subviewID[0] != "" {
|
||||
view = ViewByID(view, subviewID[0])
|
||||
}
|
||||
if view == nil {
|
||||
return AutoSize(), AutoSize(), AutoSize()
|
||||
}
|
||||
return getOrigin(view, view.Session())
|
||||
return getTransformOrigin(view, view.Session())
|
||||
}
|
||||
|
||||
// GetTranslate returns a x-, y-, and z-axis translation value of a 2D/3D translation
|
||||
|
|
|
@ -38,10 +38,10 @@ func (container *viewsContainerData) init(session Session) {
|
|||
container.viewData.init(session)
|
||||
container.tag = "ViewsContainer"
|
||||
container.views = []View{}
|
||||
container.getFunc = container.get
|
||||
container.get = container.getFunc
|
||||
container.set = container.setFunc
|
||||
container.remove = container.removeFunc
|
||||
container.changed = viewsContainerPropertyChanged
|
||||
container.changed = container.propertyChanged
|
||||
}
|
||||
|
||||
func (container *viewsContainerData) setParentID(parentID string) {
|
||||
|
@ -163,7 +163,7 @@ func viewFromTextValue(text string, session Session) View {
|
|||
return NewTextView(session, Params{Text: text})
|
||||
}
|
||||
|
||||
func (container *viewsContainerData) removeFunc(view View, tag PropertyName) []PropertyName {
|
||||
func (container *viewsContainerData) removeFunc(tag PropertyName) []PropertyName {
|
||||
switch tag {
|
||||
case Content:
|
||||
if len(container.views) > 0 {
|
||||
|
@ -173,18 +173,18 @@ func (container *viewsContainerData) removeFunc(view View, tag PropertyName) []P
|
|||
return []PropertyName{}
|
||||
|
||||
case Disabled:
|
||||
if view.getRaw(Disabled) != nil {
|
||||
view.setRaw(Disabled, nil)
|
||||
if container.getRaw(Disabled) != nil {
|
||||
container.setRaw(Disabled, nil)
|
||||
for _, view := range container.views {
|
||||
view.Remove(Disabled)
|
||||
}
|
||||
return []PropertyName{tag}
|
||||
}
|
||||
}
|
||||
return viewRemove(view, tag)
|
||||
return container.viewData.removeFunc(tag)
|
||||
}
|
||||
|
||||
func (container *viewsContainerData) setFunc(self View, tag PropertyName, value any) []PropertyName {
|
||||
func (container *viewsContainerData) setFunc(tag PropertyName, value any) []PropertyName {
|
||||
switch tag {
|
||||
case Content:
|
||||
if container.setContent(value) {
|
||||
|
@ -194,7 +194,7 @@ func (container *viewsContainerData) setFunc(self View, tag PropertyName, value
|
|||
|
||||
case Disabled:
|
||||
oldDisabled := IsDisabled(container)
|
||||
result := viewSet(self, Disabled, value)
|
||||
result := container.viewData.setFunc(Disabled, value)
|
||||
if result != nil {
|
||||
disabled := IsDisabled(container)
|
||||
if oldDisabled != disabled {
|
||||
|
@ -206,16 +206,16 @@ func (container *viewsContainerData) setFunc(self View, tag PropertyName, value
|
|||
return result
|
||||
}
|
||||
|
||||
return viewSet(self, tag, value)
|
||||
return container.viewData.setFunc(tag, value)
|
||||
}
|
||||
|
||||
func viewsContainerPropertyChanged(view View, tag PropertyName) {
|
||||
func (container *viewsContainerData) propertyChanged(tag PropertyName) {
|
||||
switch tag {
|
||||
case Content:
|
||||
updateInnerHTML(view.htmlID(), view.Session())
|
||||
updateInnerHTML(container.htmlID(), container.Session())
|
||||
|
||||
default:
|
||||
viewPropertyChanged(view, tag)
|
||||
container.viewData.propertyChanged(tag)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -292,13 +292,13 @@ func (container *viewsContainerData) setContent(value any) bool {
|
|||
return true
|
||||
}
|
||||
|
||||
func (container *viewsContainerData) get(view View, tag PropertyName) any {
|
||||
func (container *viewsContainerData) getFunc(tag PropertyName) any {
|
||||
switch tag {
|
||||
case Content:
|
||||
return container.views
|
||||
|
||||
default:
|
||||
return viewGet(view, tag)
|
||||
return container.viewData.getFunc(tag)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue