2015-07-30 20:14:55 +02:00
|
|
|
package juloo.keyboard2;
|
|
|
|
|
|
|
|
import android.content.Context;
|
|
|
|
import android.graphics.Canvas;
|
|
|
|
import android.graphics.Paint;
|
2015-09-30 22:47:18 +02:00
|
|
|
import android.graphics.RectF;
|
2015-10-13 00:02:34 +02:00
|
|
|
import android.graphics.Typeface;
|
2015-08-05 01:30:56 +02:00
|
|
|
import android.os.Handler;
|
|
|
|
import android.os.Message;
|
2015-08-03 00:01:04 +02:00
|
|
|
import android.os.Vibrator;
|
2015-09-30 22:47:18 +02:00
|
|
|
import android.util.AttributeSet;
|
|
|
|
import android.util.DisplayMetrics;
|
2015-07-30 20:14:55 +02:00
|
|
|
import android.view.MotionEvent;
|
|
|
|
import android.view.View;
|
2015-10-28 00:39:20 +01:00
|
|
|
import android.widget.PopupWindow;
|
2015-10-03 00:19:17 +02:00
|
|
|
import java.util.ArrayList;
|
2015-07-30 20:14:55 +02:00
|
|
|
|
|
|
|
public class Keyboard2View extends View
|
2015-08-05 01:30:56 +02:00
|
|
|
implements View.OnTouchListener, Handler.Callback
|
2015-07-30 20:14:55 +02:00
|
|
|
{
|
2015-08-08 15:26:23 +02:00
|
|
|
private static final long VIBRATE_MIN_INTERVAL = 100;
|
2015-07-30 20:14:55 +02:00
|
|
|
|
2015-10-29 12:49:40 +01:00
|
|
|
private KeyboardData _keyboard;
|
2015-07-30 20:14:55 +02:00
|
|
|
|
2015-10-03 00:19:17 +02:00
|
|
|
private ArrayList<KeyDown> _downKeys = new ArrayList<KeyDown>();
|
2015-08-01 23:54:38 +02:00
|
|
|
|
2015-10-29 12:49:40 +01:00
|
|
|
private int _flags = 0;
|
2015-08-01 16:33:30 +02:00
|
|
|
|
2015-10-29 12:49:40 +01:00
|
|
|
private Vibrator _vibratorService;
|
|
|
|
private long _lastVibration = 0;
|
2015-08-03 00:01:04 +02:00
|
|
|
|
2015-10-29 12:49:40 +01:00
|
|
|
private Handler _handler;
|
|
|
|
private static int _currentWhat = 0;
|
2015-08-05 01:30:56 +02:00
|
|
|
|
2015-10-29 12:49:40 +01:00
|
|
|
private Config _config;
|
|
|
|
|
|
|
|
private float _keyWidth;
|
|
|
|
|
|
|
|
private static Paint _keyBgPaint = new Paint();
|
|
|
|
private static Paint _keyDownBgPaint = new Paint();
|
|
|
|
private static Paint _keyLabelPaint;
|
|
|
|
private static Paint _keyLabelLockedPaint;
|
|
|
|
private static Paint _keySubLabelPaint;
|
|
|
|
private static Paint _keySubLabelRightPaint;
|
|
|
|
private static Paint _specialKeyLabelPaint;
|
|
|
|
private static Paint _specialKeyLabelLockedPaint;
|
|
|
|
private static Paint _specialKeySubLabelPaint;
|
|
|
|
private static Paint _specialKeySubLabelRightPaint;
|
|
|
|
|
|
|
|
private static RectF _tmpRect = new RectF();
|
2015-07-30 20:14:55 +02:00
|
|
|
|
|
|
|
public Keyboard2View(Context context, AttributeSet attrs)
|
|
|
|
{
|
|
|
|
super(context, attrs);
|
2015-08-03 00:01:04 +02:00
|
|
|
_vibratorService = (Vibrator)context.getSystemService(Context.VIBRATOR_SERVICE);
|
2015-08-05 01:30:56 +02:00
|
|
|
_handler = new Handler(this);
|
2015-10-29 12:49:40 +01:00
|
|
|
_config = ((Keyboard2)context).getConfig();
|
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));
|
2015-10-24 16:32:49 +02:00
|
|
|
_keyLabelPaint = initLabelPaint(_keyLabelPaint, Paint.Align.CENTER, R.color.key_label, R.dimen.label_text_size, null);
|
|
|
|
_keyLabelLockedPaint = initLabelPaint(_keyLabelLockedPaint, Paint.Align.CENTER, R.color.key_label_locked, R.dimen.label_text_size, null);
|
|
|
|
_keySubLabelPaint = initLabelPaint(_keySubLabelPaint, Paint.Align.LEFT, R.color.key_sub_label, R.dimen.sublabel_text_size, null);
|
|
|
|
_keySubLabelRightPaint = initLabelPaint(_keySubLabelRightPaint, Paint.Align.RIGHT, R.color.key_sub_label, R.dimen.sublabel_text_size, null);
|
|
|
|
Typeface specialKeysFont = ((Keyboard2)getContext()).getSpecialKeyFont();
|
|
|
|
_specialKeyLabelPaint = initLabelPaint(_specialKeyLabelPaint, Paint.Align.CENTER, R.color.key_label, R.dimen.label_text_size, specialKeysFont);
|
|
|
|
_specialKeyLabelLockedPaint = initLabelPaint(_specialKeyLabelLockedPaint, Paint.Align.CENTER, R.color.key_label_locked, R.dimen.label_text_size, specialKeysFont);
|
|
|
|
_specialKeySubLabelPaint = initLabelPaint(_specialKeySubLabelPaint, Paint.Align.LEFT, R.color.key_sub_label, R.dimen.sublabel_text_size, specialKeysFont);
|
|
|
|
_specialKeySubLabelRightPaint = initLabelPaint(_specialKeySubLabelRightPaint, Paint.Align.RIGHT, R.color.key_sub_label, R.dimen.sublabel_text_size, specialKeysFont);
|
2015-07-30 20:14:55 +02:00
|
|
|
setOnTouchListener(this);
|
|
|
|
}
|
|
|
|
|
2015-10-24 16:32:49 +02:00
|
|
|
private Paint initLabelPaint(Paint paint, Paint.Align align, int color, int size, Typeface font)
|
2015-10-13 00:02:34 +02:00
|
|
|
{
|
2015-10-24 16:32:49 +02:00
|
|
|
if (paint == null)
|
|
|
|
{
|
|
|
|
paint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
|
|
|
paint.setTextAlign(align);
|
|
|
|
paint.setColor(getResources().getColor(color));
|
|
|
|
paint.setTextSize(getResources().getDimension(size));
|
|
|
|
if (font != null)
|
|
|
|
paint.setTypeface(font);
|
|
|
|
}
|
2015-10-13 00:02:34 +02:00
|
|
|
return (paint);
|
|
|
|
}
|
|
|
|
|
2021-04-18 00:55:31 +02:00
|
|
|
public void setKeyboard(KeyboardData kw)
|
2015-10-11 15:30:39 +02:00
|
|
|
{
|
2021-04-18 00:55:31 +02:00
|
|
|
if (!_config.shouldOfferSwitchingToNextInputMethod)
|
|
|
|
kw = kw.removeKeys(new KeyboardData.RemoveKeysByEvent(KeyValue.EVENT_CHANGE_METHOD));
|
2021-04-15 23:23:31 +02:00
|
|
|
if (_config.disableAccentKeys)
|
2021-04-18 00:55:31 +02:00
|
|
|
kw = kw.removeKeys(new KeyboardData.RemoveKeysByFlags(KeyValue.FLAGS_ACCENTS));
|
|
|
|
_keyboard = kw;
|
2015-08-08 22:24:19 +02:00
|
|
|
reset();
|
2015-08-08 16:47:22 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public void reset()
|
|
|
|
{
|
|
|
|
_flags = 0;
|
2015-08-08 22:24:19 +02:00
|
|
|
_downKeys.clear();
|
2015-08-03 20:01:05 +02:00
|
|
|
requestLayout();
|
|
|
|
invalidate();
|
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;
|
2015-07-31 20:48:19 +02:00
|
|
|
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:
|
2015-07-31 20:48:19 +02:00
|
|
|
p = event.getActionIndex();
|
2015-07-31 01:14:35 +02:00
|
|
|
onTouchDown(event.getX(p), event.getY(p), event.getPointerId(p));
|
|
|
|
break ;
|
2015-07-31 20:48:19 +02:00
|
|
|
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);
|
|
|
|
}
|
|
|
|
|
2015-08-01 18:21:10 +02:00
|
|
|
private KeyDown getKeyDown(int pointerId)
|
2015-07-31 20:48:19 +02:00
|
|
|
{
|
2015-08-01 18:21:10 +02:00
|
|
|
for (KeyDown k : _downKeys)
|
2015-07-31 20:48:19 +02:00
|
|
|
{
|
2015-08-01 18:21:10 +02:00
|
|
|
if (k.pointerId == pointerId)
|
|
|
|
return (k);
|
2015-07-31 20:48:19 +02:00
|
|
|
}
|
2015-08-01 18:21:10 +02:00
|
|
|
return (null);
|
|
|
|
}
|
|
|
|
|
2015-08-02 19:56:23 +02:00
|
|
|
private KeyDown getKeyDown(KeyboardData.Key key)
|
2015-08-01 18:21:10 +02:00
|
|
|
{
|
|
|
|
for (KeyDown k : _downKeys)
|
|
|
|
{
|
|
|
|
if (k.key == key)
|
2015-08-02 19:56:23 +02:00
|
|
|
return (k);
|
2015-08-01 18:21:10 +02:00
|
|
|
}
|
2015-08-02 19:56:23 +02:00
|
|
|
return (null);
|
2015-08-01 18:21:10 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
private void onTouchMove(float moveX, float moveY, int pointerId)
|
|
|
|
{
|
2015-08-03 15:11:11 +02:00
|
|
|
KeyDown key = getKeyDown(pointerId);
|
|
|
|
KeyValue newValue;
|
2015-08-01 18:21:10 +02:00
|
|
|
|
2015-08-03 15:11:11 +02:00
|
|
|
if (key != null)
|
2015-08-03 00:01:04 +02:00
|
|
|
{
|
2015-08-03 15:11:11 +02:00
|
|
|
moveX -= key.downX;
|
|
|
|
moveY -= key.downY;
|
2021-04-20 00:10:45 +02:00
|
|
|
float absDist = Math.abs(moveX) + Math.abs(moveY);
|
|
|
|
key.ptrDist = absDist;
|
|
|
|
if (absDist < _config.subValueDist)
|
2015-08-03 15:11:11 +02:00
|
|
|
newValue = key.key.key0;
|
|
|
|
else if (moveX < 0)
|
|
|
|
newValue = (moveY < 0) ? key.key.key1 : key.key.key3;
|
|
|
|
else if (moveY < 0)
|
|
|
|
newValue = key.key.key2;
|
|
|
|
else
|
|
|
|
newValue = key.key.key4;
|
|
|
|
if (newValue != null && newValue != key.value)
|
|
|
|
{
|
2015-08-05 01:30:56 +02:00
|
|
|
if (key.timeoutWhat != -1)
|
2015-08-03 15:11:11 +02:00
|
|
|
{
|
2015-08-05 01:30:56 +02:00
|
|
|
_handler.removeMessages(key.timeoutWhat);
|
2021-04-18 23:28:49 +02:00
|
|
|
if ((newValue.flags & KeyValue.FLAG_NOREPEAT) == 0)
|
2015-10-29 12:49:40 +01:00
|
|
|
_handler.sendEmptyMessageDelayed(key.timeoutWhat, _config.longPressTimeout);
|
2015-08-03 15:11:11 +02:00
|
|
|
}
|
2015-08-05 01:30:56 +02:00
|
|
|
key.value = newValue;
|
2021-04-18 23:28:49 +02:00
|
|
|
key.flags = newValue.flags;
|
2015-08-05 01:30:56 +02:00
|
|
|
updateFlags();
|
2015-08-18 01:25:47 +02:00
|
|
|
invalidate();
|
2015-10-28 00:39:20 +01:00
|
|
|
handleKeyDown(newValue);
|
2015-08-03 15:11:11 +02:00
|
|
|
}
|
2015-08-03 00:01:04 +02:00
|
|
|
}
|
2015-07-31 20:48:19 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
private void onTouchDown(float touchX, float touchY, int pointerId)
|
2015-07-31 01:14:35 +02:00
|
|
|
{
|
2021-04-17 23:56:51 +02:00
|
|
|
float y = _config.marginTop - _config.keyHeight;
|
2015-07-31 20:48:19 +02:00
|
|
|
for (KeyboardData.Row row : _keyboard.getRows())
|
2015-07-30 20:14:55 +02:00
|
|
|
{
|
2015-10-29 12:49:40 +01:00
|
|
|
y += _config.keyHeight;
|
|
|
|
if (touchY < y || touchY >= (y + _config.keyHeight))
|
2015-07-31 01:14:35 +02:00
|
|
|
continue ;
|
2021-04-17 23:56:51 +02:00
|
|
|
float x = _config.horizontalMargin;
|
2021-04-15 23:23:31 +02:00
|
|
|
for (KeyboardData.Key key : row.getKeys())
|
2015-07-30 20:14:55 +02:00
|
|
|
{
|
2021-04-17 23:56:51 +02:00
|
|
|
x += key.shift * _keyWidth;
|
|
|
|
float keyW = _keyWidth * key.width;
|
2015-08-01 18:21:10 +02:00
|
|
|
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
|
2015-08-05 01:30:56 +02:00
|
|
|
{
|
|
|
|
int what = _currentWhat++;
|
2021-04-18 23:28:49 +02:00
|
|
|
if (key.key0 != null && (key.key0.flags & KeyValue.FLAG_NOREPEAT) == 0)
|
2015-10-29 12:49:40 +01:00
|
|
|
_handler.sendEmptyMessageDelayed(what, _config.longPressTimeout);
|
2015-08-05 01:30:56 +02:00
|
|
|
_downKeys.add(new KeyDown(pointerId, key, touchX, touchY, what));
|
|
|
|
}
|
2015-10-28 00:39:20 +01:00
|
|
|
handleKeyDown(key.key0);
|
2015-08-01 23:54:38 +02:00
|
|
|
updateFlags();
|
2015-07-31 20:48:19 +02:00
|
|
|
invalidate();
|
|
|
|
return ;
|
2015-07-30 22:30:29 +02:00
|
|
|
}
|
2015-08-01 01:36:41 +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)
|
|
|
|
{
|
2015-08-01 18:21:10 +02:00
|
|
|
KeyDown k = getKeyDown(pointerId);
|
2015-08-01 16:33:30 +02:00
|
|
|
|
2015-08-01 18:21:10 +02:00
|
|
|
if (k != null)
|
2015-08-01 16:33:30 +02:00
|
|
|
{
|
2015-08-05 01:30:56 +02:00
|
|
|
if (k.timeoutWhat != -1)
|
|
|
|
{
|
|
|
|
_handler.removeMessages(k.timeoutWhat);
|
|
|
|
k.timeoutWhat = -1;
|
|
|
|
}
|
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-01 18:21:10 +02:00
|
|
|
_downKeys.remove(k);
|
2015-10-28 00:39:20 +01:00
|
|
|
handleKeyUp(k);
|
2015-08-01 23:54:38 +02:00
|
|
|
updateFlags();
|
2015-08-01 18:21:10 +02:00
|
|
|
invalidate();
|
|
|
|
return ;
|
2015-07-31 01:14:35 +02:00
|
|
|
}
|
2015-07-30 20:14:55 +02:00
|
|
|
}
|
|
|
|
|
2015-10-28 00:39:20 +01:00
|
|
|
private void handleKeyUp(KeyDown key)
|
|
|
|
{
|
|
|
|
if (key.value != null && (key.flags & (KeyValue.FLAG_LOCKED | KeyValue.FLAG_NOCHAR)) == 0)
|
|
|
|
((Keyboard2)getContext()).handleKeyUp(key.value, _flags);
|
|
|
|
}
|
|
|
|
|
|
|
|
private void handleKeyDown(KeyValue key)
|
|
|
|
{
|
2015-10-28 20:56:28 +01:00
|
|
|
if (key == null)
|
|
|
|
return ;
|
2015-10-28 00:39:20 +01:00
|
|
|
vibrate();
|
|
|
|
}
|
|
|
|
|
2015-08-01 23:54:38 +02:00
|
|
|
private void updateFlags()
|
|
|
|
{
|
|
|
|
_flags = 0;
|
|
|
|
for (KeyDown k : _downKeys)
|
|
|
|
_flags |= k.flags;
|
|
|
|
}
|
|
|
|
|
2015-08-03 00:01:04 +02:00
|
|
|
private void vibrate()
|
|
|
|
{
|
2015-10-29 12:49:40 +01:00
|
|
|
if (!_config.vibrateEnabled)
|
2015-08-08 15:26:23 +02:00
|
|
|
return ;
|
|
|
|
long now = System.currentTimeMillis();
|
2015-08-03 00:01:04 +02:00
|
|
|
if ((now - _lastVibration) > VIBRATE_MIN_INTERVAL)
|
|
|
|
{
|
|
|
|
_lastVibration = now;
|
|
|
|
try
|
|
|
|
{
|
2015-10-29 12:49:40 +01:00
|
|
|
_vibratorService.vibrate(_config.vibrateDuration);
|
2015-08-03 00:01:04 +02:00
|
|
|
}
|
|
|
|
catch (Exception e)
|
|
|
|
{
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-08-05 01:30:56 +02:00
|
|
|
@Override
|
|
|
|
public boolean handleMessage(Message msg)
|
|
|
|
{
|
|
|
|
for (KeyDown key : _downKeys)
|
|
|
|
{
|
|
|
|
if (key.timeoutWhat == msg.what)
|
|
|
|
{
|
2021-04-20 00:10:45 +02:00
|
|
|
long nextInterval = _config.longPressInterval;
|
2021-04-20 00:34:21 +02:00
|
|
|
if (_config.preciseRepeat && (key.flags & KeyValue.FLAG_PRECISE_REPEAT) != 0)
|
2021-04-20 00:10:45 +02:00
|
|
|
{
|
|
|
|
// Modulate repeat interval depending on the distance of the pointer
|
|
|
|
float accel = Math.min(4.f, Math.max(0.3f, key.ptrDist / (_config.subValueDist * 15.f)));
|
|
|
|
nextInterval = (long)((float)nextInterval / accel);
|
|
|
|
}
|
|
|
|
_handler.sendEmptyMessageDelayed(msg.what, nextInterval);
|
2015-10-24 16:32:49 +02:00
|
|
|
((Keyboard2)getContext()).handleKeyUp(key.value, _flags);
|
2015-08-05 01:30:56 +02:00
|
|
|
return (true);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return (false);
|
|
|
|
}
|
|
|
|
|
2015-07-30 20:14:55 +02:00
|
|
|
@Override
|
|
|
|
public void onMeasure(int wSpec, int hSpec)
|
|
|
|
{
|
2015-08-02 23:36:22 +02:00
|
|
|
DisplayMetrics dm = getContext().getResources().getDisplayMetrics();
|
2015-07-30 20:14:55 +02:00
|
|
|
int height;
|
|
|
|
|
2015-07-31 20:48:19 +02:00
|
|
|
if (_keyboard.getRows() == null)
|
2015-07-30 20:14:55 +02:00
|
|
|
height = 0;
|
|
|
|
else
|
2015-10-29 12:49:40 +01:00
|
|
|
height = (int)(_config.keyHeight * ((float)_keyboard.getRows().size())
|
|
|
|
+ _config.marginTop + _config.marginBottom);
|
2015-08-02 23:36:22 +02:00
|
|
|
setMeasuredDimension(dm.widthPixels, height);
|
2021-04-17 23:56:51 +02:00
|
|
|
_keyWidth = (getWidth() - (_config.horizontalMargin * 2)) / _keyboard.getKeysWidth();
|
2015-07-30 20:14:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
protected void onDraw(Canvas canvas)
|
|
|
|
{
|
2021-04-17 23:56:51 +02:00
|
|
|
float y = _config.marginTop;
|
2015-07-31 20:48:19 +02:00
|
|
|
for (KeyboardData.Row row : _keyboard.getRows())
|
2015-07-30 20:14:55 +02:00
|
|
|
{
|
2021-04-17 23:56:51 +02:00
|
|
|
float x = _config.horizontalMargin;
|
2021-04-15 23:23:31 +02:00
|
|
|
for (KeyboardData.Key k : row.getKeys())
|
2015-07-30 20:14:55 +02:00
|
|
|
{
|
2021-04-17 23:56:51 +02:00
|
|
|
x += k.shift * _keyWidth;
|
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);
|
2015-10-29 12:49:40 +01:00
|
|
|
_tmpRect.set(x + _config.keyBgPadding, y + _config.keyBgPadding,
|
|
|
|
x + keyW - _config.keyBgPadding, y + _config.keyHeight - _config.keyBgPadding);
|
2015-08-02 20:21:53 +02:00
|
|
|
if (keyDown != null)
|
2015-10-03 00:19:17 +02:00
|
|
|
canvas.drawRect(_tmpRect, _keyDownBgPaint);
|
2015-07-30 22:30:29 +02:00
|
|
|
else
|
2015-10-29 12:49:40 +01:00
|
|
|
canvas.drawRoundRect(_tmpRect, _config.keyRound, _config.keyRound, _keyBgPaint);
|
2015-07-30 20:14:55 +02:00
|
|
|
if (k.key0 != null)
|
2015-10-29 12:49:40 +01:00
|
|
|
drawLabel(canvas, k.key0, keyW / 2f + x, (_config.keyHeight + _keyLabelPaint.getTextSize()) / 2f + y,
|
2015-10-13 00:02:34 +02:00
|
|
|
(keyDown != null && (keyDown.flags & KeyValue.FLAG_LOCKED) != 0));
|
2015-10-29 12:49:40 +01:00
|
|
|
float subPadding = _config.keyBgPadding + _config.keyPadding;
|
2015-07-30 20:14:55 +02:00
|
|
|
if (k.key1 != null)
|
2015-10-13 00:02:34 +02:00
|
|
|
drawSubLabel(canvas, k.key1, x + subPadding, y + subPadding - _keySubLabelPaint.ascent(), false);
|
2015-07-30 20:14:55 +02:00
|
|
|
if (k.key3 != null)
|
2015-10-29 12:49:40 +01:00
|
|
|
drawSubLabel(canvas, k.key3, x + subPadding, y + _config.keyHeight - subPadding - _keySubLabelPaint.descent(), false);
|
2015-08-03 15:11:11 +02:00
|
|
|
if (k.key2 != null)
|
2015-10-13 00:02:34 +02:00
|
|
|
drawSubLabel(canvas, k.key2, x + keyW - subPadding, y + subPadding - _keySubLabelRightPaint.ascent(), true);
|
2015-07-30 20:14:55 +02:00
|
|
|
if (k.key4 != null)
|
2015-10-29 12:49:40 +01:00
|
|
|
drawSubLabel(canvas, k.key4, x + keyW - subPadding, y + _config.keyHeight - subPadding - _keySubLabelRightPaint.descent(), true);
|
2015-08-01 01:36:41 +02:00
|
|
|
x += keyW;
|
2015-07-30 20:14:55 +02:00
|
|
|
}
|
2015-10-29 12:49:40 +01:00
|
|
|
y += _config.keyHeight;
|
2015-07-30 20:14:55 +02:00
|
|
|
}
|
|
|
|
}
|
2015-08-01 18:21:10 +02:00
|
|
|
|
2015-10-28 00:39:20 +01:00
|
|
|
@Override
|
|
|
|
public void onDetachedFromWindow()
|
|
|
|
{
|
|
|
|
super.onDetachedFromWindow();
|
|
|
|
}
|
|
|
|
|
2015-10-13 00:02:34 +02:00
|
|
|
private void drawLabel(Canvas canvas, KeyValue k, float x, float y, boolean locked)
|
|
|
|
{
|
2021-04-18 23:28:49 +02:00
|
|
|
k = KeyModifier.handleFlags(k, _flags);
|
|
|
|
if ((k.flags & KeyValue.FLAG_KEY_FONT) != 0)
|
|
|
|
canvas.drawText(k.symbol, x, y, locked ? _specialKeyLabelLockedPaint : _specialKeyLabelPaint);
|
2015-10-13 00:02:34 +02:00
|
|
|
else
|
2021-04-18 23:28:49 +02:00
|
|
|
canvas.drawText(k.symbol, x, y, locked ? _keyLabelLockedPaint : _keyLabelPaint);
|
2015-10-13 00:02:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
private void drawSubLabel(Canvas canvas, KeyValue k, float x, float y, boolean right)
|
|
|
|
{
|
2021-04-18 23:28:49 +02:00
|
|
|
k = KeyModifier.handleFlags(k, _flags);
|
|
|
|
if ((k.flags & KeyValue.FLAG_KEY_FONT) != 0)
|
|
|
|
canvas.drawText(k.symbol, x, y, right ? _specialKeySubLabelRightPaint : _specialKeySubLabelPaint);
|
2015-10-13 00:02:34 +02:00
|
|
|
else
|
2021-04-18 23:28:49 +02:00
|
|
|
canvas.drawText(k.symbol, x, y, right ? _keySubLabelRightPaint : _keySubLabelPaint);
|
2015-10-13 00:02:34 +02:00
|
|
|
}
|
|
|
|
|
2015-10-23 14:22:43 +02:00
|
|
|
private static class KeyDown
|
2015-08-01 18:21:10 +02:00
|
|
|
{
|
|
|
|
public int pointerId;
|
|
|
|
public KeyValue value;
|
|
|
|
public KeyboardData.Key key;
|
|
|
|
public float downX;
|
|
|
|
public float downY;
|
2021-04-20 00:10:45 +02:00
|
|
|
/* Manhattan distance of the pointer to the center of the key */
|
|
|
|
public float ptrDist;
|
2015-08-01 23:54:38 +02:00
|
|
|
public int flags;
|
2015-08-05 01:30:56 +02:00
|
|
|
public int timeoutWhat;
|
2015-08-01 18:21:10 +02:00
|
|
|
|
2015-08-05 01:30:56 +02:00
|
|
|
public KeyDown(int pointerId, KeyboardData.Key key, float x, float y, int what)
|
2015-08-01 18:21:10 +02:00
|
|
|
{
|
|
|
|
this.pointerId = pointerId;
|
2015-08-05 01:30:56 +02:00
|
|
|
value = key.key0;
|
2015-08-01 18:21:10 +02:00
|
|
|
this.key = key;
|
2015-08-01 21:36:40 +02:00
|
|
|
downX = x;
|
|
|
|
downY = y;
|
2021-04-20 00:10:45 +02:00
|
|
|
ptrDist = 0.f;
|
2021-04-18 23:28:49 +02:00
|
|
|
flags = (value == null) ? 0 : value.flags;
|
2015-08-05 01:30:56 +02:00
|
|
|
timeoutWhat = what;
|
2015-08-01 18:21:10 +02:00
|
|
|
}
|
|
|
|
}
|
2015-07-30 20:14:55 +02:00
|
|
|
}
|