Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using Android.Content;
- using Android.Views;
- using Android.Widget;
- using Android.Util;
- using Android.Graphics;
- using System.Threading;
- namespace Apps.Droid
- {
- public class KeyView : View, View.IOnTouchListener
- {
- public static int LongTouchDelay = 800; // .8 seconds
- public static int ShortTouchDelay = 100; // .1 seconds
- public static Color BG_NORMAL,
- BG_LIGHT, BG_DARK,
- FG_PRIMARYDARK,
- FG_PRIMARYLIGHT,
- FG_SECONDARY;
- protected KeyboardView keyboard;
- protected Key key;
- public int width { get; set; }
- public int height { get; set; }
- public bool isDown { get; set; }
- public KeyView(Context context, IAttributeSet attrs)
- : base(context, attrs)
- { }
- public KeyView(Context context, IAttributeSet attrs, int defStyle)
- : base(context, attrs, defStyle)
- { }
- public KeyView(Context context, IAttributeSet attrs, int defStyle, int defStyleRes)
- : base(context, attrs, defStyle, defStyleRes)
- { }
- protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec)
- {
- base.OnMeasure(widthMeasureSpec, heightMeasureSpec);
- SetMeasuredDimension(width, height);
- }
- // key views are always dynamically created
- public KeyView(Context ctx, KeyboardView parent, Key k, int leftMargin)
- : base(ctx)
- {
- // make sure the key will draw
- SetWillNotDraw(false);
- keyboard = parent;
- key = k;
- isDown = false;
- // check for an overridden span to adjust width, if needed
- int span = string.IsNullOrEmpty(key.Span) ? 1 : Convert.ToInt32(key.Span);
- int keyWidth = keyboard.keyWidth + ((span - 1) * keyboard.keyWidth);
- width = keyWidth;
- height = keyboard.keyHeight;
- // set margin
- var parameters = new LinearLayout.LayoutParams(
- LinearLayout.LayoutParams.WrapContent,
- LinearLayout.LayoutParams.MatchParent
- );
- parameters.LeftMargin = leftMargin;
- LayoutParameters = parameters;
- // set touch listener
- SetOnTouchListener(this);
- // enable haptic feedback for button presses
- HapticFeedbackEnabled = true;
- }
- protected override void OnDraw(Canvas canvas)
- {
- base.OnDraw(canvas);
- KeyState primary = key.Primary;
- KeyState secondary = key.Secondary;
- if (keyboard.swapped)
- {
- primary = key.Secondary != null ? key.Secondary : key.Primary;
- secondary = key.Secondary != null ? key.Primary : null;
- }
- if (keyboard.shifted)
- {
- if (primary.Shift != null)
- primary = primary.Shift;
- if (secondary != null && secondary.Shift != null)
- secondary = secondary.Shift;
- }
- // figure out what color the key is supposed to be
- Paint bg = new Paint(PaintFlags.AntiAlias);
- bg.Color = GetKeyBgColor(key.Style);
- if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.Lollipop)
- canvas.DrawRoundRect(keyboard.keyMargin, keyboard.keyMargin, width - keyboard.keyMargin, height - keyboard.keyMargin, keyboard.keyMargin, keyboard.keyMargin, bg);
- else
- canvas.DrawRoundRect(new RectF(keyboard.keyMargin, keyboard.keyMargin, width - keyboard.keyMargin, height - keyboard.keyMargin), keyboard.keyMargin, keyboard.keyMargin, bg);
- // draw primary key state
- Paint fg = new Paint(PaintFlags.AntiAlias);
- fg.TextSize = height * .5f;
- fg.Color = GetKeyFgColor(key.Style);
- string character = string.IsNullOrEmpty(primary.Character) ? "#" : primary.Character;
- int charWidth = Convert.ToInt32(fg.MeasureText(character));
- int charX = (width - charWidth) / 2;
- canvas.DrawText(character, charX, (height * .7f), fg);
- // draw secondary key state
- if (secondary != null)
- {
- fg.TextSize = height * .25f;
- fg.Color = GetKeyFgColor(key.Style, true);
- character = string.IsNullOrEmpty(secondary.Character) ? "#" : secondary.Character;
- charWidth = Convert.ToInt32(fg.MeasureText(character));
- charX = width - charWidth - (keyboard.keyMargin * 2);
- canvas.DrawText(character, charX, (height * .35f), fg);
- }
- }
- protected Color GetKeyBgColor(string style) {
- Color newColor = BG_NORMAL;
- if (key.Primary.Id == "shift" && keyboard.superShifted)
- return Color.Cyan;
- if (style != null) {
- if (style == "light")
- newColor = BG_LIGHT;
- else if (style == "dark")
- newColor = BG_DARK;
- }
- return newColor;
- }
- protected Color GetKeyFgColor(string style, bool IsSecondary = false)
- {
- if (IsSecondary)
- return FG_SECONDARY;
- Color newColor = FG_PRIMARYLIGHT;
- if (style != null && style == "dark")
- newColor = FG_PRIMARYDARK;
- return newColor;
- }
- public bool OnTouch(View v, MotionEvent e)
- {
- var activity = (MainActivity)Context;
- KeyboardPopupRowView popup = activity.kPopup;
- // capture position data
- int x = (int)e.GetX();
- int y = (int)e.GetY();
- switch (e.Action)
- {
- case MotionEventActions.Down:
- activity.Debug("[TOUCH] Down \"" + key.Primary.Id + "\"");
- // track the length of the down event to simulate a long touch
- TrackLongPress();
- int parentIndex = ((KeyboardView)v.Parent.Parent).IndexOfChild((View)v.Parent);
- int topOffset = keyboard.keyMargin + (parentIndex * keyboard.keyHeight);
- if (!key.SuppressPopup)
- popup.Show(v.Left, v.Top + topOffset, key);
- break;
- case MotionEventActions.Move:
- activity.Debug("[TOUCH] Move \"" + key.Primary.Id + "\" [" + x + ", " + y + "]");
- // check key bounds
- int leftBound = -keyboard.keyMargin - popup.offsetX;
- if (x < leftBound || y > keyboard.keyHeight || x > (popup.ChildCount * keyboard.keyWidth))
- {
- popup.Hide();
- return true;
- }
- bool popupHidden = popup.IsHidden();
- if (!popupHidden && y < 0 && y > -(keyboard.keyHeight + keyboard.keyMargin))
- {
- popup.Highlight(x);
- }
- break;
- case MotionEventActions.Up:
- activity.Debug("[TOUCH] Up \"" + key.Primary.Id + "\"");
- isDown = false;
- // short circuit the up if we've supershifted so we don't shift again
- if (keyboard.hasSuperShifted)
- {
- keyboard.hasSuperShifted = false;
- return true;
- }
- if (popup.activeKey != null)
- popup.activeKey.KeyUp();
- else
- KeyUp(keyboard.swapped);
- popup.Hide();
- // haptic feedback
- PerformHapticFeedback(FeedbackConstants.KeyboardTap);
- break;
- default:
- return false;
- }
- return true;
- }
- public void TrackLongPress()
- {
- if (key.Primary.Id == "shift")
- {
- isDown = true;
- ThreadPool.QueueUserWorkItem(o =>
- {
- Thread.Sleep(LongTouchDelay);
- ((MainActivity)Context).RunOnUiThread(() =>
- {
- if (isDown)
- keyboard.SuperShift();
- });
- });
- }
- if (key.Primary.Id == "backspace")
- {
- isDown = true;
- ThreadPool.QueueUserWorkItem(o =>
- {
- BackspaceWait(true);
- });
- }
- return;
- }
- public async void BackspaceWait(bool first = false)
- {
- int delay = first ? LongTouchDelay : ShortTouchDelay;
- Thread.Sleep(delay);
- if (isDown)
- {
- keyboard.Backspace();
- BackspaceWait();
- }
- }
- // key was pressed
- public virtual void KeyUp(bool secondary = false)
- {
- KeyState ks = secondary && key.Secondary != null ? key.Secondary : key.Primary;
- ((MainActivity)Context).Debug("[KEYUP] \"" + ks.Id + "\"");
- switch (ks.Id)
- {
- case "swap":
- keyboard.Swap();
- break;
- case "shift":
- keyboard.Shift();
- break;
- case "num":
- keyboard.LoadKeyboard(KeyboardType.MATH_SMALL);
- break;
- case "abc":
- keyboard.LoadKeyboard(KeyboardType.QWERTY);
- break;
- case "backspace":
- keyboard.Backspace();
- break;
- default:
- keyboard.InsertKey(ks);
- break;
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement