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 "modules/skottie/include/SkottieProperty.h" 13 #include "tools/skui/InputState.h" 14 #include "tools/skui/ModifierKey.h" 15 16 #include <chrono> 17 18 // A sample WYSIWYG text editor built using the GlyphDecorator API. 19 class SkottieTextEditor final : public skottie::GlyphDecorator { 20 public: 21 explicit SkottieTextEditor(std::unique_ptr<skottie::TextPropertyHandle>&&, 22 std::vector<std::unique_ptr<skottie::TextPropertyHandle>>&&); 23 ~SkottieTextEditor() override; 24 25 void toggleEnabled(); 26 27 void onDecorate(SkCanvas*, const GlyphInfo[], size_t) override; 28 29 bool onMouseInput(SkScalar x, SkScalar y, skui::InputState state, skui::ModifierKey); 30 31 bool onCharInput(SkUnichar c); 32 33 private: 34 struct GlyphData { 35 SkRect fDevBounds; // Glyph bounds mapped to device space. 36 size_t fCluster; // UTF8 cluster index. 37 }; 38 39 std::tuple<size_t, size_t> currentSelection() const; 40 size_t closestGlyph(const SkPoint& pt) const; 41 void drawCursor(SkCanvas*, const GlyphInfo glyphs[], size_t size) const; 42 void insertChar(SkUnichar c); 43 void deleteChars(size_t offset, size_t count); 44 bool deleteSelection(); 45 void updateDeps(const SkString&); 46 47 const std::unique_ptr<skottie::TextPropertyHandle> fTextProp; 48 const std::vector<std::unique_ptr<skottie::TextPropertyHandle>> fDependentProps; 49 const SkPath fCursorPath; 50 const SkRect fCursorBounds; 51 52 std::vector<GlyphData> fGlyphData; 53 std::tuple<size_t, size_t> fSelection = {0,0}; // Indices in the glyphs domain. 54 size_t fCursorIndex = 0; // Index in the UTF8 domain. 55 bool fEnabled = false; 56 bool fMouseDown = false; 57 58 std::chrono::time_point<std::chrono::steady_clock> fTimeBase; 59 }; 60 61 #endif // SkottieTextEditor_DEFINED 62