Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inserting Text from Draggable Data #21

Open
OscarEReyes opened this issue Aug 12, 2018 · 4 comments
Open

Inserting Text from Draggable Data #21

OscarEReyes opened this issue Aug 12, 2018 · 4 comments

Comments

@OscarEReyes
Copy link

I have a widget that contains draggable elements.
I would like to be able to drag these into the text editor to insert text data held by this draggable object.

Would it be possible to display caret position while hovering over the text field? So that it can then be inserted at that position if dropped.

I am not really asking for a solid answer on how to do this.
Just, if it is possible with Zefyr or if I have to make a whole different custom widget centered around this goal.

I figure I just need to display the caret position when I hover over the editor and insert text at the exact position of the caret.

@pulyaevskiy
Copy link
Contributor

It would not be a trivial task to do at this point, though it could be possible.

If you have access to BuildContext of ZefyrEditableText you could try and get ZefyrRenderContext which contains references to all render objects used by the editor and some helper methods like boxForGlobalPoint which returns render object for specified global offset.

Here is some pseudo code:

void _yourDragUpdateHandler(DragUpdateDetails details) {
  // make sure that [someBuildContext] has access to the editor instance.
  final editable = ZefyrEditableText.of(someBuildContext);
  final renderContext = editable.renderContext;
  final box = renderContext.boxForGlobalPoint(details.offset); 
  if (box == null) {
    // there is no editor content at this location on screen
    return;
  }
  // Get caret position in text at this offset.
  final localPoint = box.globalToLocal(globalPoint);
  final pos = box.getPositionForOffset(localPoint);
  // Update selection to point to new position, this would move caret.
  final editor = ZefyrEditor.of(someBuildContext);
  final caret = new TextSelection.collapsed(offset: pos.offset);
  editor.updateSelection(caret, source: ChangeSource.local);
}

In dragEnd handler you'd just need to use Zefyr controller to insert your piece of data at current caret position.

Also see implementation of selection layer for more details:

void _handleDragUpdate(DragUpdateDetails details) {
_dragPosition += details.delta;
final globalPoint = _dragPosition;
final editor = ZefyrEditor.of(context);
final editable = ZefyrEditableText.of(context);
final paragraph = editable.renderContext.boxForGlobalPoint(globalPoint);
if (paragraph == null) {
return;
}
final localPoint = paragraph.globalToLocal(globalPoint);
final position = paragraph.getPositionForOffset(localPoint);
final newSelection = selection.copyWith(
baseOffset: isBaseHandle ? position.offset : selection.baseOffset,
extentOffset: isBaseHandle ? selection.extentOffset : position.offset,
);
if (newSelection.baseOffset >= newSelection.extentOffset) {
// Don't allow reversed or collapsed selection.
return;
}
if (newSelection != _selection) {
editor.updateSelection(newSelection, source: ChangeSource.local);
}
}
}

@pulyaevskiy
Copy link
Contributor

Note that the above APIs are not final yet and are subject to change before stable release. I will be documenting all breaking changes though to try and make upgrades easier.

@OscarEReyes
Copy link
Author

Thank you for your great insights.

Any recommendations on how to get access to the context of ZefyrEditableText?

I initially thought of making a custom editor widget. However, upon forking the repository, I have been unable to get it to work. It refuses to treat is as a flutter project and fails to run flutter packages get.

@pulyaevskiy
Copy link
Contributor

You'll need to open packages/zefyr subdirectory in your IDE to make it work.

Any recommendations on how to get access to the context of ZefyrEditableText?

Good question. There is probably no easy way at this point. Your best bet would be to fork (which you already did) and play with selection overlay part of the editor as a starting point.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants