diff options
author | DavisLWebb <davislwebb@ymail.com> | 2014-05-07 12:36:36 -0400 |
---|---|---|
committer | DavisLWebb <davislwebb@ymail.com> | 2014-05-07 12:36:36 -0400 |
commit | fac4b2b460ba84cc38fb75ecbf09755528050bc7 (patch) | |
tree | 298c3400f22f4ca9b84beb0a3df7f55bbabc9003 | |
parent | 9ca3fa2d19c48dafb5f25f92bcd5ba87d03031b0 (diff) | |
parent | 58aa0ea407aedde32cbde69b2dbb6cf4ae9e31a5 (diff) |
Merge branch 'master' of https://github.com/AndrewMurrell/minak
-rw-r--r-- | 1251.odp | bin | 47734 -> 47815 bytes | |||
-rw-r--r-- | 1251.pdf | bin | 348429 -> 348454 bytes | |||
-rw-r--r-- | AndroidManifest.xml | 2 | ||||
-rw-r--r-- | libs/android-support-v4.jar | bin | 627582 -> 0 bytes | |||
-rw-r--r-- | res/layout/ime.xml | 8 | ||||
-rw-r--r-- | res/values/strings.xml | 4 | ||||
-rw-r--r-- | src/us/minak/IMEGestureOverlayView.java | 97 | ||||
-rw-r--r-- | src/us/minak/IMEModifier.java | 27 | ||||
-rw-r--r-- | src/us/minak/IMEModifierCircle.java | 37 | ||||
-rw-r--r-- | src/us/minak/IMEModifiers.java | 65 | ||||
-rw-r--r-- | src/us/minak/IMEService.java | 40 | ||||
-rw-r--r-- | src/us/minak/IMEView.java | 94 | ||||
-rw-r--r-- | src/us/minak/InputConnectionGetter.java | 14 | ||||
-rw-r--r-- | src/us/minak/OnBackspacePressedListener.java | 26 | ||||
-rw-r--r-- | src/us/minak/StringReciever.java | 5 |
15 files changed, 165 insertions, 254 deletions
Binary files differBinary 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 Binary files differdeleted file mode 100644 index a7e9919..0000000 --- a/libs/android-support-v4.jar +++ /dev/null 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">←</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); -} |