private void CalcCoordsAndUpdate(ColorHandler.Hsv hsv) { // Convert color to real-world coordinates and then calculate // the various points. HSV.Hue represents the degrees (0 to 360), // HSV.Saturation represents the radius. // This procedure doesn't draw anything--it simply // updates class-level variables. The UpdateDisplay // procedure uses these values to update the screen. // Given the angle (HSV.Hue), and distance from // the center (HSV.Saturation), and the center, // calculate the point corresponding to // the selected color, on the color wheel. _colorPoint = GetPoint((double)hsv.Hue / 255 * 360, (double)hsv.Saturation / 255 * _radius, _centerPoint); // Given the brightness (HSV.value), calculate the // point corresponding to the brightness indicator. _brightnessPoint = CalcBrightnessPoint(hsv.Value); // Store information about the selected color. _brightness = hsv.Value; _selectedColor = ColorHandler.HsvToColor(hsv); _argb = ColorHandler.HsvToRgb(hsv); // The full color is the same as HSV, except that the // brightness is set to full (255). This is the top-most // color in the brightness gradient. _fullColor = ColorHandler.HsvToColor(hsv.Alpha, hsv.Hue, hsv.Saturation, 255); }
public void Draw(Graphics g, Point mousePoint) { try { // You've moved the mouse. // Now update the screen to match. // Keep track of the previous color pointer point, // so you can put the mouse there in case the // user has clicked outside the circle. Point newColorPoint = _colorPoint; Point newBrightnessPoint = _brightnessPoint; // Store this away for later use. _g = g; if (_currentState == MouseState.MouseUp) { if (!mousePoint.IsEmpty) { if (_colorRegion.IsVisible(mousePoint)) { // Is the mouse point within the color circle? // If so, you just clicked on the color wheel. _currentState = MouseState.ClickOnColor; } else if (_brightnessRegion.IsVisible(mousePoint)) { // Is the mouse point within the brightness area? // You clicked on the brightness area. _currentState = MouseState.ClickOnBrightness; } else { // Clicked outside the color and the brightness // regions. In that case, just put the // pointers back where they were. _currentState = MouseState.ClickOutsideRegion; } } } switch (_currentState) { case MouseState.ClickOnBrightness: case MouseState.DragInBrightness: // Calculate new color information // based on the brightness, which may have changed. Point newPoint = mousePoint; if (newPoint.Y < _brightnessMin) { newPoint.Y = _brightnessMin; } else if (newPoint.Y > _brightnessMax) { newPoint.Y = _brightnessMax; } newBrightnessPoint = new Point(_brightnessX, newPoint.Y); _brightness = (int)((_brightnessMax - newPoint.Y) * _brightnessScaling); _hsv.Value = _brightness; _brightness = byte.MaxValue; _argb = ColorHandler.HsvToRgb(_hsv); _brightness = (_argb.Red + _argb.Green + _argb.Blue) / 3; break; case MouseState.ClickOnColor: case MouseState.DragInColor: // Calculate new color information // based on selected color, which may have changed. newColorPoint = mousePoint; // Calculate x and y distance from the center, // and then calculate the angle corresponding to the // new location. Point delta = new Point(mousePoint.X - _centerPoint.X, mousePoint.Y - _centerPoint.Y); int degrees = CalcDegrees(delta); // Calculate distance from the center to the new point // as a fraction of the radius. Use your old friend, // the Pythagorean theorem, to calculate this value. double distance = Math.Sqrt(delta.X * delta.X + delta.Y * delta.Y) / _radius; if (_currentState == MouseState.DragInColor) { if (distance > 1) { // Mouse is down, and outside the circle, but you // were previously dragging in the color circle. // What to do? // In that case, move the point to the edge of the // circle at the correct angle. distance = 1; newColorPoint = GetPoint(degrees, _radius, _centerPoint); } } // Calculate the new HSV and RGB values. _hsv.Hue = (degrees * 255 / 360); _hsv.Saturation = (int)(distance * 255); _brightness = byte.MaxValue; _hsv.Value = _brightness; _argb = ColorHandler.HsvToRgb(_hsv); if (_argb.Red < 0 || _argb.Red > byte.MaxValue || _argb.Green < 0 || _argb.Green > byte.MaxValue || _argb.Blue < 0 || _argb.Blue > byte.MaxValue) { UpdateDisplay(); return; } _brightness = (_argb.Red + _argb.Green + _argb.Blue) / 3; _fullColor = ColorHandler.HsvToColor(_hsv.Alpha, _hsv.Hue, _hsv.Saturation, 255); break; } _selectedColor = ColorHandler.HsvToColor(_hsv); // Raise an event back to the parent form, // so the form can update any UI it's using // to display selected color values. OnColorChanged(_argb, _hsv); // On the way out, set the new state. switch (_currentState) { case MouseState.ClickOnBrightness: _currentState = MouseState.DragInBrightness; break; case MouseState.ClickOnColor: _currentState = MouseState.DragInColor; break; case MouseState.ClickOutsideRegion: _currentState = MouseState.DragOutsideRegion; break; } // Store away the current points for next time. _colorPoint = newColorPoint; _brightnessPoint = newBrightnessPoint; // Draw the gradients and points. UpdateDisplay(); } catch (Exception e) { System.Windows.Forms.MessageBox.Show(e.Message); } }