Flutter Engine
The Flutter Engine
Classes | Public Member Functions | List of all members
skottie_utils::TextEditor Class Referencefinal

#include <TextEditor.h>

Inheritance diagram for skottie_utils::TextEditor:
skottie::GlyphDecorator SkRefCnt SkRefCntBase

Public Member Functions

 TextEditor (std::unique_ptr< skottie::TextPropertyHandle > &&, std::vector< std::unique_ptr< skottie::TextPropertyHandle > > &&)
 
 ~TextEditor () override
 
void toggleEnabled ()
 
void setEnabled (bool)
 
void onDecorate (SkCanvas *, const TextInfo &) override
 
bool onMouseInput (SkScalar x, SkScalar y, skui::InputState state, skui::ModifierKey)
 
bool onCharInput (SkUnichar c)
 
void setCursorWeight (float w)
 
virtual void onDecorate (SkCanvas *, const TextInfo &)=0
 
- Public Member Functions inherited from SkRefCntBase
 SkRefCntBase ()
 
virtual ~SkRefCntBase ()
 
bool unique () const
 
void ref () const
 
void unref () const
 

Detailed Description

Definition at line 35 of file TextEditor.h.

Constructor & Destructor Documentation

◆ TextEditor()

skottie_utils::TextEditor::TextEditor ( std::unique_ptr< skottie::TextPropertyHandle > &&  prop,
std::vector< std::unique_ptr< skottie::TextPropertyHandle > > &&  deps 
)

Definition at line 78 of file TextEditor.cpp.

81 : fTextProp(std::move(prop))
82 , fDependentProps(std::move(deps))
83 , fCursorPath(make_cursor_path())
84 , fCursorBounds(fCursorPath.computeTightBounds())
85{}
SkRect computeTightBounds() const
Definition: SkPath.cpp:3446
static SkScalar prop(SkScalar radius, SkScalar newSize, SkScalar oldSize)
Definition: rrect.cpp:83

◆ ~TextEditor()

skottie_utils::TextEditor::~TextEditor ( )
overridedefault

Member Function Documentation

◆ onCharInput()

bool skottie_utils::TextEditor::onCharInput ( SkUnichar  c)

Definition at line 303 of file TextEditor.cpp.

303 {
304 if (!fEnabled || fGlyphData.empty()) {
305 return false;
306 }
307
308 const auto& txt_str = fTextProp->get().fText;
309
310 // Natural editor bindings are currently intercepted by Viewer, so we use these instead.
311 switch (c) {
312 case '|': // commit changes and exit editing mode
313 this->toggleEnabled();
314 break;
315 case ']': { // move right
316 if (fCursorIndex < txt_str.size()) {
317 fCursorIndex = next_utf8(txt_str, fCursorIndex);
318 }
319 } break;
320 case '[': // move left
321 if (fCursorIndex > 0) {
322 fCursorIndex = prev_utf8(txt_str, fCursorIndex);
323 }
324 break;
325 case '\\': { // delete
326 if (!this->deleteSelection() && fCursorIndex > 0) {
327 // Delete preceding char.
328 const auto del_index = prev_utf8(txt_str, fCursorIndex),
329 del_count = fCursorIndex - del_index;
330
331 this->deleteChars(del_index, del_count);
332 }
333 } break;
334 default:
335 // Delete any selection on insert.
336 this->deleteSelection();
337 this->insertChar(c);
338 break;
339 }
340
341 // Reset the cursor blink timer on input.
342 fTimeBase = std::chrono::steady_clock::now();
343
344 return true;
345}
static const char * prev_utf8(const char *p, const char *begin)
Definition: editor.cpp:127
static const char * next_utf8(const char *p, const char *end)
Definition: editor.cpp:111

◆ onDecorate()

void skottie_utils::TextEditor::onDecorate ( SkCanvas canvas,
const TextInfo tinfo 
)
overridevirtual

Implements skottie::GlyphDecorator.

Definition at line 241 of file TextEditor.cpp.

241 {
242 const auto [sel_start, sel_end] = this->currentSelection();
243
244 fGlyphData.clear();
245
246 for (size_t i = 0; i < tinfo.fGlyphs.size(); ++i) {
247 const auto& ginfo = tinfo.fGlyphs[i];
248
249 SkAutoCanvasRestore acr(canvas, true);
250 canvas->concat(ginfo.fMatrix);
251
252 // Stash some glyph info, for later use.
253 fGlyphData.push_back({
254 canvas->getLocalToDevice().asM33().mapRect(ginfo.fBounds),
255 ginfo.fCluster
256 });
257
258 if (i < sel_start || i >= sel_end) {
259 continue;
260 }
261
262 static constexpr SkColor4f kSelectionColor{0, 0, 1, 0.4f};
263 canvas->drawRect(ginfo.fBounds, SkPaint(kSelectionColor));
264 }
265
266 // Only draw the cursor when there's no active selection.
267 if (sel_start == sel_end) {
268 this->drawCursor(canvas, tinfo);
269 }
270}
void drawRect(const SkRect &rect, const SkPaint &paint)
Definition: SkCanvas.cpp:1673
SkM44 getLocalToDevice() const
Definition: SkCanvas.cpp:1633
void concat(const SkMatrix &matrix)
Definition: SkCanvas.cpp:1318

◆ onMouseInput()

bool skottie_utils::TextEditor::onMouseInput ( SkScalar  x,
SkScalar  y,
skui::InputState  state,
skui::ModifierKey   
)

Definition at line 272 of file TextEditor.cpp.

273 {
274 if (!fEnabled || fGlyphData.empty()) {
275 return false;
276 }
277
278 switch (state) {
280 fMouseDown = true;
281
282 const auto closest = this->closestGlyph({x, y});
283 fSelection = {closest, closest};
284 } break;
286 fMouseDown = false;
287 break;
289 if (fMouseDown) {
290 const auto closest = this->closestGlyph({x, y});
291 std::get<1>(fSelection) = closest < std::get<0>(fSelection)
292 ? closest
293 : closest + 1;
294 }
295 break;
296 default:
297 break;
298 }
299
300 return true;
301}
AtkStateType state
double y
double x
const myers::Point & get< 1 >(const myers::Segment &s)
Definition: Myers.h:81
const myers::Point & get< 0 >(const myers::Segment &s)
Definition: Myers.h:80

◆ setCursorWeight()

void skottie_utils::TextEditor::setCursorWeight ( float  w)
inline

Definition at line 50 of file TextEditor.h.

50{ fCursorWeight = w; }
SkScalar w

◆ setEnabled()

void skottie_utils::TextEditor::setEnabled ( bool  enabled)

Definition at line 104 of file TextEditor.cpp.

104 {
105 if (enabled != fEnabled) {
106 this->toggleEnabled();
107 }
108}

◆ toggleEnabled()

void skottie_utils::TextEditor::toggleEnabled ( )

Definition at line 89 of file TextEditor.cpp.

89 {
90 fEnabled = !fEnabled;
91
92 auto txt = fTextProp->get();
93 txt.fDecorator = fEnabled ? sk_ref_sp(this) : nullptr;
94 fTextProp->set(txt);
95
96 if (fEnabled) {
97 // Always reset the cursor position to the end.
98 fCursorIndex = txt.fText.size();
99 }
100
101 fTimeBase = std::chrono::steady_clock::now();
102}
sk_sp< T > sk_ref_sp(T *obj)
Definition: SkRefCnt.h:381

The documentation for this class was generated from the following files: