summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavisLWebb <davislwebb@ymail.com>2014-05-07 12:36:36 -0400
committerDavisLWebb <davislwebb@ymail.com>2014-05-07 12:36:36 -0400
commitfac4b2b460ba84cc38fb75ecbf09755528050bc7 (patch)
tree298c3400f22f4ca9b84beb0a3df7f55bbabc9003
parent9ca3fa2d19c48dafb5f25f92bcd5ba87d03031b0 (diff)
parent58aa0ea407aedde32cbde69b2dbb6cf4ae9e31a5 (diff)
Merge branch 'master' of https://github.com/AndrewMurrell/minak
-rw-r--r--1251.odpbin47734 -> 47815 bytes
-rw-r--r--1251.pdfbin348429 -> 348454 bytes
-rw-r--r--AndroidManifest.xml2
-rw-r--r--libs/android-support-v4.jarbin627582 -> 0 bytes
-rw-r--r--res/layout/ime.xml8
-rw-r--r--res/values/strings.xml4
-rw-r--r--src/us/minak/IMEGestureOverlayView.java97
-rw-r--r--src/us/minak/IMEModifier.java27
-rw-r--r--src/us/minak/IMEModifierCircle.java37
-rw-r--r--src/us/minak/IMEModifiers.java65
-rw-r--r--src/us/minak/IMEService.java40
-rw-r--r--src/us/minak/IMEView.java94
-rw-r--r--src/us/minak/InputConnectionGetter.java14
-rw-r--r--src/us/minak/OnBackspacePressedListener.java26
-rw-r--r--src/us/minak/StringReciever.java5
15 files changed, 165 insertions, 254 deletions
diff --git a/1251.odp b/1251.odp
index b99c728..0ddab3e 100644
--- a/1251.odp
+++ b/1251.odp
Binary files differ
diff --git a/1251.pdf b/1251.pdf
index ca98eb0..3c1aea6 100644
--- a/1251.pdf
+++ b/1251.pdf
Binary files differ
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 79290e8..05ee7c0 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -5,7 +5,7 @@
android:versionName="1.0" >
<uses-sdk
- android:minSdkVersion="11"
+ android:minSdkVersion="12"
android:targetSdkVersion="19" />
<application
diff --git a/libs/android-support-v4.jar b/libs/android-support-v4.jar
deleted file mode 100644
index a7e9919..0000000
--- a/libs/android-support-v4.jar
+++ /dev/null
Binary files differ
diff --git a/res/layout/ime.xml b/res/layout/ime.xml
index 83be9d2..53f8fdf 100644
--- a/res/layout/ime.xml
+++ b/res/layout/ime.xml
@@ -20,4 +20,12 @@
android:gestureStrokeSquarenessThreshold="0.0"
android:gestureStrokeType="multiple" />
+ <Button
+ android:id="@+id/backspace_btn"
+ android:text="@string/button_backspace"
+
+ android:layout_width="80dp"
+ android:layout_height="40dp"
+ android:layout_alignParentRight="true" />
+
</us.minak.IMEView>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index d3352bc..60803b0 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -36,9 +36,7 @@
<!-- Message, displayed when the sdcard cannot be found, 1st parameter is the name of the file that stores the gestures. CHAR LIMIT=80 -->
<string name="gestures_error_loading">Could not load %s. Make sure you have storage available.</string>
- <!-- Temporary labels for buttons -->
- <string name="button_shift">Shift</string>
+ <!-- Labels for buttons -->
<string name="button_backspace">&#x2190;</string>
- <string name="button_space">Space</string>
</resources>
diff --git a/src/us/minak/IMEGestureOverlayView.java b/src/us/minak/IMEGestureOverlayView.java
index e27b70a..35fe1eb 100644
--- a/src/us/minak/IMEGestureOverlayView.java
+++ b/src/us/minak/IMEGestureOverlayView.java
@@ -1,20 +1,5 @@
-/*
- ********************************************************************************
- * Copyright (c) 2012 Samsung Electronics, Inc.
- * All rights reserved.
- *
- * This software is a confidential and proprietary information of Samsung
- * Electronics, Inc. ("Confidential Information"). You shall not disclose such
- * Confidential Information and shall use it only in accordance with the terms
- * of the license agreement you entered into with Samsung Electronics.
- ********************************************************************************
- */
-
package us.minak;
-import java.util.LinkedList;
-import java.util.List;
-
import android.content.Context;
import android.gesture.Gesture;
import android.gesture.GestureLibrary;
@@ -23,16 +8,24 @@ import android.gesture.GestureOverlayView.OnGesturePerformedListener;
import android.gesture.Prediction;
import android.graphics.Canvas;
import android.util.AttributeSet;
+import android.view.KeyEvent;
+import android.view.KeyCharacterMap;
+import android.view.MotionEvent;
+import android.view.inputmethod.InputConnection;
+
+import java.util.List;
-/**
- * Represent a space where drawing gestures are performed.
- */
public class IMEGestureOverlayView extends GestureOverlayView implements OnGesturePerformedListener {
private static final double SCORE_TRESHOLD = 3.0;
private final GestureLibrary mGestureLibrary;
- private StringReciever mOnGestureRecognizedListener;
- public List<IMEModifierCircle> circles = new LinkedList<IMEModifierCircle>();
+ private InputConnectionGetter icGetter = new InputConnectionGetter.NullGetter();
private final IMEModifiers modifiers = new IMEModifiers();
+ private final KeyCharacterMap charMap = KeyCharacterMap.load(KeyCharacterMap.VIRTUAL_KEYBOARD);
+ float x = -1, y = -1;
+ int meta = 0;
+
+ // cache for repeated calls
+ InputConnection ic = null;
public IMEGestureOverlayView(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -41,10 +34,26 @@ public class IMEGestureOverlayView extends GestureOverlayView implements OnGestu
addOnGesturePerformedListener(this);
}
- public void setOnGestureRecognizedListener(StringReciever onGestureRecognizedListener) {
- mOnGestureRecognizedListener = onGestureRecognizedListener;
+ public void setInputConnectionGetter(InputConnectionGetter icGetter) {
+ this.icGetter = icGetter;
+ }
+
+ private void sendKeyEvent(KeyEvent keyEvent) {
+ if (ic != null) {
+ ic.sendKeyEvent(new KeyEvent(
+ keyEvent.getDownTime(),
+ keyEvent.getEventTime(),
+ keyEvent.getAction(),
+ keyEvent.getKeyCode(),
+ keyEvent.getRepeatCount(),
+ keyEvent.getMetaState() | meta));
+ }
}
+ /**
+ * This function is pretty strongly based on the code in
+ * Samsung's "Penboard" whitepaper.
+ */
@Override
public void onGesturePerformed(GestureOverlayView overlay, Gesture gesture) {
final List<Prediction> predictions = mGestureLibrary.recognize(gesture);
@@ -52,18 +61,50 @@ public class IMEGestureOverlayView extends GestureOverlayView implements OnGestu
if (!predictions.isEmpty()) {
bestPrediction = predictions.get(0);
}
- if (mOnGestureRecognizedListener != null && bestPrediction != null) {
- if (bestPrediction.score > SCORE_TRESHOLD) {
- mOnGestureRecognizedListener.putString(bestPrediction.name);
- } else {
- clear(false);
+
+ ic = icGetter.getCurrentInputConnection();
+ if (ic != null) {
+ if (bestPrediction != null) {
+ if (bestPrediction.score > SCORE_TRESHOLD) {
+ for (KeyEvent keyEvent : charMap.getEvents(bestPrediction.name.toCharArray()))
+ sendKeyEvent(keyEvent);
+ } else {
+ clear(false);
+ }
+ }
+ for (IMEModifier modifier : modifiers.getSelection()) {
+ sendKeyEvent(new KeyEvent(KeyEvent.ACTION_UP, modifier.keycode));
}
}
+ modifiers.clearSelection();
+ meta = 0;
+ invalidate();
+ x = y = -1;
}
@Override
public void onDraw(Canvas canvas) {
float d = Math.min(canvas.getWidth(), canvas.getHeight());
- modifiers.draw(canvas, d/2, d/2, d*.4F);
+ modifiers.draw(canvas, d/2, d/2, d*.47F);
+ }
+
+ @Override
+ public boolean onTouchEvent (MotionEvent event) {
+ if (x < 0 && y < 0 && event.getActionMasked() == MotionEvent.ACTION_DOWN) {
+ x = event.getX();
+ y = event.getY();
+ modifiers.setSelectionPoint(x, y);
+ invalidate();
+
+ ic = icGetter.getCurrentInputConnection();
+ if (ic != null) {
+ for (IMEModifier modifier : modifiers.getSelection()) {
+ sendKeyEvent(new KeyEvent(KeyEvent.ACTION_DOWN, modifier.keycode));
+ meta |= modifier.metamask;
+ }
+ return true;
+ }
+ }
+ return false;
}
}
diff --git a/src/us/minak/IMEModifier.java b/src/us/minak/IMEModifier.java
index 6b5ee67..50dc6d3 100644
--- a/src/us/minak/IMEModifier.java
+++ b/src/us/minak/IMEModifier.java
@@ -1,24 +1,13 @@
package us.minak;
public class IMEModifier {
- public static enum State {
- ON, OFF, LOCK
- }
-
- public State state;
- private String value;
-
- public String getValue() {
- //however we want to do return this
- return this.value;
- }
-
- public void setValue(String value) {
- this.value = value;
- }
-
- IMEModifier(String value) {
- this.value = value;
- this.state = State.OFF;
+ public final String name;
+ public final int keycode;
+ public final int metamask;
+
+ public IMEModifier(String name, int keycode, int metamask) {
+ this.name = name;
+ this.keycode = keycode;
+ this.metamask = metamask;
}
}
diff --git a/src/us/minak/IMEModifierCircle.java b/src/us/minak/IMEModifierCircle.java
deleted file mode 100644
index 246036f..0000000
--- a/src/us/minak/IMEModifierCircle.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package us.minak;
-
-/*
- * Not sure if this should be drawable or what.
- *
- */
-public class IMEModifierCircle {
- private IMEModifier metaExpression;
- public float x;
- public float y;
- public float radius;
- public int color;
- public boolean expanded;
- public int expansion; //the level of expansion (if multiple circles are expanded, this decides precidence)
-
- IMEModifierCircle(float x, float y, float radius, int color, IMEModifier metaExpr) {
- this.setMetaExpression(metaExpr);
- this.x = x;
- this.y = y;
- this.radius = radius;
- this.color = color;
- this.expanded = false;
- this.expansion = 0;
- }
-
- public boolean containsPoint(float x, float y) {
- return Math.pow(x - this.x, 2) + Math.pow(y - this.y, 2) < Math.pow(this.radius, 2) ? true : false;
- }
-
- public IMEModifier getMetaExpression() {
- return metaExpression;
- }
-
- public void setMetaExpression(IMEModifier metaExpr) {
- this.metaExpression = metaExpr;
- }
-}
diff --git a/src/us/minak/IMEModifiers.java b/src/us/minak/IMEModifiers.java
index ef49f17..2766c76 100644
--- a/src/us/minak/IMEModifiers.java
+++ b/src/us/minak/IMEModifiers.java
@@ -3,20 +3,30 @@ package us.minak;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
-import java.util.List;
+import android.view.KeyEvent;
import java.util.ArrayList;
+import java.util.List;
public class IMEModifiers {
- private final String[] modifiers = { "shift", "ctrl", "alt" };
+ // FIXME: hard-coded configuration
+ private final IMEModifier[] modifiers = {
+ new IMEModifier("Shift", KeyEvent.KEYCODE_SHIFT_LEFT, KeyEvent.META_SHIFT_ON),
+ new IMEModifier("Ctrl" , KeyEvent.KEYCODE_CTRL_LEFT , KeyEvent.META_CTRL_ON ),
+ new IMEModifier("Alt" , KeyEvent.KEYCODE_ALT_LEFT , KeyEvent.META_ALT_ON )};
+
+ // Static drawing resources
private final Paint colorPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private final Paint textPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
+ // Pre-calculated graphics stuff
private float cx = 0;
private float cy = 0;
private double innerR = 0;
private double outerR = 0;
private double radEach = 0;
+ // The current state
+ ArrayList<IMEModifier> selected = new ArrayList<IMEModifier>();
public IMEModifiers() {
textPaint.setColor(Color.BLACK);
@@ -25,33 +35,37 @@ public class IMEModifiers {
public void draw(Canvas canvas, float cx, float cy, float r) {
this.cx = cx;
this.cy = cy;
- innerR = r*(1.0/3.0);
- outerR = (float)(r*(2.0/3.0));
+ innerR = r*(1.2/3.0);
+ outerR = r*(1.8/3.0);
radEach = (Math.PI*2.0)/modifiers.length;
-
+
+ double textR = r*.8;
+
double rad = 0;
float[] hsv = {0F, 1F, .75F};
-
+
for (int i = 0; i < modifiers.length; i++) {
rad = radEach * i;
hsv[0] = (float)Math.toDegrees(rad);
colorPaint.setColor(Color.HSVToColor(0x80, hsv));
- canvas.drawCircle(
- (float)(cx+innerR*Math.cos(rad)),
- (float)(cy+innerR*Math.sin(rad)),
- (float)outerR,
- colorPaint);
- canvas.drawText(
- modifiers[i],
- (float)(cx+innerR*Math.cos(rad)),
- (float)(cy+innerR*Math.sin(rad)),
- textPaint);
- }
+ if (selected.contains(modifiers[i])) {
+ canvas.drawRect(0, 0, canvas.getWidth(), canvas.getHeight(), colorPaint);
+ } else {
+ canvas.drawCircle((float)(cx+innerR*Math.cos(rad)),
+ (float)(cy+innerR*Math.sin(rad)),
+ (float)outerR,
+ colorPaint);
+ }
+ canvas.drawText(modifiers[i].name,
+ (float)(cx+textR*Math.cos(rad)),
+ (float)(cy+textR*Math.sin(rad)),
+ textPaint);
+ }
}
- public List<String> getModifiersAtPoint(float x, float y) {
- ArrayList<String> ret = new ArrayList<String>();
+ public void setSelectionPoint(float x, float y) {
+ selected.clear();
double mx;
double my;
@@ -61,9 +75,16 @@ public class IMEModifiers {
mx = cx+innerR*Math.cos(rad);
my = cy+innerR*Math.sin(rad);
- if (Math.sqrt(Math.pow(mx-x,2)+Math.pow(my-y, 2)) > outerR)
- ret.add(modifiers[i]);
+ if (Math.sqrt(Math.pow(mx-x,2)+Math.pow(my-y, 2)) < outerR)
+ selected.add(modifiers[i]);
}
- return ret;
+ }
+
+ public List<IMEModifier> getSelection() {
+ return selected;
+ }
+
+ public void clearSelection() {
+ selected.clear();
}
}
diff --git a/src/us/minak/IMEService.java b/src/us/minak/IMEService.java
index a0a9ece..f8a3660 100644
--- a/src/us/minak/IMEService.java
+++ b/src/us/minak/IMEService.java
@@ -1,52 +1,16 @@
-/*
- ********************************************************************************
- * Copyright (c) 2012 Samsung Electronics, Inc.
- * All rights reserved.
- *
- * This software is a confidential and proprietary information of Samsung
- * Electronics, Inc. ("Confidential Information"). You shall not disclose such
- * Confidential Information and shall use it only in accordance with the terms
- * of the license agreement you entered into with Samsung Electronics.
- ********************************************************************************
- */
-
package us.minak;
-import java.util.Queue;
-
import android.inputmethodservice.InputMethodService;
import android.view.View;
-import android.view.inputmethod.EditorInfo;
/**
* Represent the application input service.
*/
-public class IMEService extends InputMethodService {
- private IMEView mIMEView;
-
+public class IMEService extends InputMethodService implements InputConnectionGetter {
@Override
public View onCreateInputView() {
final IMEView minakView = (IMEView) getLayoutInflater().inflate(R.layout.ime, null);
-
- minakView.setOnCharacterEnteredListener(new StringReciever() {
- @Override
- public void putString(String character) {
- getCurrentInputConnection().commitText(character, 1);
- }
- });
-
- mIMEView = minakView;
+ minakView.setInputConnectionGetter(this);
return minakView;
}
-
- @Override
- public void onStartInput(EditorInfo attribute, boolean restarting) {
- if (mIMEView != null) {
- final Queue<Character> symbolsQueue = mIMEView.getSymbolsQueue();
- while (!symbolsQueue.isEmpty()) {
- final Character character = symbolsQueue.poll();
- getCurrentInputConnection().commitText(String.valueOf(character), 1);
- }
- }
- }
}
diff --git a/src/us/minak/IMEView.java b/src/us/minak/IMEView.java
index a992011..31ce553 100644
--- a/src/us/minak/IMEView.java
+++ b/src/us/minak/IMEView.java
@@ -1,54 +1,16 @@
-/*
- ********************************************************************************
- * Copyright (c) 2012 Samsung Electronics, Inc.
- * All rights reserved.
- *
- * This software is a confidential and proprietary information of Samsung
- * Electronics, Inc. ("Confidential Information"). You shall not disclose such
- * Confidential Information and shall use it only in accordance with the terms
- * of the license agreement you entered into with Samsung Electronics.
- ********************************************************************************
- */
-
package us.minak;
-import java.util.LinkedList;
-import java.util.Queue;
-
import android.content.Context;
import android.util.AttributeSet;
-import android.view.MotionEvent;
-import android.view.View;
+import android.widget.Button;
import android.widget.RelativeLayout;
+import android.view.View;
+import android.view.inputmethod.InputConnection;
/**
* Represents the container for the drawing space and the two side panels.
*/
-public class IMEView extends RelativeLayout {
- private StringReciever mOnCharacterEnteredListener;
- private final Queue<Character> mSymbolsQueue = new LinkedList<Character>();
-
- private float x;
- private float y;
- private boolean ongoingGesture = false;
-
- public boolean setTouchLocation(float x, float y) {
- if (!ongoingGesture) {
- this.x = x;
- this.y = y;
- return true;
- }
- return false;
- }
-
- public void setState(boolean state) {
- ongoingGesture = state;
- }
-
- public boolean getState() {
- return ongoingGesture;
- }
-
+public class IMEView extends RelativeLayout implements InputConnectionGetter {
public IMEView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@@ -56,45 +18,27 @@ public class IMEView extends RelativeLayout {
@Override
protected void onFinishInflate() {
IMEGestureOverlayView gestureOverlayView = (IMEGestureOverlayView) findViewById(R.id.drawing_space);
- gestureOverlayView.setOnGestureRecognizedListener(new StringReciever() {
+ gestureOverlayView.setInputConnectionGetter(this);
+
+ final Button backspaceButton = (Button) findViewById(R.id.backspace_btn);
+ backspaceButton.setOnClickListener(new OnClickListener() {
@Override
- public void putString(String character) {
- enterCharacter(character);
- }
+ public void onClick(View v) { backspace(); }
});
}
- public void setOnCharacterEnteredListener(StringReciever onCharacterEnteredListener) {
- mOnCharacterEnteredListener = onCharacterEnteredListener;
+ private InputConnectionGetter icGetter = new InputConnectionGetter.NullGetter();
+ public void setInputConnectionGetter(InputConnectionGetter icGetter) {
+ this.icGetter = icGetter;
}
-
- public Queue<Character> getSymbolsQueue() {
- return mSymbolsQueue;
+ @Override
+ public InputConnection getCurrentInputConnection() {
+ return icGetter.getCurrentInputConnection();
}
- private final OnTouchListener mOnTouchListener = new OnTouchListener() {
- @Override
- public boolean onTouch(View v, MotionEvent event) {
- return setTouchLocation(event.getX(), event.getY());
- }
- };
-
- /**
- * Passes the given character to the input service.
- *
- * @param character
- * The character to enter
- */
- private void enterCharacter(String character) {
- /*
- for (MetaCircle circle : ((IMEGestureOverlayView) findViewById(R.id.drawing_space)).circles) {
- //go through circles and check if they are applicable
- if (circle.containsPoint(this.x, this.y) && circle.getMetaExpression().state != MetaExpression.State.OFF) {
- //TODO: apply the Meta-key here
- ;
- }
- }
- */
- mOnCharacterEnteredListener.putString(character);
+ private void backspace() {
+ InputConnection ic = getCurrentInputConnection();
+ if (ic != null)
+ ic.deleteSurroundingText(1, 0);
}
}
diff --git a/src/us/minak/InputConnectionGetter.java b/src/us/minak/InputConnectionGetter.java
new file mode 100644
index 0000000..237eefc
--- /dev/null
+++ b/src/us/minak/InputConnectionGetter.java
@@ -0,0 +1,14 @@
+package us.minak;
+
+import android.view.inputmethod.InputConnection;
+
+public interface InputConnectionGetter {
+ public InputConnection getCurrentInputConnection();
+
+ public static class NullGetter implements InputConnectionGetter{
+ @Override
+ public InputConnection getCurrentInputConnection() {
+ return null;
+ }
+ }
+}
diff --git a/src/us/minak/OnBackspacePressedListener.java b/src/us/minak/OnBackspacePressedListener.java
deleted file mode 100644
index b4cf974..0000000
--- a/src/us/minak/OnBackspacePressedListener.java
+++ /dev/null
@@ -1,26 +0,0 @@
-/*
- ********************************************************************************
- * Copyright (c) 2012 Samsung Electronics, Inc.
- * All rights reserved.
- *
- * This software is a confidential and proprietary information of Samsung
- * Electronics, Inc. ("Confidential Information"). You shall not disclose such
- * Confidential Information and shall use it only in accordance with the terms
- * of the license agreement you entered into with Samsung Electronics.
- ********************************************************************************
- */
-
-package us.minak;
-
-/**
- * A simple interface for handling pressing the backspace button.
- */
-public interface OnBackspacePressedListener {
- /**
- * Invoked when the backspace button is pressed.
- *
- * @param isLongClick
- * if the button is long pressed
- */
- void backspacePressed(boolean isLongClick);
-}
diff --git a/src/us/minak/StringReciever.java b/src/us/minak/StringReciever.java
deleted file mode 100644
index 2b91da1..0000000
--- a/src/us/minak/StringReciever.java
+++ /dev/null
@@ -1,5 +0,0 @@
-package us.minak;
-
-public interface StringReciever {
- void putString(String character);
-}