mirror of https://github.com/anoshenko/rui.git
				
				
				
			Added Start, Stop, Pause, and Resume methods to Animation interface
This commit is contained in:
		
							parent
							
								
									2f3de8fce3
								
							
						
					
					
						commit
						5e3d37a6a0
					
				|  | @ -1,6 +1,7 @@ | |||
| # v0.17.0 | ||||
| * Added "mod", "rem", "round", "round-up", "round-down", and "round-to-zero" SizeFunc functions | ||||
| * Added ModSize, RemSize, RoundSize, RoundUpSize, RoundDownSize, and RoundToZeroSize functions | ||||
| * Added Start, Stop, Pause, and Resume methods to Animation interface | ||||
| 
 | ||||
| # v0.16.0 | ||||
| * Can use ListAdapter as "content" property value of ListLayout | ||||
|  |  | |||
							
								
								
									
										53
									
								
								animation.go
								
								
								
								
							
							
						
						
									
										53
									
								
								animation.go
								
								
								
								
							|  | @ -121,6 +121,10 @@ type animationData struct { | |||
| 	propertyList | ||||
| 	keyFramesName string | ||||
| 	usageCounter  int | ||||
| 	view          View | ||||
| 	listener      func(view View, animation Animation, event string) | ||||
| 	oldListeners  map[string][]func(View, string) | ||||
| 	oldAnimation  []Animation | ||||
| } | ||||
| 
 | ||||
| // Animation interface is used to set animation parameters. Used properties:
 | ||||
|  | @ -128,6 +132,17 @@ type animationData struct { | |||
| type Animation interface { | ||||
| 	Properties | ||||
| 	fmt.Stringer | ||||
| 
 | ||||
| 	// Start starts the animation for the view specified by the first argument.
 | ||||
| 	// The second argument specifies the animation event listener (can be nil)
 | ||||
| 	Start(view View, listener func(view View, animation Animation, event string)) bool | ||||
| 	// Stop stops the animation
 | ||||
| 	Stop() | ||||
| 	// Pause pauses the animation
 | ||||
| 	Pause() | ||||
| 	// Resume resumes an animation that was stopped using the Pause method
 | ||||
| 	Resume() | ||||
| 
 | ||||
| 	writeTransitionString(tag string, buffer *strings.Builder) | ||||
| 	animationCSS(session Session) string | ||||
| 	transitionCSS(buffer *strings.Builder, session Session) | ||||
|  | @ -163,19 +178,29 @@ func NewAnimation(params Params) Animation { | |||
| 	return animation | ||||
| } | ||||
| 
 | ||||
| func (animation *animationData) hasAnimatedProperty() bool { | ||||
| 	props := animation.getRaw(PropertyTag) | ||||
| 	if props == nil { | ||||
| func (animation *animationData) animatedProperties() []AnimatedProperty { | ||||
| 	value := animation.getRaw(PropertyTag) | ||||
| 	if value == nil { | ||||
| 		ErrorLog("There are no animated properties.") | ||||
| 		return false | ||||
| 		return nil | ||||
| 	} | ||||
| 
 | ||||
| 	if _, ok := props.([]AnimatedProperty); !ok { | ||||
| 	props, ok := value.([]AnimatedProperty) | ||||
| 	if !ok { | ||||
| 		ErrorLog("Invalid animated properties.") | ||||
| 		return false | ||||
| 		return nil | ||||
| 	} | ||||
| 
 | ||||
| 	return true | ||||
| 	if len(props) == 0 { | ||||
| 		ErrorLog("There are no animated properties.") | ||||
| 		return nil | ||||
| 	} | ||||
| 
 | ||||
| 	return props | ||||
| } | ||||
| 
 | ||||
| func (animation *animationData) hasAnimatedProperty() bool { | ||||
| 	return animation.animatedProperties() != nil | ||||
| } | ||||
| 
 | ||||
| func (animation *animationData) animationName() string { | ||||
|  | @ -394,19 +419,11 @@ func (animation *animationData) String() string { | |||
| 
 | ||||
| func (animation *animationData) animationCSS(session Session) string { | ||||
| 	if animation.keyFramesName == "" { | ||||
| 		props := animation.getRaw(PropertyTag) | ||||
| 		if props == nil { | ||||
| 			ErrorLog("There are no animated properties.") | ||||
| 		if props := animation.animatedProperties(); props != nil { | ||||
| 			animation.keyFramesName = session.registerAnimation(props) | ||||
| 		} else { | ||||
| 			return "" | ||||
| 		} | ||||
| 
 | ||||
| 		animatedProps, ok := props.([]AnimatedProperty) | ||||
| 		if !ok || len(animatedProps) == 0 { | ||||
| 			ErrorLog("Invalid animated properties.") | ||||
| 			return "" | ||||
| 		} | ||||
| 
 | ||||
| 		animation.keyFramesName = session.registerAnimation(animatedProps) | ||||
| 	} | ||||
| 
 | ||||
| 	buffer := allocStringBuilder() | ||||
|  |  | |||
|  | @ -0,0 +1,109 @@ | |||
| package rui | ||||
| 
 | ||||
| func (animation *animationData) Start(view View, listener func(view View, animation Animation, event string)) bool { | ||||
| 	if view == nil { | ||||
| 		ErrorLog("nil View in animation.Start() function") | ||||
| 		return false | ||||
| 	} | ||||
| 	if !animation.hasAnimatedProperty() { | ||||
| 		return false | ||||
| 	} | ||||
| 
 | ||||
| 	animation.view = view | ||||
| 	animation.listener = listener | ||||
| 
 | ||||
| 	animation.oldAnimation = nil | ||||
| 	if value := view.Get(AnimationTag); value != nil { | ||||
| 		if oldAnimation, ok := value.([]Animation); ok && len(oldAnimation) > 0 { | ||||
| 			animation.oldAnimation = oldAnimation | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	animation.oldListeners = map[string][]func(View, string){} | ||||
| 
 | ||||
| 	setListeners := func(event string, listener func(View, string)) { | ||||
| 		var listeners []func(View, string) = nil | ||||
| 		if value := view.Get(event); value != nil { | ||||
| 			if oldListeners, ok := value.([]func(View, string)); ok && len(oldListeners) > 0 { | ||||
| 				listeners = oldListeners | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		if listeners == nil { | ||||
| 			view.Set(event, listener) | ||||
| 		} else { | ||||
| 			animation.oldListeners[event] = listeners | ||||
| 			view.Set(event, append(listeners, listener)) | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	setListeners(AnimationStartEvent, animation.onAnimationStart) | ||||
| 	setListeners(AnimationEndEvent, animation.onAnimationEnd) | ||||
| 	setListeners(AnimationCancelEvent, animation.onAnimationCancel) | ||||
| 	setListeners(AnimationIterationEvent, animation.onAnimationIteration) | ||||
| 
 | ||||
| 	view.Set(AnimationTag, animation) | ||||
| 	return true | ||||
| } | ||||
| 
 | ||||
| func (animation *animationData) finish() { | ||||
| 	if animation.view != nil { | ||||
| 		for _, event := range []string{AnimationStartEvent, AnimationEndEvent, AnimationCancelEvent, AnimationIterationEvent} { | ||||
| 			if listeners, ok := animation.oldListeners[event]; ok { | ||||
| 				animation.view.Set(event, listeners) | ||||
| 			} else { | ||||
| 				animation.view.Remove(event) | ||||
| 			} | ||||
| 		} | ||||
| 
 | ||||
| 		animation.view.Set(AnimationTag, animation.oldAnimation) | ||||
| 
 | ||||
| 		animation.oldListeners = map[string][]func(View, string){} | ||||
| 		animation.oldAnimation = nil | ||||
| 		animation.view = nil | ||||
| 		animation.listener = nil | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (animation *animationData) Stop() { | ||||
| 	animation.finish() | ||||
| } | ||||
| 
 | ||||
| func (animation *animationData) Pause() { | ||||
| 	if animation.view != nil { | ||||
| 		animation.view.Set(AnimationPaused, true) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (animation *animationData) Resume() { | ||||
| 	if animation.view != nil { | ||||
| 		animation.view.Remove(AnimationPaused) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (animation *animationData) onAnimationStart(view View, _ string) { | ||||
| 	if animation.view != nil && animation.listener != nil { | ||||
| 		animation.listener(animation.view, animation, AnimationStartEvent) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (animation *animationData) onAnimationEnd(view View, _ string) { | ||||
| 	if animation.view != nil { | ||||
| 		if animation.listener != nil { | ||||
| 			animation.listener(animation.view, animation, AnimationEndEvent) | ||||
| 		} | ||||
| 		animation.finish() | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (animation *animationData) onAnimationIteration(view View, _ string) { | ||||
| 	if animation.view != nil && animation.listener != nil { | ||||
| 		animation.listener(animation.view, animation, AnimationIterationEvent) | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (animation *animationData) onAnimationCancel(view View, _ string) { | ||||
| 	if animation.view != nil && animation.listener != nil { | ||||
| 		animation.listener(animation.view, animation, AnimationCancelEvent) | ||||
| 	} | ||||
| } | ||||
|  | @ -299,10 +299,13 @@ type canvasData struct { | |||
| } | ||||
| 
 | ||||
| func newCanvas(view CanvasView) Canvas { | ||||
| 	session := view.Session() | ||||
| 	if !session.canvasStart(view.htmlID()) { | ||||
| 		return nil | ||||
| 	} | ||||
| 	canvas := new(canvasData) | ||||
| 	canvas.view = view | ||||
| 	canvas.session = view.Session() | ||||
| 	canvas.session.canvasStart(view.htmlID()) | ||||
| 	canvas.session = session | ||||
| 	return canvas | ||||
| } | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										47
									
								
								session.go
								
								
								
								
							
							
						
						
									
										47
									
								
								session.go
								
								
								
								
							|  | @ -144,7 +144,9 @@ type Session interface { | |||
| 	sendResponse() | ||||
| 	addAnimationCSS(css string) | ||||
| 	removeAnimation(keyframe string) | ||||
| 	canvasStart(htmlID string) | ||||
| 	htmlPropertyValue(htmlID, name string) string | ||||
| 
 | ||||
| 	canvasStart(htmlID string) bool | ||||
| 	callCanvasFunc(funcName string, args ...any) | ||||
| 	createCanvasVar(funcName string, args ...any) any | ||||
| 	callCanvasVarFunc(v any, funcName string, args ...any) | ||||
|  | @ -152,7 +154,7 @@ type Session interface { | |||
| 	updateCanvasProperty(property string, value any) | ||||
| 	canvasFinish() | ||||
| 	canvasTextMetrics(htmlID, font, text string) TextMetrics | ||||
| 	htmlPropertyValue(htmlID, name string) string | ||||
| 
 | ||||
| 	addToEventsQueue(data DataObject) | ||||
| 	handleAnswer(command string, data DataObject) bool | ||||
| 	handleRootSize(data DataObject) | ||||
|  | @ -427,20 +429,32 @@ func (session *sessionData) appendToInnerHTML(htmlID, html string) { | |||
| } | ||||
| 
 | ||||
| func (session *sessionData) updateCSSProperty(htmlID, property, value string) { | ||||
| 	if !session.ignoreViewUpdates() && session.bridge != nil { | ||||
| 		session.bridge.updateCSSProperty(htmlID, property, value) | ||||
| 	if !session.ignoreViewUpdates() { | ||||
| 		if session.bridge != nil { | ||||
| 			session.bridge.updateCSSProperty(htmlID, property, value) | ||||
| 		} else { | ||||
| 			ErrorLog("No connection") | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (session *sessionData) updateProperty(htmlID, property string, value any) { | ||||
| 	if !session.ignoreViewUpdates() && session.bridge != nil { | ||||
| 		session.bridge.updateProperty(htmlID, property, value) | ||||
| 	if !session.ignoreViewUpdates() { | ||||
| 		if session.bridge != nil { | ||||
| 			session.bridge.updateProperty(htmlID, property, value) | ||||
| 		} else { | ||||
| 			ErrorLog("No connection") | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (session *sessionData) removeProperty(htmlID, property string) { | ||||
| 	if !session.ignoreViewUpdates() && session.bridge != nil { | ||||
| 		session.bridge.removeProperty(htmlID, property) | ||||
| 	if !session.ignoreViewUpdates() { | ||||
| 		if session.bridge != nil { | ||||
| 			session.bridge.removeProperty(htmlID, property) | ||||
| 		} else { | ||||
| 			ErrorLog("No connection") | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
|  | @ -448,18 +462,23 @@ func (session *sessionData) startUpdateScript(htmlID string) bool { | |||
| 	if session.bridge != nil { | ||||
| 		return session.bridge.startUpdateScript(htmlID) | ||||
| 	} | ||||
| 	ErrorLog("No connection") | ||||
| 	return false | ||||
| } | ||||
| 
 | ||||
| func (session *sessionData) finishUpdateScript(htmlID string) { | ||||
| 	if session.bridge != nil { | ||||
| 		session.bridge.finishUpdateScript(htmlID) | ||||
| 	} else { | ||||
| 		ErrorLog("No connection") | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (session *sessionData) sendResponse() { | ||||
| 	if session.bridge != nil { | ||||
| 		session.bridge.sendResponse() | ||||
| 	} else { | ||||
| 		ErrorLog("No connection") | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
|  | @ -467,6 +486,8 @@ func (session *sessionData) addAnimationCSS(css string) { | |||
| 	session.animationCSS += css | ||||
| 	if session.bridge != nil { | ||||
| 		session.bridge.appendAnimationCSS(css) | ||||
| 	} else { | ||||
| 		ErrorLog("No connection") | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
|  | @ -503,14 +524,20 @@ func (session *sessionData) removeAnimation(keyframe string) { | |||
| 		session.animationCSS = css[:index] + css[end:] | ||||
| 		if session.bridge != nil { | ||||
| 			session.bridge.setAnimationCSS(session.animationCSS) | ||||
| 		} else { | ||||
| 			ErrorLog("No connection") | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| func (session *sessionData) canvasStart(htmlID string) { | ||||
| func (session *sessionData) canvasStart(htmlID string) bool { | ||||
| 	if session.bridge != nil { | ||||
| 		session.bridge.canvasStart(htmlID) | ||||
| 		return true | ||||
| 	} | ||||
| 
 | ||||
| 	ErrorLog("No connection") | ||||
| 	return false | ||||
| } | ||||
| 
 | ||||
| func (session *sessionData) callCanvasFunc(funcName string, args ...any) { | ||||
|  | @ -587,6 +614,8 @@ func (session *sessionData) handleAnswer(command string, data DataObject) bool { | |||
| 
 | ||||
| 	if session.bridge != nil { | ||||
| 		session.bridge.sendResponse() | ||||
| 	} else { | ||||
| 		ErrorLog("No connection") | ||||
| 	} | ||||
| 	return true | ||||
| } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue