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