protected override void OnKeyDown()

in src/Avalonia.Controls.ColorPicker/ColorSpectrum/ColorSpectrum.cs [222:348]


        protected override void OnKeyDown(KeyEventArgs e)
        {
            var key = e.Key;

            if (key != Key.Left &&
                key != Key.Right &&
                key != Key.Up &&
                key != Key.Down)
            {
                base.OnKeyDown(e);
                return;
            }

            bool isControlDown = e.KeyModifiers.HasFlag(KeyModifiers.Control);

            HsvComponent incrementComponent = HsvComponent.Hue;

            bool isSaturationValue = false;

            if (key == Key.Left ||
                key == Key.Right)
            {
                switch (Components)
                {
                    case ColorSpectrumComponents.HueSaturation:
                    case ColorSpectrumComponents.HueValue:
                        incrementComponent = HsvComponent.Hue;
                        break;

                    case ColorSpectrumComponents.SaturationValue:
                        isSaturationValue = true;
                        goto case ColorSpectrumComponents.SaturationHue;
                    case ColorSpectrumComponents.SaturationHue:
                        incrementComponent = HsvComponent.Saturation;
                        break;

                    case ColorSpectrumComponents.ValueHue:
                    case ColorSpectrumComponents.ValueSaturation:
                        incrementComponent = HsvComponent.Value;
                        break;
                }
            }
            else if (key == Key.Up ||
                     key == Key.Down)
            {
                switch (Components)
                {
                    case ColorSpectrumComponents.SaturationHue:
                    case ColorSpectrumComponents.ValueHue:
                        incrementComponent = HsvComponent.Hue;
                        break;

                    case ColorSpectrumComponents.HueSaturation:
                    case ColorSpectrumComponents.ValueSaturation:
                        incrementComponent = HsvComponent.Saturation;
                        break;

                    case ColorSpectrumComponents.SaturationValue:
                        isSaturationValue = true;
                        goto case ColorSpectrumComponents.HueValue;
                    case ColorSpectrumComponents.HueValue:
                        incrementComponent = HsvComponent.Value;
                        break;
                }
            }

            double minBound = 0.0;
            double maxBound = 0.0;

            switch (incrementComponent)
            {
                case HsvComponent.Hue:
                    minBound = MinHue;
                    maxBound = MaxHue;
                    break;

                case HsvComponent.Saturation:
                    minBound = MinSaturation;
                    maxBound = MaxSaturation;
                    break;

                case HsvComponent.Value:
                    minBound = MinValue;
                    maxBound = MaxValue;
                    break;
            }

            // The order of saturation and value in the spectrum is reversed - the max value is at the bottom while the min value is at the top -
            // so we want left and up to be lower for hue, but higher for saturation and value.
            // This will ensure that the icon always moves in the direction of the key press.
            IncrementDirection direction =
                (incrementComponent == HsvComponent.Hue && (key == Key.Left || key == Key.Up)) ||
                (incrementComponent != HsvComponent.Hue && (key == Key.Right || key == Key.Down)) ?
                IncrementDirection.Lower :
                IncrementDirection.Higher;

            // Image is flipped in RightToLeft, so we need to invert direction in that case.
            // The combination saturation and value is also flipped, so we need to invert in that case too.
            // If both are false, we don't need to invert.
            // If both are true, we would invert twice, so not invert at all.
            if ((FlowDirection == FlowDirection.RightToLeft) != isSaturationValue &&
                (key == Key.Left || key == Key.Right))
            {
                if (direction == IncrementDirection.Higher)
                {
                    direction = IncrementDirection.Lower;
                }
                else
                {
                    direction = IncrementDirection.Higher;
                }
            }

            IncrementAmount amount = isControlDown ? IncrementAmount.Large : IncrementAmount.Small;

            HsvColor hsvColor = HsvColor;
            UpdateColor(ColorPickerHelpers.IncrementColorComponent(
                new Hsv(hsvColor),
                incrementComponent,
                direction,
                amount,
                shouldWrap: true,
                minBound,
                maxBound));

            e.Handled = true;
        }