Advertisement
Guest User

KeyboardView.cs

a guest
Jan 6th, 2016
118
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 10.45 KB | None | 0 0
  1. using System;
  2. using System.Collections.Generic;
  3. using Android.Content;
  4. using Android.Widget;
  5. using Android.Util;
  6. using Android.Graphics;
  7. using System.IO;
  8. using Newtonsoft.Json;
  9. using Android.Views;
  10.  
  11. namespace Apps.Droid
  12. {
  13.     public class KeyboardView : LinearLayout
  14.     {
  15.         public static string JSON_PATH = "keyboard/",
  16.                              SMALL_PATH = JSON_PATH + "small/",
  17.                              LARGE_PATH = JSON_PATH + "large/",
  18.                              QWERTY_FILENAME = "qwerty.json",
  19.                              MATH_FILENAME = "math.json";
  20.  
  21.         public static Color BG;
  22.  
  23.         public int keyWidth { get; set; }
  24.         public int keyHeight { get; set; }
  25.         public int keyMargin { get; set; }
  26.         public bool swapped { get; set; }
  27.         public bool shifted { get; set; }
  28.         public bool superShifted { get; set; }
  29.         public bool hasSuperShifted { get; set; }
  30.         public string subject { get; set; }
  31.         protected Keyboard keyboard { get; set; }
  32.         protected List<List<KeyView>> keyLayout { get; set; }
  33.         protected bool isPortrait { get; set; }
  34.  
  35.         public KeyboardView(Context context, IAttributeSet attrs)
  36.             : base(context, attrs)
  37.         {
  38.             Init();
  39.         }
  40.  
  41.         public KeyboardView(Context context, IAttributeSet attrs, int defStyle)
  42.             : base(context, attrs, defStyle)
  43.         {
  44.             Init();
  45.         }
  46.  
  47.         public KeyboardView(Context context, IAttributeSet attrs, int defStyle, int defStyleRes)
  48.             : base(context, attrs, defStyle, defStyleRes)
  49.         {
  50.             Init();
  51.         }
  52.  
  53.         protected override void OnMeasure(int widthMeasureSpec, int heightMeasureSpec)
  54.         {
  55.             base.OnMeasure(widthMeasureSpec, heightMeasureSpec);
  56.  
  57.             RelativeLayout parent = (RelativeLayout)Parent;
  58.  
  59.             int newWidth = parent.Width,
  60.                 newHeight = 0;
  61.  
  62.             // account for landscape mode
  63.             if (parent.Width > parent.Height)
  64.             {
  65.                 isPortrait = false;
  66.                 newHeight = parent.Height / 2;
  67.             }
  68.             else
  69.             {
  70.                 isPortrait = true;
  71.                 newHeight = (int)(parent.Height * .4f);
  72.             }                
  73.  
  74.             ((MainActivity)Context).Debug("[" + newWidth + ", " + newHeight + "]");
  75.             SetMeasuredDimension(newWidth, newHeight);
  76.         }
  77.  
  78.         public void Init()
  79.         {
  80.             // make sure the keyboard will draw
  81.             SetWillNotDraw(false);
  82.  
  83.             // define colors from XML
  84.             KeyboardView.BG = Color.ParseColor(Context.GetString(Resource.Color.MWBlue));
  85.             KeyView.BG_NORMAL = Color.White;
  86.             KeyView.BG_LIGHT = Color.ParseColor(Context.GetString(Resource.Color.MWLightBlue));
  87.             KeyView.BG_DARK = Color.ParseColor(Context.GetString(Resource.Color.MWDarkBlue));
  88.             KeyView.FG_PRIMARYDARK = Color.White;
  89.             KeyView.FG_PRIMARYLIGHT = Color.Black;
  90.             KeyView.FG_SECONDARY = Color.ParseColor(Context.GetString(Resource.Color.MWGray));
  91.  
  92.             subject = "algebra";
  93.  
  94.             // default to qwerty
  95.             LoadKeyboard(KeyboardType.QWERTY, false);
  96.         }
  97.  
  98.         public void LoadKeyboard(KeyboardType type, bool invalidate = true)
  99.         {
  100.             // determine file path
  101.             string path = "";
  102.             string subjectPath = "";
  103.  
  104.             switch (type)
  105.             {
  106.                 case KeyboardType.MATH_LARGE:
  107.                     path = LARGE_PATH + MATH_FILENAME;
  108.                     subjectPath = LARGE_PATH + subject + ".json";
  109.                     break;
  110.                 case KeyboardType.MATH_SMALL:
  111.                     path = SMALL_PATH + MATH_FILENAME;
  112.                     subjectPath = SMALL_PATH + subject + ".json";
  113.                     break;
  114.                 default:
  115.                 case KeyboardType.QWERTY:
  116.                     path = JSON_PATH + QWERTY_FILENAME;
  117.                     break;
  118.             }
  119.  
  120.             // create a new keyboard object
  121.             string json = "",
  122.                    subjectJson = "";
  123.             using (StreamReader sr = new StreamReader(Context.Assets.Open(path)))
  124.             {
  125.                 json = sr.ReadToEnd();
  126.             }
  127.  
  128.             if (!string.IsNullOrEmpty(subjectPath))
  129.             {
  130.                 using (StreamReader sr = new StreamReader(Context.Assets.Open(subjectPath)))
  131.                 {
  132.                     subjectJson = sr.ReadToEnd();
  133.                 }
  134.             }
  135.  
  136.             // tell the draw to rebuild
  137.             keyLayout = null;
  138.  
  139.             // default the states
  140.             swapped = false;
  141.             shifted = false;
  142.             hasSuperShifted = false;
  143.  
  144.             keyboard = Keyboard.Create(type, json, subjectJson);
  145.  
  146.             if (invalidate)
  147.                 PostInvalidate();
  148.         }
  149.  
  150.         public void Build()
  151.         {
  152.             // only build once
  153.             if (keyLayout != null)
  154.                 return;
  155.  
  156.             // clear out children
  157.             RemoveAllViews();
  158.  
  159.             // define sizes of stuff
  160.             if (isPortrait)
  161.             {
  162.                 keyMargin = (int)(MeasuredWidth * .01f);
  163.             }
  164.             else
  165.             {
  166.                 keyMargin = (int)(MeasuredHeight * .01f);
  167.             }
  168.  
  169.             keyWidth = (MeasuredWidth - (keyMargin * 2)) / keyboard.MaxCols;
  170.             keyHeight = (MeasuredHeight - (keyMargin * 2)) / keyboard.Rows.Count;
  171.  
  172.             // set general padding around keyboardview
  173.             SetPadding(keyMargin, keyMargin, keyMargin, keyMargin);
  174.  
  175.             // build KeyLayout from the keyboard object
  176.             keyLayout = new List<List<KeyView>>();
  177.             int idx = 0;
  178.             foreach (List<Key> row in keyboard.Rows)
  179.             {
  180.                 keyLayout.Add(new List<KeyView>());
  181.  
  182.                 // create and add new KeyboardRowView
  183.                 KeyboardRowView krv = new KeyboardRowView(Context, this, idx);
  184.                 AddView(krv);
  185.  
  186.                 // figure out if we need a margin offset for this row
  187.                 int extraMargin = 0;
  188.                 int numCols = CountRowCols(row);
  189.                 if (numCols < keyboard.MaxCols)
  190.                 {
  191.                     // measure full width of the button container and the total row margin
  192.                     int rowWidth = (int)(numCols * keyWidth);
  193.                     int rowMargin = MeasuredWidth - (keyMargin * 2) - rowWidth;
  194.  
  195.                     // add the offset
  196.                     extraMargin = rowMargin / 2;
  197.                 }
  198.  
  199.                 // build keys and add them to keyLayout and KeyboardRowView
  200.                 int idx2 = 0;
  201.                 foreach (Key key in row)
  202.                 {
  203.                     int leftMargin = idx2 == 0 ? extraMargin : 0;
  204.                     KeyView kv = new KeyView(Context, this, key, leftMargin);
  205.                     keyLayout[idx].Add(kv);
  206.                     krv.AddView(kv);
  207.  
  208.                     idx2++;
  209.                 }
  210.  
  211.                 idx++;
  212.             }
  213.         }
  214.  
  215.         protected override void OnDraw(Canvas canvas)
  216.         {
  217.             Build();
  218.            
  219.             base.OnDraw(canvas);
  220.  
  221.             // background
  222.             Paint bg = new Paint(PaintFlags.AntiAlias);
  223.             bg.Color = BG; // light blue
  224.             canvas.DrawRect(0, 0, MeasuredWidth, Height, bg);
  225.  
  226.             //InvalidateKeys();
  227.         }
  228.  
  229.         // invalidate all the KeyView children manually since Android can't seem to follow its own rules
  230.         protected void InvalidateKeys()
  231.         {
  232.             for (int idx = 0; idx < ChildCount; idx++)
  233.             {
  234.                 KeyboardRowView krv = (KeyboardRowView)GetChildAt(idx);
  235.                 for (int idx2 = 0; idx2 < krv.ChildCount; idx2++)
  236.                 {
  237.                     KeyView kv = (KeyView)krv.GetChildAt(idx2);
  238.                     kv.Invalidate();
  239.                 }
  240.             }
  241.         }
  242.  
  243.         // invalidate all KeyView's children of this view so they redraw
  244.         //protected void DrawChildren(Canvas canvas)
  245.         //{
  246.         //    for (int idx = 0; idx < ChildCount; idx++)
  247.         //    {
  248.         //        KeyboardRowView krv = (KeyboardRowView)GetChildAt(idx);
  249.         //        for (int idx2 = 0; idx2 < krv.ChildCount; idx2++)
  250.         //        {
  251.         //            KeyView kv = (KeyView)krv.GetChildAt(idx2);
  252.         //            kv.Draw(canvas);
  253.         //        }
  254.         //    }
  255.         //}
  256.  
  257.         protected int CountRowCols(List<Key> row)
  258.         {
  259.             int cols = 0;
  260.  
  261.             foreach (Key k in row)
  262.             {
  263.                 int span = string.IsNullOrEmpty(k.Span) ? 1 : Convert.ToInt32(k.Span);
  264.                 cols += span;
  265.             }
  266.  
  267.             return cols;
  268.         }
  269.  
  270.         public void Swap()
  271.         {
  272.             swapped = swapped ? false : true;
  273.             PostInvalidate();
  274.             ((MainActivity)Context).Debug("[SWAP]");
  275.         }
  276.  
  277.         public void Shift()
  278.         {
  279.             shifted = shifted ? false : true;
  280.             superShifted = false;
  281.             PostInvalidate();
  282.             ((MainActivity)Context).Debug("[SHIFT]");
  283.         }
  284.  
  285.         public void SuperShift()
  286.         {
  287.             superShifted = superShifted ? false : true;
  288.             shifted = superShifted;
  289.             hasSuperShifted = true;
  290.             PostInvalidate();
  291.             ((MainActivity)Context).Debug("[SUPER SHIFT]");
  292.         }
  293.  
  294.         public void Backspace()
  295.         {
  296.             MainActivity activity = (MainActivity)Context;
  297.  
  298.             activity.RunOnUiThread(() =>
  299.             {
  300.                 activity.wvEditor.LoadUrl("javascript:(function() { Mathway.UI.Editor.keypress('backspace', '', -1); })()");
  301.  
  302.                 // haptic feedback
  303.                 PerformHapticFeedback(FeedbackConstants.KeyboardTap);
  304.             });
  305.         }
  306.  
  307.         // a non-special key was pressed and should be sent to the app
  308.         public void InsertKey(KeyState ks)
  309.         {
  310.             MainActivity activity = (MainActivity)Context;
  311.  
  312.             activity.RunOnUiThread(() =>
  313.             {
  314.                 string jsCall = shifted ? "keydown" : "keypress";
  315.                 activity.wvEditor.LoadUrl("javascript:(function() { Mathway.UI.Editor." + jsCall + "('" + ks.Id + "', '" + ks.Character + "', '" + ks.Ascii + "');})()");
  316.             });
  317.         }
  318.     }
  319. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement