1/*
2 * Copyright 2018 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#ifndef SkottieUtils_DEFINED
9#define SkottieUtils_DEFINED
10
11#include "modules/skottie/include/Skottie.h"
12#include "modules/skottie/include/SkottieProperty.h"
13
14#include <memory>
15#include <string>
16#include <unordered_map>
17#include <vector>
18
19namespace skottie_utils {
20
21/**
22 * CustomPropertyManager implements a property management scheme where color/opacity/transform
23 * attributes are grouped and manipulated by name (one-to-many mapping).
24 *
25 * - setters apply the value to all properties in a named group
26 *
27 * - getters return all the managed property groups, and the first value within each of them
28 * (unchecked assumption: all properties within the same group have the same value)
29 *
30 * Attach to an Animation::Builder using the utility methods below to intercept properties and
31 * markers at build time.
32 */
33class CustomPropertyManager final {
34public:
35 CustomPropertyManager();
36 ~CustomPropertyManager();
37
38 using PropKey = std::string;
39
40 std::vector<PropKey> getColorProps() const;
41 skottie::ColorPropertyValue getColor(const PropKey&) const;
42 bool setColor(const PropKey&, const skottie::ColorPropertyValue&);
43
44 std::vector<PropKey> getOpacityProps() const;
45 skottie::OpacityPropertyValue getOpacity(const PropKey&) const;
46 bool setOpacity(const PropKey&, const skottie::OpacityPropertyValue&);
47
48 std::vector<PropKey> getTransformProps() const;
49 skottie::TransformPropertyValue getTransform(const PropKey&) const;
50 bool setTransform(const PropKey&, const skottie::TransformPropertyValue&);
51
52 std::vector<PropKey> getTextProps() const;
53 skottie::TextPropertyValue getText(const PropKey&) const;
54 bool setText(const PropKey&, const skottie::TextPropertyValue&);
55
56 struct MarkerInfo {
57 std::string name;
58 float t0, t1;
59 };
60 const std::vector<MarkerInfo>& markers() const { return fMarkers; }
61
62 // Returns a property observer to be attached to an animation builder.
63 sk_sp<skottie::PropertyObserver> getPropertyObserver() const;
64
65 // Returns a marker observer to be attached to an animation builder.
66 sk_sp<skottie::MarkerObserver> getMarkerObserver() const;
67
68private:
69 class PropertyInterceptor;
70 class MarkerInterceptor;
71
72 static std::string acceptKey(const char* name) {
73 static constexpr char kPrefix = '$';
74
75 return (name[0] == kPrefix && name[1] != '\0')
76 ? std::string(name + 1)
77 : std::string();
78 }
79
80 sk_sp<PropertyInterceptor> fPropertyInterceptor;
81 sk_sp<MarkerInterceptor> fMarkerInterceptor;
82
83 template <typename T>
84 using PropGroup = std::vector<std::unique_ptr<T>>;
85
86 template <typename T>
87 using PropMap = std::unordered_map<PropKey, PropGroup<T>>;
88
89 template <typename T>
90 std::vector<PropKey> getProps(const PropMap<T>& container) const;
91
92 template <typename V, typename T>
93 V get(const PropKey&, const PropMap<T>& container) const;
94
95 template <typename V, typename T>
96 bool set(const PropKey&, const V&, const PropMap<T>& container);
97
98 PropMap<skottie::ColorPropertyHandle> fColorMap;
99 PropMap<skottie::OpacityPropertyHandle> fOpacityMap;
100 PropMap<skottie::TransformPropertyHandle> fTransformMap;
101 PropMap<skottie::TextPropertyHandle> fTextMap;
102 std::vector<MarkerInfo> fMarkers;
103 std::string fCurrentNode;
104};
105
106} // namespace skottie_utils
107
108#endif // SkottieUtils_DEFINED
109