/// <summary>
        /// Detects the DirectInput button being presed
        /// </summary>
        private void btnDetectButton_Click(object sender, EventArgs e)
        {
            this.detectingButtonNumber = !this.detectingButtonNumber;

            // If we just hit the Detect Button...
            if (this.detectingButtonNumber)
            {
                // Change the label of the button
                this.btnDetectButton.Text = "Detecting...";

                // Wait for a button press
                HookManager.CurrentDevideGuid       = this.selectedJoystick.Information.ProductGuid;
                HookManager.DirectInputButtonInsert = (code) => {
                    // Changes current definition
                    this.currentDefinition = this.currentDefinition.Modify(buttonNumber: code);

                    if (Application.OpenForms["DirectInputButtonPropertiesForm"] != null)
                    {
                        (Application.OpenForms["DirectInputButtonPropertiesForm"] as DirectInputButtonPropertiesForm).Invoke(new DataSetMethodInvoker(ChangeButton), code + 1);
                    }

                    return(true);
                };
            }
            else
            {
                this.btnDetectButton.Text         = "Detect Button";
                HookManager.DirectInputAxisInsert = null;
            }
        }
        /// <summary>
        /// Takes the current text position input value, updates the current defifinition with it and invokes the change events.
        /// </summary>
        private void UpdateTextPosition()
        {
            var newPos = new TPoint(this.txtTextPosition.X, this.txtTextPosition.Y);

            this.currentDefinition = this.currentDefinition.Modify(textPosition: newPos);
            this.DefinitionChanged?.Invoke(this.currentDefinition);
        }
        /// <summary>
        /// Called when the user clicks "Apply" in the rectangle dialog. Sets the new boundaries and invokes the changed event.
        /// </summary>
        private void OnRectangleDimensionsSet(TRectangle rectangle)
        {
            this.lstBoundaries.Items.Clear();
            this.lstBoundaries.Items.Add(rectangle.TopLeft);
            this.lstBoundaries.Items.Add(rectangle.TopRight);
            this.lstBoundaries.Items.Add(rectangle.BottomRight);
            this.lstBoundaries.Items.Add(rectangle.BottomLeft);

            this.currentDefinition =
                this.currentDefinition.Modify(boundaries: this.lstBoundaries.Items.Cast <TPoint>().ToList());
            this.DefinitionChanged?.Invoke(this.currentDefinition);
        }
        private void cmbButtonNumber_SelectedIndexChanged(object sender, EventArgs e)
        {
            ComboBox comboBox = (ComboBox)sender;

            if (comboBox.SelectedItem != null)
            {
                int selectedButton = ((JoystickButtonComboBoxItem)comboBox.SelectedItem).ID;

                // Handles changing the button
                this.currentDefinition = this.currentDefinition.Modify(buttonNumber: selectedButton);
                this.DefinitionChanged?.Invoke(this.currentDefinition);
            }
        }
        /// <summary>
        /// Handles moving a boundary down in the list, sets the new boundaries and invokes the changed event.
        /// </summary>
        private void btnBoundaryDown_Click(object sender, EventArgs e)
        {
            var item  = this.lstBoundaries.SelectedItem;
            var index = this.lstBoundaries.SelectedIndex;

            if (item == null || index == this.lstBoundaries.Items.Count - 1)
            {
                return;
            }

            this.lstBoundaries.Items.Remove(item);
            this.lstBoundaries.Items.Insert(index + 1, item);
            this.lstBoundaries.SelectedIndex = index + 1;

            this.currentDefinition =
                this.currentDefinition.Modify(boundaries: this.lstBoundaries.Items.Cast <TPoint>().ToList());
            this.DefinitionChanged?.Invoke(this.currentDefinition);
        }
        /// <summary>
        /// Handles adding a boundary, sets the new boundaries and invokes the changed event.
        /// </summary>
        private void btnAddBoundary_Click(object sender, EventArgs e)
        {
            var newBoundary = new TPoint(this.txtBoundaries.X, this.txtBoundaries.Y);

            if (this.lstBoundaries.Items.Cast <TPoint>().Any(p => p.X == newBoundary.X && p.Y == newBoundary.Y))
            {
                return;
            }

            var newIndex = Math.Max(0, this.lstBoundaries.SelectedIndex);

            this.lstBoundaries.Items.Insert(newIndex, newBoundary);
            this.lstBoundaries.SelectedIndex = newIndex;

            this.currentDefinition =
                this.currentDefinition.Modify(boundaries: this.lstBoundaries.Items.Cast <TPoint>().ToList());
            this.DefinitionChanged?.Invoke(this.currentDefinition);
        }
        /// <summary>
        /// Handles removing a boundary, sets the new boundaries and invokes the changed event.
        /// </summary>
        private void btnRemoveBoundary_Click(object sender, EventArgs e)
        {
            if (this.lstBoundaries.SelectedItem == null)
            {
                return;
            }
            if (this.lstBoundaries.Items.Count < 4)
            {
                return;
            }

            var index = this.lstBoundaries.SelectedIndex;

            this.lstBoundaries.Items.Remove(this.lstBoundaries.SelectedItem);
            this.lstBoundaries.SelectedIndex = Math.Min(this.lstBoundaries.Items.Count - 1, index);

            this.currentDefinition =
                this.currentDefinition.Modify(boundaries: this.lstBoundaries.Items.Cast <TPoint>().ToList());
            this.DefinitionChanged?.Invoke(this.currentDefinition);
        }
        /// <summary>
        /// Selects a different joystick from the dropdown
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void comboBoxDevicesList_SelectedIndexChanged(object sender, EventArgs e)
        {
            ComboBox comboBox     = (ComboBox)sender;
            string   selectedGuid = comboBox.SelectedValue.ToString();

            this.selectedJoystick = null;
            foreach (var joystick in this.devices)
            {
                if (joystick.Information.ProductGuid.ToString() == selectedGuid)
                {
                    this.selectedJoystick = joystick;
                    break;
                }
            }

            // Handles changing the device
            this.currentDefinition = this.currentDefinition.Modify(deviceId: selectedGuid);
            this.DefinitionChanged?.Invoke(this.currentDefinition);

            // Refreshes the Buttons dropdown
            RefreshFormOnJoystickChange();
        }
        /// <summary>
        /// Handles updating a boundary, sets the new boundaries and invokes the changed event.
        /// </summary>
        private void btnUpdateBoundary_Click(object sender, EventArgs e)
        {
            if (this.lstBoundaries.SelectedItem == null)
            {
                return;
            }

            var updateIndex = this.lstBoundaries.SelectedIndex;
            var newBoundary = new TPoint(this.txtBoundaries.X, this.txtBoundaries.Y);

            if (this.lstBoundaries.Items.Cast <TPoint>().Any(p => p.X == newBoundary.X && p.Y == newBoundary.Y))
            {
                return;
            }

            this.lstBoundaries.Items.RemoveAt(updateIndex);
            this.lstBoundaries.Items.Insert(updateIndex, newBoundary);
            this.lstBoundaries.SelectedIndex = updateIndex;

            this.currentDefinition =
                this.currentDefinition.Modify(boundaries: this.lstBoundaries.Items.Cast <TPoint>().ToList());
            this.DefinitionChanged?.Invoke(this.currentDefinition);
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="DirectInputButtonPropertiesForm" /> class.
 /// </summary>
 public DirectInputButtonPropertiesForm(DirectInputButtonDefinition initialDefinition)
 {
     this.initialDefinition = initialDefinition;
     this.currentDefinition = (DirectInputButtonDefinition)initialDefinition.Clone();
     this.InitializeComponent();
 }
 /// <summary>
 /// Handles changing the change on caps state, sets the new value and invokes the changed event.
 /// </summary>
 private void chkChangeOnCaps_CheckedChanged(object sender, EventArgs e)
 {
     this.currentDefinition = this.currentDefinition.Modify(changeOnCaps: this.chkChangeOnCaps.Checked);
     this.DefinitionChanged?.Invoke(this.currentDefinition);
 }
 private void txtDeviceId_TextChanged(object sender, EventArgs e)
 {
     this.currentDefinition = this.currentDefinition.Modify(deviceId: this.txtDeviceId.Text);
     this.DefinitionChanged?.Invoke(this.currentDefinition);
 }
 /// <summary>
 /// Handles changing the shift text, sets the new shift text and invokes the changed event.
 /// </summary>
 private void txtShiftText_TextChanged(object sender, EventArgs e)
 {
     this.currentDefinition = this.currentDefinition.Modify(shiftText: this.txtShiftText.Text);
     this.DefinitionChanged?.Invoke(this.currentDefinition);
 }