mirror of
https://github.com/google/pebble.git
synced 2025-11-19 22:11:02 -05:00
Import of the watch repository from Pebble
This commit is contained in:
286
src/fw/applib/legacy2/ui/animation_legacy2.h
Normal file
286
src/fw/applib/legacy2/ui/animation_legacy2.h
Normal file
@@ -0,0 +1,286 @@
|
||||
/*
|
||||
* Copyright 2024 Google LLC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "util/list.h"
|
||||
#include "drivers/rtc.h"
|
||||
#include "applib/ui/animation.h"
|
||||
|
||||
//! @file animation.h
|
||||
//! @addtogroup UI
|
||||
//! @{
|
||||
//! @addtogroup AnimationLegacy2
|
||||
//! \brief Abstract framework to create arbitrary animations
|
||||
//!
|
||||
//! The AnimationLegacy2 framework provides your Pebble app with an base layer to create arbitrary
|
||||
//! animations. The simplest way to work with animations is to use the layer frame
|
||||
//! \ref PropertyAnimationLegacy2, which enables you to move a Layer around on the screen.
|
||||
//! Using animation_legacy2_set_implementation(), you can implement a custom animation.
|
||||
//!
|
||||
|
||||
|
||||
//! @{
|
||||
|
||||
///////////////////
|
||||
// Base AnimationLegacy2
|
||||
//
|
||||
|
||||
struct AnimationLegacy2;
|
||||
struct AnimationLegacy2Implementation;
|
||||
struct AnimationLegacy2Handlers;
|
||||
|
||||
|
||||
//! Creates a new AnimationLegacy2 on the heap and initalizes it with the default values.
|
||||
//!
|
||||
//! * Duration: 250ms,
|
||||
//! * Curve: \ref AnimationCurveEaseInOut (ease-in-out),
|
||||
//! * Delay: 0ms,
|
||||
//! * Handlers: `{NULL, NULL}` (none),
|
||||
//! * Context: `NULL` (none),
|
||||
//! * Implementation: `NULL` (no implementation),
|
||||
//! * Scheduled: no
|
||||
//! @return A pointer to the animation. `NULL` if the animation could not
|
||||
//! be created
|
||||
struct AnimationLegacy2 *animation_legacy2_create(void);
|
||||
|
||||
//! Destroys an AnimationLegacy2 previously created by animation_legacy2_create.
|
||||
void animation_legacy2_destroy(struct AnimationLegacy2 *animation);
|
||||
|
||||
//! @internal
|
||||
//! resets animation to default values (see animation_create)
|
||||
void animation_legacy2_init(struct AnimationLegacy2 *animation);
|
||||
|
||||
//! Sets the time in milliseconds that an animation takes from start to finish.
|
||||
//! @param animation The animation for which to set the duration.
|
||||
//! @param duration_ms The duration in milliseconds of the animation. This excludes
|
||||
//! any optional delay as set using \ref animation_legacy2_set_delay().
|
||||
void animation_legacy2_set_duration(struct AnimationLegacy2 *animation, uint32_t duration_ms);
|
||||
|
||||
//! Sets an optional delay for the animation.
|
||||
//! @param animation The animation for which to set the delay.
|
||||
//! @param delay_ms The delay in milliseconds that the animation system should
|
||||
//! wait from the moment the animation is scheduled to starting the animation.
|
||||
void animation_legacy2_set_delay(struct AnimationLegacy2 *animation, uint32_t delay_ms);
|
||||
|
||||
//! Sets the animation curve for the animation.
|
||||
//! @param animation The animation for which to set the curve.
|
||||
//! @param curve The type of curve.
|
||||
//! @see AnimationCurve
|
||||
void animation_legacy2_set_curve(struct AnimationLegacy2 *animation, AnimationCurve curve);
|
||||
|
||||
//! Sets a custom animation curve function.
|
||||
//! @param animation The animation for which to set the curve.
|
||||
//! @param curve_function The custom animation curve function.
|
||||
//! @see AnimationCurveFunction
|
||||
void animation_legacy2_set_custom_curve(struct AnimationLegacy2 *animation,
|
||||
AnimationCurveFunction curve_function);
|
||||
|
||||
//! Gets the custom animation curve function.
|
||||
//! @param animation The animation for which to get the curve.
|
||||
//! @return The custom animation curve function for the given animation. NULL if not set.
|
||||
//! @see AnimationCurveFunction
|
||||
AnimationCurveFunction animation_legacy2_get_custom_curve(struct AnimationLegacy2 *animation);
|
||||
|
||||
//! The function pointer type of the handler that will be called when an animation is started,
|
||||
//! just before updating the first frame of the animation.
|
||||
//! @param animation The animation that was started.
|
||||
//! @param context The pointer to custom, application specific data, as set using
|
||||
//! \ref animation_legacy2_set_handlers()
|
||||
//! @note This is called after any optional delay as set by \ref animation_legacy2_set_delay()
|
||||
//! has expired.
|
||||
//! @see animation_legacy2_set_handlers
|
||||
typedef void (*AnimationLegacy2StartedHandler)(struct AnimationLegacy2 *animation, void *context);
|
||||
|
||||
//! The function pointer type of the handler that will be called when the animation is stopped.
|
||||
//! @param animation The animation that was stopped.
|
||||
//! @param finished True if the animation was stopped because it was finished normally,
|
||||
//! or False if the animation was stopped prematurely, because it was unscheduled before finishing.
|
||||
//! @param context The pointer to custom, application specific data, as set using
|
||||
//! \ref animation_legacy2_set_handlers()
|
||||
//! @see animation_legacy2_set_handlers
|
||||
typedef void (*AnimationLegacy2StoppedHandler)(struct AnimationLegacy2 *animation, bool finished,
|
||||
void *context);
|
||||
|
||||
//! The handlers that will get called when an animation starts and stops.
|
||||
//! See documentation with the function pointer types for more information.
|
||||
//! @see animation_legacy2_set_handlers
|
||||
typedef struct AnimationLegacy2Handlers {
|
||||
//! The handler that will be called when an animation is started.
|
||||
AnimationLegacy2StartedHandler started;
|
||||
//! The handler that will be called when an animation is stopped.
|
||||
AnimationLegacy2StoppedHandler stopped;
|
||||
} AnimationLegacy2Handlers;
|
||||
|
||||
//! Sets the callbacks for the animation.
|
||||
//! Often an application needs to run code at the start or at the end of an animation.
|
||||
//! Using this function is possible to register callback functions with an animation,
|
||||
//! that will get called at the start and end of the animation.
|
||||
//! @param animation The animation for which to set up the callbacks.
|
||||
//! @param callbacks The callbacks.
|
||||
//! @param context A pointer to application specific data, that will be passed as an argument by
|
||||
//! the animation subsystem when a callback is called.
|
||||
void animation_legacy2_set_handlers(struct AnimationLegacy2 *animation,
|
||||
AnimationLegacy2Handlers callbacks, void *context);
|
||||
|
||||
//! Gets the application-specific callback context of the animation.
|
||||
//! This `void` pointer is passed as an argument when the animation system calls AnimationHandlers
|
||||
//! callbacks. The context pointer can be set to point to any application specific data using
|
||||
//! \ref animation_legacy2_set_handlers().
|
||||
//! @param animation The animation.
|
||||
//! @see animation_legacy2_set_handlers
|
||||
void *animation_legacy2_get_context(struct AnimationLegacy2 *animation);
|
||||
|
||||
//! Schedules the animation. Call this once after configuring an animation to get it to
|
||||
//! start running.
|
||||
//!
|
||||
//! If the animation's implementation has a `.setup` callback it will get called before
|
||||
//! this function returns.
|
||||
//!
|
||||
//! @note If the animation was already scheduled,
|
||||
//! it will first unschedule it and then re-schedule it again.
|
||||
//! Note that in that case, the animation's `.stopped` handler, the implementation's
|
||||
//! `.teardown` and `.setup` will get called, due to the unscheduling and scheduling.
|
||||
//! @param animation The animation to schedule.
|
||||
//! @see \ref animation_legacy2_unschedule()
|
||||
void animation_legacy2_schedule(struct AnimationLegacy2 *animation);
|
||||
|
||||
//! Unschedules the animation, which in effect stops the animation.
|
||||
//! @param animation The animation to unschedule.
|
||||
//! @note If the animation was not yet finished, unscheduling it will
|
||||
//! cause its `.stopped` handler to get called, with the "finished" argument set to false.
|
||||
//! @see \ref animation_legacy2_schedule()
|
||||
void animation_legacy2_unschedule(struct AnimationLegacy2 *animation);
|
||||
|
||||
//! Unschedules all animations of the application.
|
||||
//! @see animation_legacy2_unschedule
|
||||
void animation_legacy2_unschedule_all(void);
|
||||
|
||||
//! @return True if the animation was scheduled, or false if it was not.
|
||||
//! @note An animation will be scheduled when it is running and not finished yet.
|
||||
//! An animation that has finished is automatically unscheduled.
|
||||
//! @param animation The animation for which to get its scheduled state.
|
||||
//! @see animation_legacy2_schedule
|
||||
//! @see animation_legacy2_unschedule
|
||||
bool animation_legacy2_is_scheduled(struct AnimationLegacy2 *animation);
|
||||
|
||||
//! The data structure of an animation.
|
||||
typedef struct AnimationLegacy2 {
|
||||
ListNode list_node;
|
||||
const struct AnimationLegacy2Implementation *implementation;
|
||||
AnimationLegacy2Handlers handlers;
|
||||
void *context;
|
||||
//! Absolute time when the animation got scheduled, in ms since system start.
|
||||
uint32_t abs_start_time_ms;
|
||||
uint32_t delay_ms;
|
||||
uint32_t duration_ms;
|
||||
AnimationCurve curve:3;
|
||||
bool is_completed:1;
|
||||
//! Pointer to a custom curve. Unfortunately, due to backward-compatibility
|
||||
//! constraints, it must fit into 28 bits.
|
||||
//! It is only valid when curve == AnimationCurveCustomFunction.
|
||||
//! The mapping from 28-bit field to pointer is unpublished. Call
|
||||
//! animation_legacy2_set_custom_curve() to ensure your app continues to run
|
||||
//! after future Pebble updates.
|
||||
uintptr_t custom_curve_function:28;
|
||||
} AnimationLegacy2;
|
||||
|
||||
///////////////////////////////////////
|
||||
// Implementing custom animation types
|
||||
|
||||
//! Pointer to function that (optionally) prepares the animation for running.
|
||||
//! This callback is called when the animation is added to the scheduler.
|
||||
//! @param animation The animation that needs to be set up.
|
||||
//! @see animation_legacy2_schedule
|
||||
//! @see AnimationTeardownImplementation
|
||||
typedef void (*AnimationLegacy2SetupImplementation)(struct AnimationLegacy2 *animation);
|
||||
|
||||
//! Pointer to function that updates the animation according to the given normalized distance.
|
||||
//! This callback will be called repeatedly by the animation scheduler whenever the animation needs
|
||||
//! to be updated.
|
||||
//! @param animation The animation that needs to update; gets passed in by the animation framework.
|
||||
//! @param distance_normalized The current normalized distance; gets passed in by the animation
|
||||
//! framework for each animation frame.
|
||||
//! This is a value between \ref ANIMATION_NORMALIZED_MIN and \ref ANIMATION_NORMALIZED_MAX.
|
||||
//! At the start of the animation, the value will be \ref ANIMATION_NORMALIZED_MIN.
|
||||
//! At the end of the animation, the value will be \ref ANIMATION_NORMALIZED_MAX.
|
||||
//! For each frame during the animation, the value will be the distance along the
|
||||
//! animation path, mapped between \ref ANIMATION_NORMALIZED_MIN and
|
||||
//! \ref ANIMATION_NORMALIZED_MAX based on the animation duration and the
|
||||
//! \ref AnimationCurve set.
|
||||
//! For example, say an animation was scheduled at t = 1.0s, has a delay of 1.0s,
|
||||
//! a duration of 2.0s and a curve of AnimationCurveLinear.
|
||||
//! Then the .update callback will get called on t = 2.0s with
|
||||
//! distance_normalized = \ref ANIMATION_NORMALIZED_MIN. For each frame
|
||||
//! thereafter until t = 4.0s, the update callback will get called where
|
||||
//! distance_normalized is
|
||||
//! (\ref ANIMATION_NORMALIZED_MIN + (((\ref ANIMATION_NORMALIZED_MAX -
|
||||
//! \ref ANIMATION_NORMALIZED_MIN) * t) / duration)).
|
||||
//! Other animation curves will result in a non-linear relation between
|
||||
//! distance_normalized and time.
|
||||
//! @internal
|
||||
//! @see animation_legacy2_timing.h
|
||||
typedef void (*AnimationLegacy2UpdateImplementation)(struct AnimationLegacy2 *animation,
|
||||
const uint32_t distance_normalized);
|
||||
|
||||
//! Pointer to function that (optionally) cleans up the animation.
|
||||
//! This callback is called when the animation is removed from the scheduler.
|
||||
//! In case the `.setup` implementation
|
||||
//! allocated any memory, this is a good place to release that memory again.
|
||||
//! @param animation The animation that needs to be teared down.
|
||||
//! @see animation_legacy2_unschedule
|
||||
//! @see AnimationSetupImplementation
|
||||
typedef void (*AnimationLegacy2TeardownImplementation)(struct AnimationLegacy2 *animation);
|
||||
|
||||
//! The 3 callbacks that implement a custom animation.
|
||||
//! Only the `.update` callback is mandatory, `.setup` and `.teardown` are optional.
|
||||
//! See the documentation with the function pointer typedefs for more information.
|
||||
//!
|
||||
//! @note The `.setup` callback is called immediately after scheduling the animation,
|
||||
//! regardless if there is a delay set for that animation using \ref animation_legacy2_set_delay().
|
||||
//!
|
||||
//! The diagram below illustrates the order in which callbacks can be expected to get called
|
||||
//! over the life cycle of an animation. It also illustrates where the implementation of
|
||||
//! different animation callbacks are intended to be “living”.
|
||||
//! 
|
||||
//!
|
||||
//! @see AnimationLegacy2SetupImplementation
|
||||
//! @see AnimationLegacy2UpdateImplementation
|
||||
//! @see AnimationLegacy2TeardownImplementation
|
||||
typedef struct AnimationLegacy2Implementation {
|
||||
//! Called by the animation system when an animation is scheduled, to prepare it for running.
|
||||
//! This callback is optional and can be left `NULL` when not needed.
|
||||
AnimationLegacy2SetupImplementation setup;
|
||||
//! Called by the animation system when the animation needs to calculate the next animation frame.
|
||||
//! This callback is mandatory and should not be left `NULL`.
|
||||
AnimationLegacy2UpdateImplementation update;
|
||||
//! Called by the animation system when an animation is unscheduled, to clean up after it has run.
|
||||
//! This callback is optional and can be left `NULL` when not needed.
|
||||
AnimationLegacy2TeardownImplementation teardown;
|
||||
} AnimationLegacy2Implementation;
|
||||
|
||||
//! Sets the implementation of the custom animation.
|
||||
//! When implementing custom animations, use this function to specify what functions need to be called to
|
||||
//! for the setup, frame update and teardown of the animation.
|
||||
//! @param animation The animation for which to set the implementation.
|
||||
//! @param implementation The structure with function pointers to the implementation of the setup, update and teardown functions.
|
||||
//! @see AnimationImplementation
|
||||
void animation_legacy2_set_implementation(struct AnimationLegacy2 *animation,
|
||||
const AnimationLegacy2Implementation *implementation);
|
||||
|
||||
//! @} // group AnimationLegacy2
|
||||
//! @} // group UI
|
||||
Reference in New Issue
Block a user