Unexpected-Keyboard/srcs/juloo.keyboard2/Keyboard2View.java

313 lines
8.7 KiB
Java
Raw Normal View History

2015-07-30 20:14:55 +02:00
package juloo.keyboard2;
import android.content.Context;
import android.graphics.Canvas;
2015-08-01 21:36:40 +02:00
import android.graphics.RectF;
2015-07-30 20:14:55 +02:00
import android.graphics.Paint;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.view.View;
2015-08-01 23:54:38 +02:00
import java.util.LinkedList;
2015-07-30 20:14:55 +02:00
public class Keyboard2View extends View
implements View.OnTouchListener
{
private static final float KEY_PER_ROW = 10;
private Keyboard2 _ime;
private KeyboardData _keyboard;
2015-07-30 20:14:55 +02:00
2015-08-01 23:54:38 +02:00
private LinkedList<KeyDown> _downKeys = new LinkedList<KeyDown>();
private int _flags = 0;
2015-08-01 16:33:30 +02:00
private float _verticalMargin;
private float _horizontalMargin;
2015-07-30 20:14:55 +02:00
private float _keyWidth;
private float _keyHeight;
private float _keyPadding;
private float _keyBgPadding;
2015-08-01 21:36:40 +02:00
private float _keyRound;
2015-07-30 20:14:55 +02:00
2015-08-01 23:54:38 +02:00
private Paint _keyBgPaint = new Paint();
private Paint _keyDownBgPaint = new Paint();
private Paint _keyLabelPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
2015-08-02 20:21:53 +02:00
private Paint _keyLabelLockedPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
2015-08-01 23:54:38 +02:00
private Paint _keySubLabelPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
2015-07-30 20:14:55 +02:00
public Keyboard2View(Context context, AttributeSet attrs)
{
super(context, attrs);
DisplayMetrics dm = context.getResources().getDisplayMetrics();
_verticalMargin = getResources().getDimension(R.dimen.vertical_margin);
_horizontalMargin = getResources().getDimension(R.dimen.horizontal_margin);
2015-07-31 23:52:47 +02:00
_keyHeight = getResources().getDimension(R.dimen.key_height);
_keyPadding = getResources().getDimension(R.dimen.key_padding);
_keyBgPadding = getResources().getDimension(R.dimen.key_bg_padding);
2015-08-01 21:36:40 +02:00
_keyRound = getResources().getDimension(R.dimen.key_round);
_keyWidth = (dm.widthPixels - (_horizontalMargin * 2)) / KEY_PER_ROW;
2015-07-30 20:14:55 +02:00
_keyBgPaint.setColor(getResources().getColor(R.color.key_bg));
_keyDownBgPaint.setColor(getResources().getColor(R.color.key_down_bg));
_keyLabelPaint.setColor(getResources().getColor(R.color.key_label));
2015-07-31 23:52:47 +02:00
_keyLabelPaint.setTextSize(getResources().getDimension(R.dimen.label_text_size));
2015-07-30 20:14:55 +02:00
_keyLabelPaint.setTextAlign(Paint.Align.CENTER);
2015-08-02 20:21:53 +02:00
_keyLabelLockedPaint.setColor(getResources().getColor(R.color.key_label_locked));
_keyLabelLockedPaint.setTextSize(getResources().getDimension(R.dimen.label_text_size));
_keyLabelLockedPaint.setTextAlign(Paint.Align.CENTER);
2015-07-31 23:17:07 +02:00
_keySubLabelPaint.setColor(getResources().getColor(R.color.key_sub_label));
2015-07-31 23:52:47 +02:00
_keySubLabelPaint.setTextSize(getResources().getDimension(R.dimen.sublabel_text_size));
2015-07-30 20:14:55 +02:00
_keySubLabelPaint.setTextAlign(Paint.Align.CENTER);
setOnTouchListener(this);
}
public void setKeyboard(Keyboard2 ime, KeyboardData keyboardData)
2015-07-30 20:14:55 +02:00
{
_ime = ime;
_keyboard = keyboardData;
2015-07-30 20:14:55 +02:00
}
@Override
public boolean onTouch(View v, MotionEvent event)
{
float x;
float y;
2015-07-30 22:30:29 +02:00
float keyW;
int p;
2015-07-30 20:14:55 +02:00
2015-07-31 01:14:35 +02:00
switch (event.getActionMasked())
{
case MotionEvent.ACTION_UP:
case MotionEvent.ACTION_POINTER_UP:
onTouchUp(event.getPointerId(event.getActionIndex()));
break ;
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_POINTER_DOWN:
p = event.getActionIndex();
2015-07-31 01:14:35 +02:00
onTouchDown(event.getX(p), event.getY(p), event.getPointerId(p));
break ;
case MotionEvent.ACTION_MOVE:
for (p = 0; p < event.getPointerCount(); p++)
onTouchMove(event.getX(p), event.getY(p), event.getPointerId(p));
break ;
2015-07-31 01:14:35 +02:00
default:
return (false);
}
return (true);
}
private KeyDown getKeyDown(int pointerId)
{
for (KeyDown k : _downKeys)
{
if (k.pointerId == pointerId)
return (k);
}
return (null);
}
2015-08-02 19:56:23 +02:00
private KeyDown getKeyDown(KeyboardData.Key key)
{
for (KeyDown k : _downKeys)
{
if (k.key == key)
2015-08-02 19:56:23 +02:00
return (k);
}
2015-08-02 19:56:23 +02:00
return (null);
}
private void onTouchMove(float moveX, float moveY, int pointerId)
{
KeyDown k = getKeyDown(pointerId);
2015-08-01 23:54:38 +02:00
if (k != null && k.updateDown(moveX, moveY))
updateFlags();
}
private void onTouchDown(float touchX, float touchY, int pointerId)
2015-07-31 01:14:35 +02:00
{
float x;
float y;
float keyW;
y = _verticalMargin - _keyHeight;
for (KeyboardData.Row row : _keyboard.getRows())
2015-07-30 20:14:55 +02:00
{
y += _keyHeight;
if (touchY < y || touchY >= (y + _keyHeight))
2015-07-31 01:14:35 +02:00
continue ;
x = (KEY_PER_ROW * _keyWidth - row.getWidth(_keyWidth)) / 2 + _horizontalMargin;
for (KeyboardData.Key key : row)
2015-07-30 20:14:55 +02:00
{
keyW = _keyWidth * key.width;
if (touchX >= x && touchX < (x + keyW))
2015-07-30 22:30:29 +02:00
{
2015-08-02 19:56:23 +02:00
KeyDown down = getKeyDown(key);
if (down != null)
{
2015-08-02 20:21:53 +02:00
if ((down.flags & KeyValue.FLAG_LOCK) != 0)
{
down.flags ^= KeyValue.FLAG_LOCK;
down.flags |= KeyValue.FLAG_LOCKED;
}
else if (down.pointerId == -1)
2015-08-02 19:56:23 +02:00
down.pointerId = pointerId;
}
else
_downKeys.add(new KeyDown(pointerId, key, touchX, touchY));
2015-08-01 23:54:38 +02:00
updateFlags();
invalidate();
return ;
2015-07-30 22:30:29 +02:00
}
x += keyW;
2015-07-30 20:14:55 +02:00
}
}
2015-07-31 01:14:35 +02:00
}
private void onTouchUp(int pointerId)
{
KeyDown k = getKeyDown(pointerId);
2015-08-01 16:33:30 +02:00
if (k != null)
2015-08-01 16:33:30 +02:00
{
2015-08-01 23:54:38 +02:00
if ((k.flags & KeyValue.FLAG_KEEP_ON) != 0)
{
k.flags ^= KeyValue.FLAG_KEEP_ON;
k.pointerId = -1;
return ;
}
for (int i = 0; i < _downKeys.size(); i++)
{
KeyDown downKey = _downKeys.get(i);
2015-08-02 20:21:53 +02:00
if (downKey.pointerId == -1 && (downKey.flags & KeyValue.FLAG_LOCKED) == 0)
2015-08-01 23:54:38 +02:00
_downKeys.remove(i--);
else if ((downKey.flags & KeyValue.FLAG_KEEP_ON) != 0)
downKey.flags ^= KeyValue.FLAG_KEEP_ON;
}
2015-08-02 20:21:53 +02:00
if (k.value != null && (k.flags & (KeyValue.FLAG_LOCKED | KeyValue.FLAG_NOCHAR)) == 0)
2015-08-01 23:54:38 +02:00
_ime.handleKeyUp(k.value, _flags);
_downKeys.remove(k);
2015-08-01 23:54:38 +02:00
updateFlags();
invalidate();
return ;
2015-07-31 01:14:35 +02:00
}
2015-07-30 20:14:55 +02:00
}
2015-08-01 23:54:38 +02:00
private void updateFlags()
{
_flags = 0;
for (KeyDown k : _downKeys)
_flags |= k.flags;
}
2015-07-30 20:14:55 +02:00
@Override
public void onMeasure(int wSpec, int hSpec)
{
int height;
if (_keyboard.getRows() == null)
2015-07-30 20:14:55 +02:00
height = 0;
else
height = (int)(_keyHeight * ((float)_keyboard.getRows().size())
+ (_verticalMargin * 2));
2015-07-30 20:14:55 +02:00
setMeasuredDimension(MeasureSpec.getSize(wSpec), height);
}
@Override
protected void onDraw(Canvas canvas)
{
float x;
float y;
2015-08-01 23:54:38 +02:00
boolean upperCase = ((_flags & KeyValue.FLAG_SHIFT) != 0);
2015-07-30 20:14:55 +02:00
y = _verticalMargin;
for (KeyboardData.Row row : _keyboard.getRows())
2015-07-30 20:14:55 +02:00
{
x = (KEY_PER_ROW * _keyWidth - row.getWidth(_keyWidth)) / 2 + _horizontalMargin;
for (KeyboardData.Key k : row)
2015-07-30 20:14:55 +02:00
{
float keyW = _keyWidth * k.width;
2015-08-02 20:21:53 +02:00
KeyDown keyDown = getKeyDown(k);
if (keyDown != null)
canvas.drawRect(x + _keyBgPadding, y + _keyBgPadding,
x + keyW - _keyBgPadding, y + _keyHeight - _keyBgPadding, _keyDownBgPaint);
2015-07-30 22:30:29 +02:00
else
2015-08-01 21:36:40 +02:00
canvas.drawRoundRect(new RectF(x + _keyBgPadding, y + _keyBgPadding,
x + keyW - _keyBgPadding, y + _keyHeight - _keyBgPadding), _keyRound, _keyRound, _keyBgPaint);
2015-07-30 20:14:55 +02:00
if (k.key0 != null)
2015-08-01 23:54:38 +02:00
canvas.drawText(k.key0.getSymbol(upperCase), keyW / 2 + x,
2015-08-02 20:21:53 +02:00
(_keyHeight + _keyLabelPaint.getTextSize()) / 2 + y,
(keyDown != null && (keyDown.flags & KeyValue.FLAG_LOCKED) != 0)
? _keyLabelLockedPaint : _keyLabelPaint);
2015-07-31 23:17:07 +02:00
float textOffsetY = _keySubLabelPaint.getTextSize() / 2;
float subPadding = _keyPadding + _keyBgPadding;
2015-07-30 20:14:55 +02:00
if (k.key1 != null)
2015-08-01 23:54:38 +02:00
canvas.drawText(k.key1.getSymbol(upperCase), x + subPadding,
y + subPadding + textOffsetY, _keySubLabelPaint);
2015-07-30 20:14:55 +02:00
if (k.key2 != null)
2015-08-01 23:54:38 +02:00
canvas.drawText(k.key2.getSymbol(upperCase), x + keyW - subPadding,
y + subPadding + textOffsetY, _keySubLabelPaint);
2015-07-31 23:52:47 +02:00
textOffsetY /= 2; // lol
2015-07-30 20:14:55 +02:00
if (k.key3 != null)
2015-08-01 23:54:38 +02:00
canvas.drawText(k.key3.getSymbol(upperCase), x + subPadding,
y + _keyHeight - subPadding + textOffsetY, _keySubLabelPaint);
2015-07-30 20:14:55 +02:00
if (k.key4 != null)
2015-08-01 23:54:38 +02:00
canvas.drawText(k.key4.getSymbol(upperCase), x + keyW - subPadding,
y + _keyHeight - subPadding + textOffsetY, _keySubLabelPaint);
x += keyW;
2015-07-30 20:14:55 +02:00
}
y += _keyHeight;
2015-07-30 20:14:55 +02:00
}
}
private class KeyDown
{
private static final float SUB_VALUE_DIST = 6f;
public int pointerId;
public KeyValue value;
public KeyboardData.Key key;
public float downX;
public float downY;
2015-08-01 23:54:38 +02:00
public int flags;
public KeyDown(int pointerId, KeyboardData.Key key, float x, float y)
{
this.pointerId = pointerId;
2015-08-01 21:36:40 +02:00
value = key.key0;
this.key = key;
2015-08-01 21:36:40 +02:00
downX = x;
downY = y;
2015-08-02 19:56:23 +02:00
flags = (value == null) ? 0 : value.getFlags();
}
2015-08-01 21:36:40 +02:00
public boolean updateDown(float x, float y)
{
2015-08-01 21:36:40 +02:00
KeyValue newValue = getDownValue(x - downX, y - downY);
if (newValue != null && newValue != value)
{
value = newValue;
2015-08-01 23:54:38 +02:00
flags = newValue.getFlags();
2015-08-01 21:36:40 +02:00
return (true);
}
return (false);
}
private KeyValue getDownValue(float x, float y)
{
if ((Math.abs(x) + Math.abs(y)) < SUB_VALUE_DIST)
return (key.key0);
if (x < 0)
{
if (y < 0)
return (key.key1);
return (key.key3);
}
else if (y < 0)
return (key.key2);
return (key.key4);
}
}
2015-07-30 20:14:55 +02:00
}