Updated Popup animation

This commit is contained in:
Alexei Anoshenko 2026-06-25 20:25:56 +03:00
parent 73b0ee0c5c
commit 0c1bdce7c8
1 changed files with 48 additions and 50 deletions

View File

@ -8,6 +8,7 @@ import (
"reflect" "reflect"
"slices" "slices"
"strings" "strings"
"sync"
) )
// Constants for [Popup] specific properties and events // Constants for [Popup] specific properties and events
@ -304,7 +305,7 @@ type Popup interface {
SetHotKey(keyCode KeyCode, controlKeys ControlKeyMask, fn func(Popup)) SetHotKey(keyCode KeyCode, controlKeys ControlKeyMask, fn func(Popup))
onDismiss() onDismiss()
html(buffer *strings.Builder) html(hidden bool) string
viewByHTMLID(id string) View viewByHTMLID(id string) View
keyEvent(event KeyEvent) bool keyEvent(event KeyEvent) bool
showAnimation() showAnimation()
@ -343,6 +344,7 @@ type popupData struct {
type popupManager struct { type popupManager struct {
popups []Popup popups []Popup
dismissAnimation []Popup dismissAnimation []Popup
mutex sync.Mutex
} }
func (popup *popupData) createArrowView(location int) View { func (popup *popupData) createArrowView(location int) View {
@ -770,23 +772,23 @@ func (popup *popupData) propertyChanged(tag PropertyName) {
animation := popup.animationProperty() animation := popup.animationProperty()
opacity, _ := floatProperty(popup, ShowOpacity, popup.session, 1) opacity, _ := floatProperty(popup, ShowOpacity, popup.session, 1)
if opacity != 1 { if opacity != 1 {
popup.popupView.SetTransition(Opacity, animation) popup.layerView.SetTransition(Opacity, animation)
} }
transform := getTransformProperty(popup, ShowTransform) transform := getTransformProperty(popup, ShowTransform)
if transform != nil { if transform != nil {
popup.popupView.SetTransition(Transform, animation) popup.layerView.SetTransition(Transform, animation)
} }
case ShowOpacity: case ShowOpacity:
opacity, _ := floatProperty(popup, ShowOpacity, popup.session, 1) opacity, _ := floatProperty(popup, ShowOpacity, popup.session, 1)
if opacity != 1 { if opacity != 1 {
popup.popupView.SetTransition(Opacity, popup.animationProperty()) popup.layerView.SetTransition(Opacity, popup.animationProperty())
} }
case ShowTransform: case ShowTransform:
transform := getTransformProperty(popup, ShowTransform) transform := getTransformProperty(popup, ShowTransform)
if transform != nil { if transform != nil {
popup.popupView.SetTransition(Transform, popup.animationProperty()) popup.layerView.SetTransition(Transform, popup.animationProperty())
} }
default: default:
@ -979,7 +981,7 @@ func (popup *popupData) showTransformAndOpacity() (TransformProperty, float64) {
func (popup *popupData) showAnimation() { func (popup *popupData) showAnimation() {
transform, opacity := popup.showTransformAndOpacity() transform, opacity := popup.showTransformAndOpacity()
if opacity != 1 || transform != nil { if opacity != 1 || transform != nil {
htmlID := popup.popupView.htmlID() htmlID := popup.layerView.htmlID()
session := popup.Session() session := popup.Session()
session.updateProperty(htmlID, "ontransitionend", "scanElementsSize()") session.updateProperty(htmlID, "ontransitionend", "scanElementsSize()")
@ -987,10 +989,10 @@ func (popup *popupData) showAnimation() {
animation := popup.animationProperty() animation := popup.animationProperty()
if opacity != 1 { if opacity != 1 {
popup.popupView.SetTransition(Opacity, animation) popup.layerView.SetTransition(Opacity, animation)
} }
if transform != nil { if transform != nil {
popup.popupView.SetTransition(Transform, animation) popup.layerView.SetTransition(Transform, animation)
} }
if opacity != 1 { if opacity != 1 {
@ -1006,10 +1008,10 @@ func (popup *popupData) dismissAnimation(listener func(View, PropertyName)) bool
transform, opacity := popup.showTransformAndOpacity() transform, opacity := popup.showTransformAndOpacity()
if opacity != 1 || transform != nil { if opacity != 1 || transform != nil {
session := popup.Session() session := popup.Session()
popup.popupView.Set(TransitionEndEvent, listener) popup.layerView.Set(TransitionEndEvent, listener)
popup.popupView.Set(TransitionCancelEvent, listener) popup.layerView.Set(TransitionCancelEvent, listener)
htmlID := popup.popupView.htmlID() htmlID := popup.layerView.htmlID()
if opacity != 1 { if opacity != 1 {
session.updateCSSProperty(htmlID, string(Opacity), fmt.Sprintf("%.2f", opacity)) session.updateCSSProperty(htmlID, string(Opacity), fmt.Sprintf("%.2f", opacity))
} }
@ -1017,18 +1019,27 @@ func (popup *popupData) dismissAnimation(listener func(View, PropertyName)) bool
session.updateCSSProperty(htmlID, string(Transform), transform.transformCSS(session)) session.updateCSSProperty(htmlID, string(Transform), transform.transformCSS(session))
} }
Set(popup.layerView, popupArrowID, Visibility, Invisible) //Set(popup.layerView, popupArrowID, Visibility, Invisible)
popup.dismissAnimationRunning = true popup.dismissAnimationRunning = true
return true return true
} }
return false return false
} }
func (popup *popupData) html(buffer *strings.Builder) { func (popup *popupData) html(hidden bool) string {
if popup.layerView == nil { if popup.layerView == nil {
popup.layerView = popup.createLayerView() popup.layerView = popup.createLayerView()
} }
if hidden {
popup.layerView.Set(Visibility, Invisible)
}
buffer := allocStringBuilder()
defer freeStringBuilder(buffer)
viewHTML(popup.layerView, buffer, "") viewHTML(popup.layerView, buffer, "")
return buffer.String()
} }
func (popup *popupData) viewByHTMLID(id string) View { func (popup *popupData) viewByHTMLID(id string) View {
@ -1352,12 +1363,12 @@ func (popup *popupData) createLayerView() GridLayout {
if opacity != 1 || transform != nil { if opacity != 1 || transform != nil {
animation := popup.animationProperty() animation := popup.animationProperty()
if opacity != 1 { if opacity != 1 {
popup.popupView.Set(Opacity, opacity) popup.layerView.Set(Opacity, opacity)
popup.popupView.SetTransition(Opacity, animation) popup.layerView.SetTransition(Opacity, animation)
} }
if transform != nil { if transform != nil {
popup.popupView.Set(Transform, transform) popup.layerView.Set(Transform, transform)
popup.popupView.SetTransition(Transform, animation) popup.layerView.SetTransition(Transform, animation)
} }
} }
@ -1549,43 +1560,33 @@ func ShowPopup(view View, param Params) Popup {
return popup return popup
} }
func (manager *popupManager) updatePopupLayerInnerHTML(session Session) {
if manager.popups == nil {
manager.popups = []Popup{}
session.updateInnerHTML(popupLayerID, "")
return
}
buffer := allocStringBuilder()
defer freeStringBuilder(buffer)
for _, popup := range manager.popups {
popup.html(buffer)
}
session.updateInnerHTML(popupLayerID, buffer.String())
}
func (manager *popupManager) showPopup(popup Popup) { func (manager *popupManager) showPopup(popup Popup) {
if popup == nil { if popup == nil {
return return
} }
for len(manager.dismissAnimation) > 0 { manager.mutex.Lock()
p := manager.dismissAnimation[0] dismissAnimation := manager.dismissAnimation
manager.dismissAnimation = manager.dismissAnimation[1:] manager.dismissAnimation = nil
p.onDismiss() manager.mutex.Unlock()
for _, p := range dismissAnimation {
manager.removePopup(p) manager.removePopup(p)
p.onDismiss()
} }
session := popup.Session() manager.mutex.Lock()
if len(manager.popups) == 0 { if len(manager.popups) == 0 {
manager.popups = []Popup{popup} manager.popups = []Popup{popup}
} else { } else {
manager.popups = append(manager.popups, popup) manager.popups = append(manager.popups, popup)
} }
manager.mutex.Unlock()
session := popup.Session()
session.callFunc("blurCurrent") session.callFunc("blurCurrent")
manager.updatePopupLayerInnerHTML(session) session.appendToInnerHTML(popupLayerID, popup.html(false))
session.updateCSSProperty("ruiTooltipLayer", "visibility", "hidden") session.updateCSSProperty("ruiTooltipLayer", "visibility", "hidden")
session.updateCSSProperty("ruiTooltipLayer", "opacity", "0") session.updateCSSProperty("ruiTooltipLayer", "opacity", "0")
session.updateCSSProperty(popupLayerID, "visibility", "visible") session.updateCSSProperty(popupLayerID, "visibility", "visible")
@ -1594,13 +1595,7 @@ func (manager *popupManager) showPopup(popup Popup) {
} }
func (manager *popupManager) dismissPopup(popup Popup, animation bool) { func (manager *popupManager) dismissPopup(popup Popup, animation bool) {
if manager.popups == nil { if len(manager.popups) <= 0 || popup == nil {
manager.popups = []Popup{}
return
}
count := len(manager.popups)
if count <= 0 || popup == nil {
return return
} }
@ -1615,11 +1610,13 @@ func (manager *popupManager) dismissPopup(popup Popup, animation bool) {
} }
if animation && popup.dismissAnimation(listener) { if animation && popup.dismissAnimation(listener) {
manager.mutex.Lock()
if len(manager.dismissAnimation) == 0 { if len(manager.dismissAnimation) == 0 {
manager.dismissAnimation = []Popup{popup} manager.dismissAnimation = []Popup{popup}
} else { } else {
manager.dismissAnimation = append(manager.dismissAnimation, popup) manager.dismissAnimation = append(manager.dismissAnimation, popup)
} }
manager.mutex.Unlock()
} else { } else {
manager.removePopup(popup) manager.removePopup(popup)
popup.onDismiss() popup.onDismiss()
@ -1627,10 +1624,8 @@ func (manager *popupManager) dismissPopup(popup Popup, animation bool) {
} }
func (manager *popupManager) removePopup(popup Popup) { func (manager *popupManager) removePopup(popup Popup) {
if manager.popups == nil { manager.mutex.Lock()
manager.popups = []Popup{} defer manager.mutex.Unlock()
return
}
index := slices.Index(manager.popups, popup) index := slices.Index(manager.popups, popup)
if index < 0 { if index < 0 {
@ -1646,6 +1641,9 @@ func (manager *popupManager) removePopup(popup Popup) {
} }
func (manager *popupManager) dismissAnimationFinished(popup Popup) { func (manager *popupManager) dismissAnimationFinished(popup Popup) {
manager.mutex.Lock()
defer manager.mutex.Unlock()
if manager.dismissAnimation != nil { if manager.dismissAnimation != nil {
if i := slices.Index(manager.dismissAnimation, popup); i >= 0 { if i := slices.Index(manager.dismissAnimation, popup); i >= 0 {
manager.dismissAnimation = append(manager.dismissAnimation[:i], manager.dismissAnimation[i+1:]...) manager.dismissAnimation = append(manager.dismissAnimation[:i], manager.dismissAnimation[i+1:]...)