Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,59 @@ public interface ScribeMethodHandler {
void startStylusHandwriting();
}

// TODO(justinmc): Scribe stylus gestures should be supported here.
// https://github.com/flutter/flutter/issues/156018
public void previewHandwritingGesture(
PreviewableHandwritingGesture gesture, CancellationSignal cancellationSignal) {
System.out.println("justin sending previewHandwritingGesture for gesture: " + gesture);
final HashMap<Object, Object> gestureMap = new HashMap<>();
if (gesture instanceof DeleteGesture) {
gestureMap.put("type", "delete");
} else if (gesture instanceof DeleteRangeGesture) {
gestureMap.put("type", "deleteRange");
} else if (gesture instanceof SelectGesture) {
gestureMap.put("type", "select");
} else if (gesture instanceof SelectRangeGesture) {
gestureMap.put("type", "selectRange");
} else {
return;
}

// TODO(justinmc): You'll need to provide some kind of API that allows users
// to cancel a previewed gesture. Maybe keep ahold of cancellationSignal
// here, then provide platform channel methods for cancel, isCanceled,
// setOnCancelListener, and throwIfCanceled.
channel.invokeMethod("ScribeClient.previewHandwritingGesture", gestureMap);
}

public void performHandwritingGesture(HandwritingGesture gesture, MethodChannel.Result result) {
System.out.println("justin sending performHandwritingGesture for gesture: " + gesture);

final HashMap<Object, Object> gestureMap = new HashMap<>();
if (gesture instanceof SelectGesture) {
final SelectGesture selectGesture = (SelectGesture) gesture;
final HashMap<Object, Object> selectionAreaMap = new HashMap<>();
final RectF selectionArea = selectGesture.getSelectionArea();
selectionAreaMap.put("bottom", selectionArea.bottom);
selectionAreaMap.put("top", selectionArea.top);
selectionAreaMap.put("left", selectionArea.left);
selectionAreaMap.put("right", selectionArea.right);
gestureMap.put("type", "select");
gestureMap.put("granularity", selectGesture.getGranularity());
gestureMap.put("selectionArea", selectionAreaMap);
} else if (gesture instanceof DeleteGesture) {
final DeleteGesture deleteGesture = (DeleteGesture) gesture;
final HashMap<Object, Object> deletionAreaMap = new HashMap<>();
final RectF deletionArea = deleteGesture.getDeletionArea();
deletionAreaMap.put("bottom", deletionArea.bottom);
deletionAreaMap.put("top", deletionArea.top);
deletionAreaMap.put("left", deletionArea.left);
deletionAreaMap.put("right", deletionArea.right);
gestureMap.put("type", "delete");
gestureMap.put("granularity", deleteGesture.getGranularity());
gestureMap.put("deletionArea", deletionAreaMap);
}
// TODO(justinmc): All other gestures.
// https://developer.android.com/reference/android/view/inputmethod/HandwritingGesture#public-methods

channel.invokeMethod("ScribeClient.performHandwritingGesture", gestureMap, result);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.CancellationSignal;
import android.text.DynamicLayout;
import android.text.Editable;
import android.text.InputType;
Expand All @@ -26,21 +27,26 @@
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.ExtractedText;
import android.view.inputmethod.ExtractedTextRequest;
import android.view.inputmethod.HandwritingGesture;
import android.view.inputmethod.InputContentInfo;
import android.view.inputmethod.InputMethodManager;
import android.view.inputmethod.PreviewableHandwritingGesture;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.core.view.inputmethod.InputConnectionCompat;
import io.flutter.Log;
import io.flutter.embedding.engine.FlutterJNI;
import io.flutter.embedding.engine.systemchannels.ScribeChannel;
import io.flutter.embedding.engine.systemchannels.TextInputChannel;
import io.flutter.plugin.common.MethodChannel;
import java.io.ByteArrayOutputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Executor;
import java.util.function.IntConsumer;

public class InputConnectionAdaptor extends BaseInputConnection
implements ListenableEditingState.EditingStateWatcher {
Expand Down Expand Up @@ -275,9 +281,44 @@ public boolean setSelection(int start, int end) {
return result;
}

// TODO(justinmc): Scribe stylus gestures should be supported here via
// performHandwritingGesture.
// https://github.com/flutter/flutter/issues/156018
@Override
public boolean previewHandwritingGesture(
PreviewableHandwritingGesture gesture, CancellationSignal cancellationSignal) {
System.out.println(
"justin previewHandwritingGesture gesture: " + gesture + ", " + cancellationSignal);

scribeChannel.previewHandwritingGesture(gesture, cancellationSignal);
return true;
}

@Override
public void performHandwritingGesture(
HandwritingGesture gesture, Executor executor, IntConsumer consumer) {
System.out.println("justin performHandwritingGesture gesture: " + gesture);

final MethodChannel.Result result =
new MethodChannel.Result() {
@Override
public void success(Object result) {
executor.execute(() -> consumer.accept(HANDWRITING_GESTURE_RESULT_SUCCESS));
}

@Override
public void error(String errorCode, String errorMessage, Object errorDetails) {
executor.execute(() -> consumer.accept(HANDWRITING_GESTURE_RESULT_FAILED));
}

@Override
public void notImplemented() {
executor.execute(() -> consumer.accept(HANDWRITING_GESTURE_RESULT_UNSUPPORTED));
}
// TODO(justinmc): There are a few other HANDWRITING_GESTURE_RESULTs
// that may be useful, see
// https://developer.android.com/reference/android/view/inputmethod/InputConnection
};

scribeChannel.performHandwritingGesture((HandwritingGesture) gesture, result);
}

// Sanitizes the index to ensure the index is within the range of the
// contents of editable.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,17 @@
import android.view.autofill.AutofillId;
import android.view.autofill.AutofillManager;
import android.view.autofill.AutofillValue;
import android.view.inputmethod.DeleteGesture;
import android.view.inputmethod.DeleteRangeGesture;
import android.view.inputmethod.EditorInfo;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputMethodManager;
import android.view.inputmethod.InsertGesture;
import android.view.inputmethod.InsertModeGesture;
import android.view.inputmethod.JoinOrSplitGesture;
import android.view.inputmethod.RemoveSpaceGesture;
import android.view.inputmethod.SelectGesture;
import android.view.inputmethod.SelectRangeGesture;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
Expand All @@ -34,7 +42,9 @@
import io.flutter.embedding.engine.systemchannels.TextInputChannel.TextEditState;
import io.flutter.plugin.platform.PlatformViewsController;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Set;

/** Android implementation of the text input plugin. */
public class TextInputPlugin implements ListenableEditingState.EditingStateWatcher {
Expand Down Expand Up @@ -350,10 +360,25 @@ public InputConnection createInputConnection(
if (Build.VERSION.SDK_INT >= API_LEVELS.API_34) {
EditorInfoCompat.setStylusHandwritingEnabled(outAttrs, true);
}
// TODO(justinmc): Scribe stylus gestures should be supported here via
// outAttrs.setSupportedHandwritingGestures and
// outAttrs.setSupportedHandwritingGesturePreviews.
// https://github.com/flutter/flutter/issues/156018

EditorInfoCompat.setStylusHandwritingEnabled(outAttrs, true);
outAttrs.setSupportedHandwritingGestures(
Arrays.asList(
SelectGesture.class,
SelectRangeGesture.class,
InsertGesture.class,
InsertModeGesture.class,
DeleteGesture.class,
DeleteRangeGesture.class,
SelectRangeGesture.class,
JoinOrSplitGesture.class,
RemoveSpaceGesture.class));
outAttrs.setSupportedHandwritingGesturePreviews(
Set.of(
SelectGesture.class,
SelectRangeGesture.class,
DeleteGesture.class,
DeleteRangeGesture.class));

InputConnectionAdaptor connection =
new InputConnectionAdaptor(
Expand Down
Loading