in dev/ColorPicker/ColorSpectrum.cpp [98:214]
void ColorSpectrum::OnKeyDown(winrt::KeyRoutedEventArgs const& args)
{
if (args.Key() != winrt::VirtualKey::Left &&
args.Key() != winrt::VirtualKey::Right &&
args.Key() != winrt::VirtualKey::Up &&
args.Key() != winrt::VirtualKey::Down)
{
__super::OnKeyDown(args);
return;
}
bool isControlDown = (winrt::Window::Current().CoreWindow().GetKeyState(winrt::VirtualKey::Control) & winrt::CoreVirtualKeyStates::Down) == winrt::CoreVirtualKeyStates::Down;
winrt::ColorPickerHsvChannel incrementChannel = winrt::ColorPickerHsvChannel::Hue;
bool isSaturationValue = false;
if (args.Key() == winrt::VirtualKey::Left ||
args.Key() == winrt::VirtualKey::Right)
{
switch (Components())
{
case winrt::ColorSpectrumComponents::HueSaturation:
case winrt::ColorSpectrumComponents::HueValue:
incrementChannel = winrt::ColorPickerHsvChannel::Hue;
break;
case winrt::ColorSpectrumComponents::SaturationValue:
isSaturationValue = true;
[[fallthrough]]; // fallthrough is explicitly wanted
case winrt::ColorSpectrumComponents::SaturationHue:
incrementChannel = winrt::ColorPickerHsvChannel::Saturation;
break;
case winrt::ColorSpectrumComponents::ValueHue:
case winrt::ColorSpectrumComponents::ValueSaturation:
incrementChannel = winrt::ColorPickerHsvChannel::Value;
break;
}
}
else if (args.Key() == winrt::VirtualKey::Up ||
args.Key() == winrt::VirtualKey::Down)
{
switch (Components())
{
case winrt::ColorSpectrumComponents::SaturationHue:
case winrt::ColorSpectrumComponents::ValueHue:
incrementChannel = winrt::ColorPickerHsvChannel::Hue;
break;
case winrt::ColorSpectrumComponents::HueSaturation:
case winrt::ColorSpectrumComponents::ValueSaturation:
incrementChannel = winrt::ColorPickerHsvChannel::Saturation;
break;
case winrt::ColorSpectrumComponents::SaturationValue:
isSaturationValue = true;
[[fallthrough]]; // fallthrough is explicitly wanted
case winrt::ColorSpectrumComponents::HueValue:
incrementChannel = winrt::ColorPickerHsvChannel::Value;
break;
}
}
double minBound = 0;
double maxBound = 0;
switch (incrementChannel)
{
case winrt::ColorPickerHsvChannel::Hue:
minBound = MinHue();
maxBound = MaxHue();
break;
case winrt::ColorPickerHsvChannel::Saturation:
minBound = MinSaturation();
maxBound = MaxSaturation();
break;
case winrt::ColorPickerHsvChannel::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 =
(incrementChannel == winrt::ColorPickerHsvChannel::Hue && (args.Key() == winrt::VirtualKey::Left || args.Key() == winrt::VirtualKey::Up)) ||
(incrementChannel != winrt::ColorPickerHsvChannel::Hue && (args.Key() == winrt::VirtualKey::Right || args.Key() == winrt::VirtualKey::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() == winrt::FlowDirection::RightToLeft) != isSaturationValue &&
(args.Key() == winrt::VirtualKey::Left || args.Key() == winrt::VirtualKey::Right))
{
if (direction == IncrementDirection::Higher)
{
direction = IncrementDirection::Lower;
}
else
{
direction = IncrementDirection::Higher;
}
}
const IncrementAmount amount = isControlDown ? IncrementAmount::Large : IncrementAmount::Small;
const winrt::float4 hsvColor = HsvColor();
UpdateColor(IncrementColorChannel(Hsv(hsv::GetHue(hsvColor), hsv::GetSaturation(hsvColor), hsv::GetValue(hsvColor)), incrementChannel, direction, amount, true /* shouldWrap */, minBound, maxBound));
args.Handled(true);
}