Overview

Single Line Widget is an interactive input method enabling users to handwrite a single line of text. It is a widget designed to ensure a natural, handwriting-based HMI with real-time recognition and ink editing gestures, thanks to a user-friendly interface.

Single Line Widget manages a line of text, modeling it as an infinite horizontal ribbon, also known as the writing area. As the user writes in a continuous flow, the ribbon automatically scrolls after a short delay and turns handwritten ink into typeset characters.

The scroll bar and the cursor allow the user to go back and forth the line to change text - in case it has not been properly recognized - either with editing gestures or by choosing an alternative (or candidate) suggested by the widget.

Use cases

The below use cases are only examples of applications where Single Line Widget has been used, sometimes with additional features. Note that all available features are listed in the API.

SMS

Here is an integration example of Single Line Widget in MyScript Stylus for iOS. In this scenario, the user handwrites a text message on a smartphone. Candidates and editing gestures can be used to modify text.

Form-filling

Here is an integration example of Single Line Widget in a form-filling application for iOS. In this scenario, the user fills out a form using handwriting. Candidates and editing gestures can be used to modify text.

Features

Text input with horizontal auto-scrolling
Canvas where handwritten text automatically scrolls to free writing space.

Real-time cursive text
Real-time recognition of handwritten text (printscript and cursive).

Typeset rendering
Captured handwritten text can be turned into typeset text in real-time.

Editing gestures
The following gestures can be applied on both original handwritten text and typeset text: single tap, long press, return, erase, select, underline, join, insert and overwrite.

Option list (candidates)
Word option list for non-Asian languages and character option list for Asian languages.

Customization options

  • Text size, color & font
  • Ink width & color
  • Background image of the scrolling area
  • Baseline position, thickness and color
  • Auto-scroll margin and delay (auto-scroll feature can be enabled/disabled)
  • Auto-typeset delay (auto-typeset feature can be enabled/disabled)

Writing and correction modes

The writing mode is designed to enable the user to write text in a continuous flow. The writing area scrolls automatically after a short delay, once the user has finished writing. Scrolling of the writing area is managed by the widget.

The correction mode is designed to enable the user to navigate and edit the text already entered. A cursor bar is displayed in the writing area.

Cursor interface

In correction mode, Single Line Widget displays a cursor bar in the writing area. The input method manages and sets the position of the cursor bar which is moved accordingly in the writing area.

Positioning the cursor inside the text automatically selects the word or character at the position of the cursor, depending on the current selection mode. This triggers a selection change event that notifies the input method of the available handwriting candidates.

Languages

Single Line Widget supports 64 languages for Android and 59 languages for iOS and Windows. The full list is available on the Developer Portal.

Recommendations

Gesture detection

User action  Gesture Description  Sample & default actions
Single tap Briefly touch a word No action by default whereas a cursor moves in the sample.
Long press Tap and hold down n/a
Return Draw a line downwards then leftwards Insert a hard line break
Erase Strike through OR scratch out a word Erase
Select Circle a word No action in the sample whereas there is a selection by default
Underline Draw a line under a word No action in the sample whereas there is an underline by default
Join Draw a straight line upwards OR draw a line from one word to the next one Remove extra space
Insert Draw a straight line downwards Break a word
Overwrite Write a letter (or a whole word) on top of another Overwrite
These gestures might be confusing for your users at first, so you might want to integrate only some of these. If you choose to integrate all the gestures, we recommend you clearly explain these to your users to avoid any confusion.

Integration

General information about ATK (licenses, samples, etc.) is available in the ATK Overview section.
Please make sure to use the latest version of Android Studio and have all Android tools and SDK (level 15 or up) installed and configured properly.

Step 1 - Download your Certificate

  1. Log in at https://atk.myscript.com.
  2. In the Applications tab, click Create application.
  3. Enter your application name and its description, then click Create.
  4. Click Open, then Create certificate.
  5. Enter the package name that can be found in AndroidManifest.xml and select the target environment, then click Create.
  6. Click on the .java download icon to download the corresponding certificate.
  7. Paste it in your project and start creating your app.
You need one certificate per application and per platform. You can integrate several widgets in one application.

Step 2 - Configure your Dependencies

  • In the build.gradle file of your project, add:
repositories {
    flatDir {
        // Location of your package's `libs` directory containing `*.aar` files.
        dirs 'path/to/libs'
    }
}
  • In the dependencies section, add:
compile 'com.android.support:appcompat-v7:23.+'

compile(name: 'MyScript_ATK-Core-android-component', ext: 'aar')
compile(name: 'MyScript_ATK-Text-android-component', ext: 'aar')
compile(name: 'MyScript_ATK-IMCommon-android-component', ext: 'aar')
compile(name: 'MyScript_ATK-SingleLineWidget-android-widget', ext: 'aar')

Step 3 - Add Resources

Copy the assets directory from samples/SingleLineWidgetSample/src/main into your project. Resources should include at least an ak resource. More lk resources can be added as well, to improve and/or constrain the handwriting recognition.

Example: To use US English, resources should be at least:

  • resources/en_US/en_US-ak-cur.lite.res,
  • resources/en_US/en_US-lk-text.lite.res,
  • conf/en_US.conf.
Resources are available for download on the Developer Portal. You can also customize your own resources: Check the Developer Tools page to discover how.

Step 4 - Add a Layout Resource

To integrate the Single Line Widget view, add the following snippet in your layout.

<com.myscript.atk.sltw.SingleLineWidget
    android:id="@+id/singleLine_widget"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
/>

Step 5 - Start with Minimal Integration Code

An Internet connection is required to launch and run ATK applications. To authorize it, add the following line in the AndroidManifest.xml file:

<uses-permission android:name="android.permission.INTERNET" />
However, a 30-day grace period is offered, from the moment you first launch your application. A connection will then be mandatory.

Edit the MainActivity class:

public class MainActivity extends AppCompatActivity implements
    SingleLineWidgetApi.OnConfiguredListener,
    SingleLineWidgetApi.OnTextChangedListener
{

  private static final String TAG = "SingleLineDemo";

  private SingleLineWidgetApi widget;

  @Override
  protected void onCreate(Bundle savedInstanceState)
  {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);

    widget = (SingleLineWidget) findViewById(R.id.singleLine_widget);
    if (!widget.registerCertificate(MyCertificate.getBytes()))
    {
      AlertDialog.Builder dlgAlert  = new AlertDialog.Builder(this);
      dlgAlert.setMessage("Please use a valid certificate.");
      dlgAlert.setTitle("Invalid certificate");
      dlgAlert.setCancelable(false);
      dlgAlert.setPositiveButton("OK", new DialogInterface.OnClickListener()
      {
        public void onClick(DialogInterface dialog, int which)
        {
          //dismiss the dialog
        }
      });
      dlgAlert.create().show();
      return;
    }

    widget.setOnConfiguredListener(this);
    widget.setOnTextChangedListener(this);

    // references assets directly from the APK to avoid extraction in application
    // file system
    widget.addSearchDir("zip://" + getPackageCodePath() + "!/assets/conf");

    // The configuration is an asynchronous operation. Callbacks are provided to
    // monitor the beginning and end of the configuration process and update the UI
    // of the input method accordingly.
    //
    // "en_US" references the en_US bundle name in conf/en_US.conf file in your assets.
    // "cur_text" references the configuration name in en_US.conf
    widget.configure("en_US", "cur_text");
  }

  @Override
  protected void onDestroy()
  {
    widget.setOnTextChangedListener(null);
    widget.setOnConfiguredListener(null);

    super.onDestroy();
  }

  @Override
  public void onConfigured(SingleLineWidgetApi widget, boolean success)
  {
    if(!success)
    {
      Toast.makeText(getApplicationContext(), widget.getErrorString(), Toast.LENGTH_LONG).show();
      Log.e(TAG, "Unable to configure the Single Line Widget: " + widget.getErrorString());
      return;
    }
    Toast.makeText(getApplicationContext(), "Single Line Widget Configured", Toast.LENGTH_SHORT).show();
    if(BuildConfig.DEBUG)
      Log.d(TAG, "Single Line Widget configured!");
  }

  @Override
  public void onTextChanged(SingleLineWidgetApi widget, String s, boolean intermediate)
  {
    Toast.makeText(getApplicationContext(), "Recognition update", Toast.LENGTH_SHORT).show();
    if(BuildConfig.DEBUG)
    {
      Log.d(TAG, "Single Line Widget recognition: " + widget.getText());
    }
  }
}

API

See the API documentation for Android.