/* Copyright (C) 2006 Christian Schneider * * This file is part of Nomad. * * Nomad is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Nomad is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Nomad; if not, write to the Free Software * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ /* * Created on Jan 21, 2007 */ package net.sf.nmedit.jtheme.component.plaf; import java.awt.AlphaComposite; import java.awt.Color; import java.awt.Composite; import java.awt.Graphics2D; import java.awt.RenderingHints; import javax.swing.JComponent; import javax.swing.UIDefaults; import net.sf.nmedit.jtheme.component.JTComponent; import net.sf.nmedit.jtheme.component.JTControl; import net.sf.nmedit.jtheme.component.misc.KnobMetrics; public class JTBasicKnobUI extends JTBasicControlUI { public static final Color defaultBackgroundColor = new Color(0xE3E3E3); public static final Color defaultBorderColor = new Color(0x000000); public static final Color defaultFocusedBorderColor = new Color(0x660000FF, true); public static final Color defaultGripColor = new Color(0x000000); public static final String knobBackgroundColorKey = "color.background"; public static final String knobBorderColorKey = "color.border"; public static final String knobGripColorKey = "color.grip"; public static final String knobGripStartValueKey = "grip.start"; public static final String knobGripStopValueKey = "grip.stop"; protected static final UIInstance<JTBasicKnobUI> uiInstance = new UIInstance<JTBasicKnobUI>(JTBasicKnobUI.class); public static JTBasicKnobUI createUI(JComponent c) { JTBasicKnobUI ui = uiInstance.getInstance(c); if (ui == null) uiInstance.setInstance(c, ui = new JTBasicKnobUI()); return ui; } public void installUI(JComponent c) { super.installUI(c); c.setOpaque(false); } private Color backgroundColor; private Color borderColor; private double gripStartValue; private double gripStopValue; private Color gripColor; protected void initUIDefaults(UIDefaults defaults) { // read the defaults here backgroundColor = defaults.getColor(getPrefix()+knobBackgroundColorKey); borderColor = defaults.getColor(getPrefix()+knobBorderColorKey); gripStartValue = getDouble(defaults, getPrefix()+knobGripStartValueKey, 0.25/2); gripStopValue = getDouble(defaults, getPrefix()+knobGripStopValueKey, KnobMetrics.cw(0.25/2)); gripColor = defaults.getColor(getPrefix()+knobGripColorKey); if (backgroundColor == null) backgroundColor = defaultBackgroundColor; if (borderColor == null) borderColor = defaultBorderColor; if (gripColor == null) gripColor = defaultGripColor; } public void uninstallUI(JComponent c) { super.uninstallUI(c); } protected String getPrefix() { return "knob."; } public void paintStaticLayer(Graphics2D g, JTComponent c) { g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); JTControl control = (JTControl) c; paintKnobBackground(g, control); } public void paintDynamicLayer(Graphics2D g, JTComponent c) { g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); JTControl control = (JTControl) c; paintKnobForegroundUnderlay(g, control); paintKnobForeground(g, control); } protected static int diameter(int w, int h) { // use uneven size to avoid bad looking circles int d = Math.min(w, h); return d - (d+1)%2; } protected static int diameter(JTComponent c) { return diameter(c.getWidth(), c.getHeight()); } public boolean contains(JComponent c, int x, int y) { if (super.contains(c, x, y)) // check rectangular region first { int w = c.getWidth(); int h = c.getHeight(); double r = diameter(w, h)/2d; float mx = w/2f; float my = h/2f; float dx = x-mx; float dy = y-my; return Math.sqrt(dx*dx+dy*dy)<=r; } return false; } protected void paintKnobBackground( Graphics2D g, JTControl control ) { int size = diameter(control); g.setColor(backgroundColor); g.fillOval(0, 0, size, size); g.setColor(borderColor); g.drawOval(0, 0, size-1, size-1); } protected void paintKnobForegroundUnderlay( Graphics2D g, JTControl control ) { if (control.hasFocus()) { Color focusColor = defaultFocusedBorderColor; int size = diameter(control); g.setColor(focusColor); g.drawOval(1, 1, size-3, size-3); } } protected void paintKnobForeground( Graphics2D g, JTControl control ) { double value = control.getNormalizedValue(); if (control.isExtensionAdapterSet()) { int e = control.getExtensionValue(); if (e != 0) { int relative = control.getValue()+e; if (relative<control.getMinValue()) relative = control.getMinValue(); else if (relative>control.getMaxValue()) relative = control.getMaxValue(); float d = control.getMaxValue()-control.getMinValue(); if (d>0) { float rnorm = (relative-control.getMinValue())/d; paintExtensionGrip(g, control, getExtensionColor(control.getControlAdapter().getParameter()), value, rnorm); } } } /* if (control.isExtensionAdapterSet()) { double relative = value+(control.getExtNormalizedValue()*2)-1; paintExtensionGrip(g, control, gripColor, value, relative); }*/ paintKnobGrip(g, control, gripColor, value); } private static final Composite extComposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.7f); private void paintExtensionGrip(Graphics2D g, JTControl control, Color fill, double start, double stop) { int size = diameter(control); int degStop = -(int)((stop-start)*360*.75); // scale and translate value start = KnobMetrics.cw(gripStartValue+.25+(start*(gripStopValue-gripStartValue))); int degStart = (int)(start*360); g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); Composite composite = g.getComposite(); g.setComposite(extComposite); g.setColor(fill); g.fillArc(1, 1, size-3, size-3, degStart, degStop); g.setComposite(composite); } private void paintKnobGrip(Graphics2D g, JTControl control, Color gripColor, double value) { int size = diameter(control); int len = size/2-1; int cxy = 1+len; // scale and translate value value = KnobMetrics.cw(gripStartValue+(value*(gripStopValue-gripStartValue))); int gx = (int) (Math.sin(value*KnobMetrics.PI2)*len); int gy = (int) (Math.cos(value*KnobMetrics.PI2)*len); g.setColor(gripColor); g.drawLine(cxy, cxy, cxy+gx, cxy+gy); } }