void UpdateControlsBasedOnSelection()
        {
            updatingInternally = true;
            try
            {
                XkeySelection selection = xkeyLayout.GetSelection();
                bool          isTall    = selection.GetGroupType() == KeyGroupType.Tall;
                bool          isWide    = selection.GetGroupType() == KeyGroupType.Wide;
                bool          isSquare  = selection.GetGroupType() == KeyGroupType.Square;

                chkTall.Checked                 = isTall;
                chkWide.Checked                 = isWide;
                chkSquareButton.Checked         = isSquare;
                chkKeyRepeatsifHeldDown.Checked = selection.AllKeysRepeatIfHeldDown();
                chkBlocker.Enabled              = selection.HasOnlySingleKeys();
                txtKeyName.Enabled              = selection.Count > 0;
                if (chkBlocker.Enabled)
                {
                    chkBlocker.Checked = selection.IsBlocked();
                }
                chkTall.Enabled = isTall || selection.CanBeTall();
                chkWide.Enabled = isWide || selection.CanBeWide();
                chkKeyRepeatsifHeldDown.Enabled = selection.Count > 0;
                chkSquareButton.Enabled         = isSquare || selection.CanBeSquare();
                txtKeyName.Text = selection.GetName();
            }
            finally
            {
                updatingInternally = false;
            }
        }
        public void GroupSelection(KeyGroupType keysGroupType)
        {
            XkeySelection selection = GetSelection();

            RemoveSelectedKeys();
            KeyGroup keyGroup = new KeyGroup()
            {
                Type = keysGroupType, Name = selection.GetName()
            };
            int topmostRow     = -1;
            int leftmostColumn = -1;

            foreach (KeyBase selectedKey in selection.SelectedKeys)
            {
                selectedKey.ClearSelection();
                keyGroup.Keys.Add(selectedKey);
                if (topmostRow == -1 || selectedKey.Row < topmostRow)
                {
                    topmostRow = selectedKey.Row;
                }
                if (leftmostColumn == -1 || selectedKey.Column < leftmostColumn)
                {
                    leftmostColumn = selectedKey.Column;
                }
            }
            keyGroup.Selected = true;
            keyGroup.SetPosition(leftmostColumn, topmostRow);
            keys.Add(keyGroup);
            OnSelectionChanged();
        }
        public bool Select(int column, int row, bool addToSelection, bool toggleSelection)
        {
            if (IsSelected(column, row) && !toggleSelection)
            {
                XkeySelection selection = GetSelection();
                if (selection.SelectedKeys.Count == 1) // Already selected. No changes.
                {
                    return(false);
                }
            }

            if (!addToSelection && !toggleSelection)
            {
                ClearSelection();
            }

            for (int i = 0; i < Keys.Count; i++)
            {
                if (toggleSelection)
                {
                    Keys[i].ToggleSelection(column, row);
                }
                else
                {
                    Keys[i].Select(column, row);
                }
            }
            return(true);
        }
        void RemoveSelectedKeys()
        {
            XkeySelection selection = GetSelection();

            foreach (KeyBase selectedKey in selection.SelectedKeys)
            {
                keys.Remove(selectedKey);
            }
        }
        public XkeySelection GetSelection()
        {
            XkeySelection selection = new XkeySelection();

            for (int i = 0; i < Keys.Count; i++)
            {
                if (Keys[i].Selected)
                {
                    selection.AddKey(Keys[i]);
                }
            }
            return(selection);
        }
        public void UngroupSelection()
        {
            XkeySelection selection = GetSelection();

            foreach (KeyBase selectedKey in selection.SelectedKeys)
            {
                KeyGroup keyGroup = selectedKey as KeyGroup;
                if (keyGroup != null)
                {
                    keyGroup.Ungroup(this);
                }
            }
            OnSelectionChanged();
        }
        private void chkBlocker_CheckedChanged(object sender, EventArgs e)
        {
            if (updatingInternally)
            {
                return;
            }
            XkeySelection selection = xkeyLayout.GetSelection();

            if (selection.GetGroupType() != KeyGroupType.NoGroup)
            {
                return;
            }

            bool allAreBlocked = true;

            foreach (KeyBase selectedKey in selection.SelectedKeys)
            {
                Key xkey = selectedKey as Key;
                if (xkey != null)
                {
                    if (!xkey.IsBlocked)
                    {
                        allAreBlocked = false;
                    }
                }
            }

            bool newBlockSetting;

            if (allAreBlocked)
            {
                newBlockSetting = false;
            }
            else
            {
                newBlockSetting = true;
            }
            foreach (KeyBase selectedKey in selection.SelectedKeys)
            {
                Key xkey = selectedKey as Key;
                if (xkey != null)
                {
                    xkey.IsBlocked = newBlockSetting;
                }
            }
            xkeyLayout.BlockSettingsChanged();
            RefreshKeyLayout();
            txtKeyName.Focus();
        }
        private void chkWide_CheckedChanged(object sender, EventArgs e)
        {
            if (updatingInternally)
            {
                return;
            }
            XkeySelection selection = xkeyLayout.GetSelection();

            if (selection.GetGroupType() == KeyGroupType.Wide)
            {
                xkeyLayout.UngroupSelection();
            }
            else if (selection.Count == 2)
            {
                xkeyLayout.GroupSelection(KeyGroupType.Wide);
            }
            txtKeyName.Focus();
        }