001: /*
002: * SmoothGradientUtils.java
003: *
004: * Copyright (C) 2002, 2003, 2004, 2005, 2006 Takis Diakoumis
005: *
006: * This program is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU General Public License
008: * as published by the Free Software Foundation; either version 2
009: * of the License, or any later version.
010: *
011: * This program is distributed in the hope that it will be useful,
012: * but WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
014: * GNU General Public License for more details.
015: *
016: * You should have received a copy of the GNU General Public License
017: * along with this program; if not, write to the Free Software
018: * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
019: *
020: */
021:
022: package org.underworldlabs.swing.plaf.smoothgradient;
023:
024: import java.awt.Color;
025: import java.awt.Component;
026: import java.awt.GradientPaint;
027: import java.awt.Graphics;
028: import java.awt.Graphics2D;
029: import java.awt.Rectangle;
030:
031: import javax.swing.JComponent;
032: import javax.swing.UIManager;
033: import javax.swing.plaf.metal.MetalLookAndFeel;
034:
035: /* ----------------------------------------------------------
036: * CVS NOTE: Changes to the CVS repository prior to the
037: * release of version 3.0.0beta1 has meant a
038: * resetting of CVS revision numbers.
039: * ----------------------------------------------------------
040: */
041:
042: /**
043: *
044: * @author Takis Diakoumis
045: * @version $Revision: 1.4 $
046: * @date $Date: 2006/05/14 06:56:07 $
047: */
048: public final class SmoothGradientUtils {
049:
050: static void drawDark3DBorder(Graphics g, int x, int y, int w, int h) {
051: drawFlush3DBorder(g, x, y, w, h);
052: g.setColor(SmoothGradientLookAndFeel.getControl());
053: g.drawLine(x + 1, y + 1, 1, h - 3);
054: g.drawLine(y + 1, y + 1, w - 3, 1);
055: }
056:
057: static void drawDisabledBorder(Graphics g, int x, int y, int w,
058: int h) {
059: g.setColor(MetalLookAndFeel.getControlShadow());
060: drawRect(g, x, y, w - 1, h - 1);
061: }
062:
063: /**
064: * Unlike <code>MetalUtils</code> we first draw with highlight then dark shadow
065: */
066: static void drawFlush3DBorder(Graphics g, int x, int y, int w, int h) {
067: g.translate(x, y);
068: g.setColor(SmoothGradientLookAndFeel.getControlHighlight());
069: drawRect(g, 1, 1, w - 2, h - 2);
070: g.drawLine(0, h - 1, 0, h - 1);
071: g.drawLine(w - 1, 0, w - 1, 0);
072: g.setColor(SmoothGradientLookAndFeel.getControlDarkShadow());
073: drawRect(g, 0, 0, w - 2, h - 2);
074: g.translate(-x, -y);
075: }
076:
077: /**
078: * Copied from <code>MetalUtils</code>.
079: */
080: static void drawPressed3DBorder(Graphics g, int x, int y, int w,
081: int h) {
082: g.translate(x, y);
083: drawFlush3DBorder(g, 0, 0, w, h);
084: g.setColor(MetalLookAndFeel.getControlShadow());
085: g.drawLine(1, 1, 1, h - 3);
086: g.drawLine(1, 1, w - 3, 1);
087: g.translate(-x, -y);
088: }
089:
090: /**
091: * Copied from <code>MetalUtils</code>.
092: */
093: static void drawButtonBorder(Graphics g, int x, int y, int w,
094: int h, boolean active) {
095: if (active) {
096: drawActiveButtonBorder(g, x, y, w, h);
097: } else {
098: drawFlush3DBorder(g, x, y, w, h);
099: }
100: }
101:
102: /**
103: * Copied from <code>MetalUtils</code>.
104: */
105: static void drawActiveButtonBorder(Graphics g, int x, int y, int w,
106: int h) {
107: drawFlush3DBorder(g, x, y, w, h);
108: g.setColor(SmoothGradientLookAndFeel.getPrimaryControl());
109: g.drawLine(x + 1, y + 1, x + 1, h - 3);
110: g.drawLine(x + 1, y + 1, w - 3, x + 1);
111: g.setColor(SmoothGradientLookAndFeel
112: .getPrimaryControlDarkShadow());
113: g.drawLine(x + 2, h - 2, w - 2, h - 2);
114: g.drawLine(w - 2, y + 2, w - 2, h - 2);
115: }
116:
117: /**
118: * Modified edges.
119: */
120: static void drawDefaultButtonBorder(Graphics g, int x, int y,
121: int w, int h, boolean active) {
122: drawButtonBorder(g, x + 1, y + 1, w - 1, h - 1, active);
123: g.translate(x, y);
124: g.setColor(SmoothGradientLookAndFeel.getControlDarkShadow());
125: drawRect(g, 0, 0, w - 3, h - 3);
126: g.drawLine(w - 2, 0, w - 2, 0);
127: g.drawLine(0, h - 2, 0, h - 2);
128: g.setColor(SmoothGradientLookAndFeel.getControl());
129: g.drawLine(w - 1, 0, w - 1, 0);
130: g.drawLine(0, h - 1, 0, h - 1);
131: g.translate(-x, -y);
132: }
133:
134: static void drawDefaultButtonPressedBorder(Graphics g, int x,
135: int y, int w, int h) {
136: drawPressed3DBorder(g, x + 1, y + 1, w - 1, h - 1);
137: g.translate(x, y);
138: g.setColor(SmoothGradientLookAndFeel.getControlDarkShadow());
139: drawRect(g, 0, 0, w - 3, h - 3);
140: g.drawLine(w - 2, 0, w - 2, 0);
141: g.drawLine(0, h - 2, 0, h - 2);
142: g.setColor(SmoothGradientLookAndFeel.getControl());
143: g.drawLine(w - 1, 0, w - 1, 0);
144: g.drawLine(0, h - 1, 0, h - 1);
145: g.translate(-x, -y);
146: }
147:
148: static void drawThinFlush3DBorder(Graphics g, int x, int y, int w,
149: int h) {
150: g.translate(x, y);
151: g.setColor(SmoothGradientLookAndFeel.getControlHighlight());
152: g.drawLine(0, 0, w - 2, 0);
153: g.drawLine(0, 0, 0, h - 2);
154: g.setColor(SmoothGradientLookAndFeel.getControlDarkShadow());
155: g.drawLine(w - 1, 0, w - 1, h - 1);
156: g.drawLine(0, h - 1, w - 1, h - 1);
157: g.translate(-x, -y);
158: }
159:
160: static void drawThinPressed3DBorder(Graphics g, int x, int y,
161: int w, int h) {
162: g.translate(x, y);
163: g.setColor(SmoothGradientLookAndFeel.getControlDarkShadow());
164: g.drawLine(0, 0, w - 2, 0);
165: g.drawLine(0, 0, 0, h - 2);
166: g.setColor(SmoothGradientLookAndFeel.getControlHighlight());
167: g.drawLine(w - 1, 0, w - 1, h - 1);
168: g.drawLine(0, h - 1, w - 1, h - 1);
169: g.translate(-x, -y);
170: }
171:
172: /*
173: * Convenience function for determining ComponentOrientation. Helps us
174: * avoid having Munge directives throughout the code.
175: */
176: public static boolean isLeftToRight(Component c) {
177: return c.getComponentOrientation().isLeftToRight();
178: }
179:
180: // 3D Effects ***********************************************************************
181:
182: /**
183: * Checks and answers if the specified component type has 3D effects.
184: */
185: static boolean is3D(String key) {
186: return true;
187: // Object value = UIManager.get(key + "is3DEnabled");
188: // return Boolean.TRUE.equals(value);
189: }
190:
191: /**
192: * Checks and answers if we have a custom hint that forces the 3D mode.
193: *
194: * @see #forceFlat
195: */
196: static boolean force3D(JComponent c) {
197: Object value = c
198: .getClientProperty(SmoothGradientLookAndFeel.IS_3D_KEY);
199: return Boolean.TRUE.equals(value);
200: }
201:
202: public static int getInt(Object key, int defaultValue) {
203: Object value = UIManager.get(key);
204:
205: if (value instanceof Integer) {
206: return ((Integer) value).intValue();
207: }
208: if (value instanceof String) {
209: try {
210: return Integer.parseInt((String) value);
211: } catch (NumberFormatException nfe) {
212: }
213: }
214: return defaultValue;
215: }
216:
217: /**
218: * Checks and answers if we have a custom hint that forces the 3D mode.
219: *
220: * @see #forceFlat
221: */
222: static boolean forceFlat(JComponent c) {
223: Object value = c
224: .getClientProperty(SmoothGradientLookAndFeel.IS_3D_KEY);
225: return Boolean.FALSE.equals(value);
226: }
227:
228: // Painting 3D Effects *************************************************************
229:
230: private static float FRACTION_3D = 0.5f;
231:
232: private static void add3DEffekt(Graphics g, Rectangle r,
233: boolean isHorizontal, Color startC0, Color stopC0,
234: Color startC1, Color stopC1) {
235:
236: Graphics2D g2 = (Graphics2D) g;
237: int xb0, yb0, xb1, yb1, xd0, yd0, xd1, yd1, width, height;
238: if (isHorizontal) {
239: width = r.width;
240: height = (int) (r.height * FRACTION_3D);
241: xb0 = r.x;
242: yb0 = r.y;
243: xb1 = xb0;
244: yb1 = yb0 + height;
245: xd0 = xb1;
246: yd0 = yb1;
247: xd1 = xd0;
248: yd1 = r.y + r.height;
249: } else {
250: width = (int) (r.width * FRACTION_3D);
251: height = r.height;
252: xb0 = r.x;
253: yb0 = r.y;
254: xb1 = xb0 + width;
255: yb1 = yb0;
256: xd0 = xb1;
257: yd0 = yb0;
258: xd1 = r.x + r.width;
259: yd1 = yd0;
260: }
261: g2.setPaint(new GradientPaint(xb0, yb0, stopC0, xb1, yb1,
262: startC0));
263: g2.fillRect(r.x, r.y, width, height);
264: g2.setPaint(new GradientPaint(xd0, yd0, startC1, xd1, yd1,
265: stopC1));
266: g2.fillRect(xd0, yd0, width, height);
267: }
268:
269: public static void add3DEffekt(Graphics g, Rectangle r) {
270: Color brightenStop = UIManager.getColor("Plastic.brightenStop");
271: if (null == brightenStop)
272: brightenStop = SmoothGradientLookAndFeel.BRIGHTEN_STOP;
273:
274: // Add round sides
275: Graphics2D g2 = (Graphics2D) g;
276: int border = 10;
277: g2
278: .setPaint(new GradientPaint(r.x, r.y, brightenStop, r.x
279: + border, r.y,
280: SmoothGradientLookAndFeel.BRIGHTEN_START));
281: g2.fillRect(r.x, r.y, border, r.height);
282: int x = r.x + r.width - border;
283: int y = r.y;
284: g2.setPaint(new GradientPaint(x, y,
285: SmoothGradientLookAndFeel.DARKEN_START, x + border, y,
286: SmoothGradientLookAndFeel.LT_DARKEN_STOP));
287: g2.fillRect(x, y, border, r.height);
288:
289: add3DEffekt(g, r, true,
290: SmoothGradientLookAndFeel.BRIGHTEN_START, brightenStop,
291: SmoothGradientLookAndFeel.DARKEN_START,
292: SmoothGradientLookAndFeel.LT_DARKEN_STOP);
293: }
294:
295: public static void addLight3DEffekt(Graphics g, Rectangle r,
296: boolean isHorizontal) {
297: Color ltBrightenStop = UIManager
298: .getColor("Plastic.ltBrightenStop");
299: if (null == ltBrightenStop)
300: ltBrightenStop = SmoothGradientLookAndFeel.LT_BRIGHTEN_STOP;
301:
302: add3DEffekt(g, r, isHorizontal,
303: SmoothGradientLookAndFeel.BRIGHTEN_START,
304: ltBrightenStop, SmoothGradientLookAndFeel.DARKEN_START,
305: SmoothGradientLookAndFeel.LT_DARKEN_STOP);
306: }
307:
308: public static void addLight3DEffekt(Graphics g, Rectangle r) {
309: Color ltBrightenStop = UIManager
310: .getColor("Plastic.ltBrightenStop");
311: if (null == ltBrightenStop)
312: ltBrightenStop = SmoothGradientLookAndFeel.LT_BRIGHTEN_STOP;
313:
314: add3DEffekt(g, r, true, SmoothGradientLookAndFeel.DARKEN_START,
315: SmoothGradientLookAndFeel.LT_DARKEN_STOP,
316: SmoothGradientLookAndFeel.BRIGHTEN_START,
317: ltBrightenStop);
318: }
319:
320: // Low level graphics ***************************************************
321:
322: /**
323: * An optimized version of Graphics.drawRect.
324: */
325: private static void drawRect(Graphics g, int x, int y, int w, int h) {
326: g.fillRect(x, y, w + 1, 1);
327: g.fillRect(x, y + 1, 1, h);
328: g.fillRect(x + 1, y + h, w, 1);
329: g.fillRect(x + w, y + 1, 1, h);
330: }
331:
332: }
|