xref: /aosp_15_r20/external/skia/modules/skottie/utils/TextEditor.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
2  * Copyright 2022 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 SkottieTextEditor_DEFINED
9 #define SkottieTextEditor_DEFINED
10 
11 #include "include/core/SkPath.h"
12 #include "include/core/SkRect.h"
13 #include "include/core/SkScalar.h"
14 #include "include/core/SkTypes.h"
15 #include "modules/skottie/include/SkottieProperty.h"
16 
17 #include <chrono>
18 #include <cstddef>
19 #include <memory>
20 #include <tuple>
21 #include <vector>
22 
23 class SkCanvas;
24 class SkString;
25 struct SkPoint;
26 
27 namespace skui {
28 enum class InputState;
29 enum class ModifierKey;
30 }  // namespace skui
31 
32 namespace skottie_utils {
33 
34 // A sample WYSIWYG text editor built using the GlyphDecorator API.
35 class TextEditor final : public skottie::GlyphDecorator {
36 public:
37     TextEditor(std::unique_ptr<skottie::TextPropertyHandle>&&,
38                std::vector<std::unique_ptr<skottie::TextPropertyHandle>>&&);
39     ~TextEditor() override;
40 
41     void toggleEnabled();
42     void setEnabled(bool);
43 
44     void onDecorate(SkCanvas*, const TextInfo&) override;
45 
46     bool onMouseInput(SkScalar x, SkScalar y, skui::InputState state, skui::ModifierKey);
47 
48     bool onCharInput(SkUnichar c);
49 
setCursorWeight(float w)50     void setCursorWeight(float w) { fCursorWeight = w; }
51 
52 private:
53     struct GlyphData {
54         SkRect fDevBounds; // Glyph bounds mapped to device space.
55         size_t fCluster;   // UTF8 cluster index.
56     };
57 
58     std::tuple<size_t, size_t> currentSelection() const;
59     size_t closestGlyph(const SkPoint& pt) const;
60     void drawCursor(SkCanvas*, const TextInfo&) const;
61     void insertChar(SkUnichar c);
62     void deleteChars(size_t offset, size_t count);
63     bool deleteSelection();
64     void updateDeps(const SkString&);
65 
66     const std::unique_ptr<skottie::TextPropertyHandle>              fTextProp;
67     const std::vector<std::unique_ptr<skottie::TextPropertyHandle>> fDependentProps;
68     const SkPath                                                    fCursorPath;
69     const SkRect                                                    fCursorBounds;
70 
71     std::vector<GlyphData>     fGlyphData;
72     std::tuple<size_t, size_t> fSelection    = {0,0};  // Indices in the glyphs domain.
73     size_t                     fCursorIndex  = 0;      // Index in the UTF8 domain.
74     float                      fCursorWeight = 1;
75     bool                       fEnabled      = false;
76     bool                       fMouseDown    = false;
77 
78     std::chrono::time_point<std::chrono::steady_clock> fTimeBase;
79 };
80 
81 }  // namespace skottie_utils
82 
83 #endif // SkottieTextEditor_DEFINED
84