gtkcolorchooserpanel.java
来自「JAVA 所有包」· Java 代码 · 共 1,284 行 · 第 1/3 页
JAVA
1,284 行
/** * Adjusts the saturation and brightness. <code>x</code> and * <code>y</code> give the location to adjust to and are relative * to the origin of the wheel/triangle. * * @param x X coordinate on the triangle to adjust to * @param y Y coordinate on the triangle to adjust to * @param checkLoc if true the location is checked to make sure * it is contained in the triangle, if false the location is * constrained to fit in the triangle. * @return true if the location is valid */ boolean adjustSB(int x, int y, boolean checkLoc) { int innerR = getWheelRadius() - getWheelWidth(); boolean resetXY = false; // Invert the axis. y = -y; if (checkLoc && (x < -innerR || x > innerR || y < -innerR || y > innerR)) { return false; } // Rotate to origin and and verify x is valid. int triangleSize = (int)innerR * 3 / 2; double x1 = Math.cos(angle) * x - Math.sin(angle) * y; double y1 = Math.sin(angle) * x + Math.cos(angle) * y; if (x1 < -(innerR / 2)) { if (checkLoc) { return false; } x1 = -innerR / 2; resetXY = true; } else if ((int)x1 > innerR) { if (checkLoc) { return false; } x1 = innerR; resetXY = true; } // Verify y location is valid. int maxY = (int)((triangleSize - x1 - innerR / 2.0) * Math.tan(Math.toRadians(30.0))); if (y1 <= -maxY) { if (checkLoc) { return false; } y1 = -maxY; resetXY = true; } else if (y1 > maxY) { if (checkLoc) { return false; } y1 = maxY; resetXY = true; } // Rotate again to determine value and scale double x2 = Math.cos(Math.toRadians(-30.0)) * x1 - Math.sin(Math.toRadians(-30.0)) * y1; double y2 = Math.sin(Math.toRadians(-30.0)) * x1 + Math.cos(Math.toRadians(-30.0)) * y1; float value = Math.min(1.0f, (float)((innerR - y2) / (double)triangleSize)); float maxX = (float)(Math.tan(Math.toRadians(30)) * (innerR - y2)); float saturation = Math.min(1.0f, (float)(x2 / maxX / 2 + .5)); setFlag(FLAGS_SETTING_COLOR, true); if (resetXY) { setSaturationAndBrightness(saturation, value); } else { setSaturationAndBrightness(saturation, value, x + getWheelXOrigin(),getWheelYOrigin() - y); } GTKColorChooserPanel.this.setSaturationAndBrightness(saturation, value, true); setFlag(FLAGS_SETTING_COLOR, false); return true; } /** * Sets the saturation and brightness. */ private void setSaturationAndBrightness(float s, float b) { int innerR = getTriangleCircumscribedRadius(); int triangleSize = (int)innerR * 3 / 2; double x = b * triangleSize; double maxY = x * Math.tan(Math.toRadians(30.0)); double y = 2 * maxY * s - maxY; x = x - innerR; double x1 = Math.cos(Math.toRadians(-60.0) - angle) * x - Math.sin(Math.toRadians(-60.0) - angle) * y; double y1 = Math.sin(Math.toRadians(-60.0) - angle) * x + Math.cos(Math.toRadians(-60.0) - angle) * y; int newCircleX = (int)x1 + getWheelXOrigin(); int newCircleY = getWheelYOrigin() - (int)y1; setSaturationAndBrightness(s, b, newCircleX, newCircleY); } /** * Sets the saturation and brightness. */ private void setSaturationAndBrightness(float s, float b, int newCircleX, int newCircleY) { newCircleX -= getIndicatorSize() / 2; newCircleY -= getIndicatorSize() / 2; int minX = Math.min(newCircleX, circleX); int minY = Math.min(newCircleY, circleY); repaint(minX, minY, Math.max(circleX, newCircleX) - minX + getIndicatorSize() + 1, Math.max(circleY, newCircleY) - minY + getIndicatorSize() + 1); circleX = newCircleX; circleY = newCircleY; } /** * Adjusts the hue based on the passed in location. * * @param x X location to adjust to, relative to the origin of the * wheel * @param y Y location to adjust to, relative to the origin of the * wheel * @param check if true the location is checked to make sure * it is contained in the wheel, if false the location is * constrained to fit in the wheel * @return true if the location is valid. */ private boolean adjustHue(int x, int y, boolean check) { double rad = Math.sqrt(x * x + y * y); int size = getWheelRadius(); if (!check || (rad >= size - getWheelWidth() && rad < size)) { // Map the location to an angle and reset hue double angle; if (x == 0) { if (y > 0) { angle = Math.PI / 2.0; } else { angle = Math.PI + Math.PI / 2.0; } } else { angle = Math.atan((double)y / (double)x); if (x < 0) { angle += Math.PI; } else if (angle < 0) { angle += 2 * Math.PI; } } setFlag(FLAGS_SETTING_COLOR, true); setHue((float)(1.0 - angle / Math.PI / 2), true); setFlag(FLAGS_SETTING_COLOR, false); setHueAngle(angle); setSaturationAndBrightness(getSaturation(), getBrightness()); return true; } return false; } /** * Rotates the triangle to accomodate the passed in hue. */ private void setAngleFromHue(float hue) { setHueAngle((1.0 - hue) * Math.PI * 2); } /** * Sets the angle representing the hue. */ private void setHueAngle(double angle) { double oldAngle = this.angle; this.angle = angle; if (angle != oldAngle) { setFlag(FLAGS_CHANGED_ANGLE, true); repaint(); } } /** * Returns the size of the color indicator. */ private int getIndicatorSize() { return 8; } /** * Returns the circumscribed radius of the triangle. */ private int getTriangleCircumscribedRadius() { return 72; } /** * Returns the x origin of the wheel and triangle. */ private int getWheelXOrigin() { return 85; } /** * Returns y origin of the wheel and triangle. */ private int getWheelYOrigin() { return 85; } /** * Returns the width of the wheel. */ private int getWheelWidth() { return 13; } /** * Sets the focus to one of: 0 no one, 1 the wheel or 2 the triangle. */ private void setFocusType(int type) { if (type == 0) { setFlag(FLAGS_FOCUSED_WHEEL, false); setFlag(FLAGS_FOCUSED_TRIANGLE, false); repaint(); } else { int toSet = FLAGS_FOCUSED_WHEEL; int toUnset = FLAGS_FOCUSED_TRIANGLE; if (type == 2) { toSet = FLAGS_FOCUSED_TRIANGLE; toUnset = FLAGS_FOCUSED_WHEEL; } if (!isSet(toSet)) { setFlag(toSet, true); repaint(); setFlag(toUnset, false); } } } /** * Returns the radius of the wheel. */ private int getWheelRadius() { // As far as I can tell, GTK doesn't allow stretching this // widget return 85; } /** * Updates the flags bitmask. */ private void setFlag(int flag, boolean value) { if (value) { flags |= flag; } else { flags &= ~flag; } } /** * Returns true if a particular flag has been set. */ private boolean isSet(int flag) { return ((flags & flag) == flag); } /** * Returns the RGB color to use for the specified location. The * passed in point must be on the color wheel and be relative to the * origin of the color wheel. * * @param x X location to get color for * @param y Y location to get color for * @param rad Radius from center of color wheel * @param integer with red, green and blue components */ private int colorWheelLocationToRGB(int x, int y, double rad) { double angle = Math.acos((double)x / rad); int rgb; if (angle < PI_3) { if (y < 0) { // FFFF00 - FF0000 rgb = 0xFF0000 | (int)Math.min(255, (int)(255 * angle / PI_3)) << 8; } else { // FF0000 - FF00FF rgb = 0xFF0000 | (int)Math.min(255, (int)(255 * angle / PI_3)); } } else if (angle < 2 * PI_3) { angle -= PI_3; if (y < 0) { // 00FF00 - FFFF00 rgb = 0x00FF00 | (int)Math.max(0, 255 - (int)(255 * angle / PI_3)) << 16; } else { // FF00FF - 0000FF rgb = 0x0000FF | (int)Math.max(0, 255 - (int)(255 * angle / PI_3)) << 16; } } else { angle -= 2 * PI_3; if (y < 0) { // 00FFFF - 00FF00 rgb = 0x00FF00 | (int)Math.min(255, (int)(255 * angle / PI_3)); } else { // 0000FF - 00FFFF rgb = 0x0000FF | (int)Math.min(255, (int)(255 * angle / PI_3)) << 8; } } return rgb; } /** * Increments the hue. */ void incrementHue(boolean positive) { float hue = triangle.getGTKColorChooserPanel().getHue(); if (positive) { hue += 1.0f / 360.0f; } else { hue -= 1.0f / 360.0f; } if (hue > 1) { hue -= 1; } else if (hue < 0) { hue += 1; } getGTKColorChooserPanel().setHue(hue, true); } } /** * Action class used for colors. */ private static class ColorAction extends AbstractAction { private int type; ColorAction(String name, int type) { super(name); this.type = type; } public void actionPerformed(ActionEvent e) { ColorTriangle triangle = (ColorTriangle)e.getSource(); if (triangle.isWheelFocused()) { float hue = triangle.getGTKColorChooserPanel().getHue(); switch (type) { case 0: case 2: triangle.incrementHue(true); break; case 1: case 3: triangle.incrementHue(false); break; case 4: triangle.focusTriangle(); break; case 5: compositeRequestFocus(triangle, false); break; } } else { int xDelta = 0; int yDelta = 0; switch (type) { case 0: // up yDelta--; break; case 1: // down yDelta++; break; case 2: // left xDelta--; break; case 3: // right xDelta++; break; case 4: compositeRequestFocus(triangle, true); return; case 5: triangle.focusWheel(); return; } triangle.adjustSB(triangle.getColorX() + xDelta, triangle.getColorY() + yDelta, true); } } } private class OpaqueLabel extends JLabel { public boolean isOpaque() { return true; } }}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?