iink SDK on Device

Answered

Update theme interactively

I am trying to provide a UI where the user can adjust font size and line spacing interactively with sliders.

However, the styling reference page mentions this about font size and line size:

https://developer.myscript.com/docs/interactive-ink/1.4/reference/styling/

"In both cases, to avoid visual artifacts, you should change the editor theme before opening the part."

So is there a recommended way of adjusting the theme interactively?

For example, do I need to

- Save the content, close the editor view, close the content part, close the content package

- Set the new theme

- Reopen everything closed above

Or can I only do a subset of the above?

I am using version 1.4 of the IINK SDK for Android.


Best Answer

Dear Nicolas,


currently, the error is indicated in the log, the SetViewSize has indeed not been done.


You shall indeed ensure it has been done:


_editor = _engine.CreateEditor(_renderer);
_editor.SetViewSize((int)ActualWidth, (int)ActualHeight);
_editor.SetFontMetricsProvider(new FontMetricsProvider(_dpiX, dpiY));
_editor.AddListener(new EditorListener(this));


Best regards,


Olivier


Dear Nicolas,


Thank you for contacting us.


Currently, the theme can be changed dynamically, but in the case of the font-size and line-height, this can indeed have unexpected changes (e.g. the ink located at the rigth will no longer be visible).


You shall then close and re-open all the following elements to avoid such behavior:

-Close editor

-close part

-close package.


Then, proceed the opposite way:

-Create editor

-set theme

-create package

-create part


Best regards,


Olivier

Thank you for your reply Olivier.

I tried implementing what you described above, but the app crashes as soon as I touch the screen following the operations you described.

This is my code to try to change the theme. I ran it with the debugger and it seems to complete successfully. But the app crashes when I touch the screen after its execution.

StringBuilder theme = new StringBuilder();
theme.append(".text { font-size: ").append(fontSize).append("; line-height: 1.3 }");

try {
contentPackage.save();
} catch (IOException e) {
e.printStackTrace();
}
editorView.close();

// close contentPart and set its reference to null
if (contentPart != null) {
contentPart.close();
contentPart = null;
}

// then close contentPackage and set its reference to null
if (contentPackage != null) {
contentPackage.close();
contentPackage = null;
}

editorView.setEngine(engine);

editorView.setInputControllerListener(new CustomIInputControllerListener());

editor = editorView.getEditor();
assert editor != null;

editor.addListener(new IinkListener());

editor.setTheme(theme.toString());

File file = new File(getFilesDir(), packageName);
try {
if (file.exists()) {
contentPackage = engine.openPackage(file);
contentPart = contentPackage.getPart(0);
} else {
contentPackage = engine.createPackage(file);
contentPart = contentPackage.createPart(PART_TYPE);
}
} catch (IOException e) {
Log.e(TAG, "Failed to open package \"" + packageName + "\".");
e.printStackTrace();
return;
}

// wait for view size initialization before setting part
editorView.post(new Runnable() {
@Override
public void run() {
assert editorView.getRenderer() != null;
editorView.getRenderer().setViewOffset(0, 0);
editorView.getRenderer().setViewScale(1);
editorView.setVisibility(View.VISIBLE);
editor.setPart(contentPart);
}
});

Here is the error log:

2021-02-02 15:23:18.025 6319-6319/com.double_std.memotechlanguagep1 E/MainActivity: Motion event: MotionEvent { action=ACTION_DOWN, actionButton=0, id[0]=0, x[0]=513.36914, y[0]=1191.585, toolType[0]=TOOL_TYPE_FINGER, buttonState=0, metaState=0, flags=0x0, edgeFlags=0x0, pointerCount=1, historySize=0, eventTime=19457589, downTime=19457589, deviceId=13, source=0x1002 }
2021-02-02 15:23:18.028 6319-6319/com.double_std.memotechlanguagep1 E/InputEventReceiver: Exception dispatching input event.
2021-02-02 15:23:18.028 6319-6319/com.double_std.memotechlanguagep1 E/MessageQueue-JNI: Exception in MessageQueue callback: handleReceiveCallback
2021-02-02 15:23:18.031 6319-6319/com.double_std.memotechlanguagep1 E/MessageQueue-JNI: java.lang.IllegalStateException: no view size set
        at com.myscript.iink.NativeFunctions.pointerDown(Native Method)
        at com.myscript.iink.Editor.pointerDown(Editor.java:409)
        at com.myscript.iink.uireferenceimplementation.InputController.handleOnTouchForPointer(InputController.java:156)
        at com.myscript.iink.uireferenceimplementation.InputController.onTouch(InputController.java:223)
        at android.view.View.dispatchTouchEvent(View.java:13459)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3209)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2881)
        at com.double_std.memotechlanguagep1.MainActivity$7.onTouch(MainActivity.java:222)
        at android.view.View.dispatchTouchEvent(View.java:13459)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3215)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2838)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3215)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2838)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3215)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2838)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3215)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2838)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3215)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2838)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3215)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2838)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3215)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2838)
        at com.android.internal.policy.DecorView.superDispatchTouchEvent(DecorView.java:698)
        at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1879)
        at android.app.Activity.dispatchTouchEvent(Activity.java:3486)
        at androidx.appcompat.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:69)
        at com.android.internal.policy.DecorView.dispatchTouchEvent(DecorView.java:656)
        at android.view.View.dispatchPointerEvent(View.java:13711)
        at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:6128)
        at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:5906)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:5355)
        at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:5408)
        at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:5374)
        at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:5533)
        at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:5382)
        at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:5590)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:5355)
        at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:5408)
        at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:5374)
        at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:5382)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:5355)
        at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:8397)
        at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:8330)
        at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:8291)
        at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:8512)
        at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:198)
        at android.os.MessageQueue.nativePollOnce(Native Method)
        at android.os.MessageQueue.next(MessageQueue.java:326)
        at android.os.Looper.loop(Looper.java:181)
        at android.app.ActivityThread.main(ActivityThread.java:6986)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1445)
2021-02-02 15:23:18.033 6319-6319/com.double_std.memotechlanguagep1 E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.double_std.memotechlanguagep1, PID: 6319
    java.lang.IllegalStateException: no view size set
        at com.myscript.iink.NativeFunctions.pointerDown(Native Method)
        at com.myscript.iink.Editor.pointerDown(Editor.java:409)
        at com.myscript.iink.uireferenceimplementation.InputController.handleOnTouchForPointer(InputController.java:156)
        at com.myscript.iink.uireferenceimplementation.InputController.onTouch(InputController.java:223)
        at android.view.View.dispatchTouchEvent(View.java:13459)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3209)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2881)
        at com.double_std.memotechlanguagep1.MainActivity$7.onTouch(MainActivity.java:222)
        at android.view.View.dispatchTouchEvent(View.java:13459)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3215)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2838)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3215)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2838)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3215)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2838)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3215)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2838)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3215)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2838)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3215)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2838)
        at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3215)
        at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2838)
        at com.android.internal.policy.DecorView.superDispatchTouchEvent(DecorView.java:698)
        at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1879)
        at android.app.Activity.dispatchTouchEvent(Activity.java:3486)
        at androidx.appcompat.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:69)
        at com.android.internal.policy.DecorView.dispatchTouchEvent(DecorView.java:656)
        at android.view.View.dispatchPointerEvent(View.java:13711)
        at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:6128)
        at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:5906)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:5355)
        at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:5408)
        at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:5374)
        at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:5533)
        at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:5382)
        at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:5590)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:5355)
        at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:5408)
        at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:5374)
        at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:5382)
        at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:5355)
        at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:8397)
        at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:8330)
        at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:8291)
        at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:8512)
        at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:198)
        at android.os.MessageQueue.nativePollOnce(Native Method)
        at android.os.MessageQueue.next(MessageQueue.java:326)
        at android.os.Looper.loop(Looper.java:181)
        at android.app.ActivityThread.main(ActivityThread.java:6986)
        at java.lang.reflect.Method.invoke(Native Method)
2021-02-02 15:23:18.034 6319-6319/com.double_std.memotechlanguagep1 E/AndroidRuntime:     at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:494)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1445)

Answer

Dear Nicolas,


currently, the error is indicated in the log, the SetViewSize has indeed not been done.


You shall indeed ensure it has been done:


_editor = _engine.CreateEditor(_renderer);
_editor.SetViewSize((int)ActualWidth, (int)ActualHeight);
_editor.SetFontMetricsProvider(new FontMetricsProvider(_dpiX, dpiY));
_editor.AddListener(new EditorListener(this));


Best regards,


Olivier

Thank you Olivier,

editor.setFontMetricsProvider is already handled by the uireferenceimplementation when we call editorView.setEngine(engine)

However, it looks like SetViewSize is not being called by the framework unless the view size actually changes. So I added the call to editor.SetViewSize as you suggested and now it works.

Thanks again!