Example #1
0
        public static Hsv IncrementColorComponent(
            Hsv originalHsv,
            HsvComponent component,
            IncrementDirection direction,
            IncrementAmount amount,
            bool shouldWrap,
            double minBound,
            double maxBound)
        {
            Hsv newHsv = originalHsv;

            if (amount == IncrementAmount.Small || !ColorHelper.ToDisplayNameExists)
            {
                // In order to avoid working with small values that can incur rounding issues,
                // we'll multiple saturation and value by 100 to put them in the range of 0-100 instead of 0-1.
                newHsv.S *= 100;
                newHsv.V *= 100;

                // Note: *valueToIncrement replaced with ref local variable for C#, must be initialized
                ref double valueToIncrement = ref newHsv.H;
                double     incrementAmount  = 0.0;

                // If we're adding a small increment, then we'll just add or subtract 1.
                // If we're adding a large increment, then we want to snap to the next
                // or previous major value - for hue, this is every increment of 30;
                // for saturation and value, this is every increment of 10.
                switch (component)
                {
                case HsvComponent.Hue:
                    valueToIncrement = ref newHsv.H;
                    incrementAmount  = amount == IncrementAmount.Small ? 1 : 30;
                    break;

                case HsvComponent.Saturation:
                    valueToIncrement = ref newHsv.S;
                    incrementAmount  = amount == IncrementAmount.Small ? 1 : 10;
                    break;

                case HsvComponent.Value:
                    valueToIncrement = ref newHsv.V;
                    incrementAmount  = amount == IncrementAmount.Small ? 1 : 10;
                    break;

                default:
                    throw new InvalidOperationException("Invalid HsvComponent.");
                }

                double previousValue = valueToIncrement;

                valueToIncrement += (direction == IncrementDirection.Lower ? -incrementAmount : incrementAmount);

                // If the value has reached outside the bounds, we were previous at the boundary, and we should wrap,
                // then we'll place the selection on the other side of the spectrum.
                // Otherwise, we'll place it on the boundary that was exceeded.
                if (valueToIncrement < minBound)
                {
                    valueToIncrement = (shouldWrap && previousValue == minBound) ? maxBound : minBound;
                }

                if (valueToIncrement > maxBound)
                {
                    valueToIncrement = (shouldWrap && previousValue == maxBound) ? minBound : maxBound;
                }

                // We multiplied saturation and value by 100 previously, so now we want to put them back in the 0-1 range.
                newHsv.S /= 100;
                newHsv.V /= 100;
            }
Example #2
0
        public static Hsv IncrementColorChannel(
            Hsv originalHsv,
            ColorPickerHsvChannel channel,
            IncrementDirection direction,
            IncrementAmount amount,
            bool shouldWrap,
            double minBound,
            double maxBound)
        {
            var newHsv = originalHsv;

            if (amount == IncrementAmount.Small)
            {
                // In order to avoid working with small values that can incur rounding issues,
                // we'll multiple saturation and value by 100 to put them in the range of 0-100 instead of 0-1.
                newHsv.S *= 100;
                newHsv.V *= 100;

                ref var valueToIncrement = ref newHsv.H;
                double  incrementAmount  = 0;

                // If we're adding a small increment, then we'll just add or subtract 1.
                // If we're adding a large increment, then we want to snap to the next
                // or previous major value - for hue, this is every increment of 30;
                // for saturation and value, this is every increment of 10.
                switch (channel)
                {
                case ColorPickerHsvChannel.Hue:
                    valueToIncrement = ref newHsv.H;
                    incrementAmount  = amount == IncrementAmount.Small ? 1 : 30;
                    break;

                case ColorPickerHsvChannel.Saturation:
                    valueToIncrement = ref newHsv.S;
                    incrementAmount  = amount == IncrementAmount.Small ? 1 : 10;
                    break;

                case ColorPickerHsvChannel.Value:
                    valueToIncrement = ref newHsv.V;
                    incrementAmount  = amount == IncrementAmount.Small ? 1 : 10;
                    break;

                default:
                    throw new InvalidOperationException("Invalid ColorPickerHsvChannel.");
                }

                var previousValue = valueToIncrement;

                valueToIncrement += direction == IncrementDirection.Lower ? -incrementAmount : incrementAmount;

                // If the value has reached outside the bounds, we were previous at the boundary, and we should wrap,
                // then we'll place the selection on the other side of the spectrum.
                // Otherwise, we'll place it on the boundary that was exceeded.
                if (valueToIncrement < minBound)
                {
                    valueToIncrement = (shouldWrap && previousValue == minBound) ? maxBound : minBound;
                }

                if (valueToIncrement > maxBound)
                {
                    valueToIncrement = (shouldWrap && previousValue == maxBound) ? minBound : maxBound;
                }

                // We multiplied saturation and value by 100 previously, so now we want to put them back in the 0-1 range.
                newHsv.S /= 100;
                newHsv.V /= 100;
            }