2
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
4
* Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
6
* The contents of this file are subject to the terms of either the GNU
7
* General Public License Version 2 only ("GPL") or the Common
8
* Development and Distribution License("CDDL") (collectively, the
9
* "License"). You may not use this file except in compliance with the
10
* License. You can obtain a copy of the License at
11
* http://www.netbeans.org/cddl-gplv2.html
12
* or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
13
* specific language governing permissions and limitations under the
14
* License. When distributing the software, include this License Header
15
* Notice in each file and include the License file at
16
* nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
17
* particular file as subject to the "Classpath" exception as provided
18
* by Sun in the GPL Version 2 section of the License file that
19
* accompanied this code. If applicable, add the following below the
20
* License Header, with the fields enclosed by brackets [] replaced by
21
* your own identifying information:
22
* "Portions Copyrighted [year] [name of copyright owner]"
26
* The Original Software is NetBeans. The Initial Developer of the Original
27
* Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
28
* Microsystems, Inc. All Rights Reserved.
30
* If you wish your version of this file to be governed by only the CDDL
31
* or only the GPL Version 2, indicate your decision by adding
32
* "[Contributor] elects to include this software in this distribution
33
* under the [CDDL or GPL Version 2] license." If you do not indicate a
34
* single choice of license, a recipient has the option to distribute
35
* your version of this file under either the CDDL, the GPL Version 2 or
36
* to extend the choice of license to its licensees as provided above.
37
* However, if you add GPL Version 2 code and therefore, elected the GPL
38
* Version 2 license, then the option applies only if the new code is
39
* made subject to such option by the copyright holder.
41
package org.netbeans.swing.plaf.gtk;
44
import javax.swing.border.Border;
48
* A matte border with a few twists - can do drop shadow; also, for toolbars,
49
* will check the position of the component and return taller insets for the
50
* top row, so it's offset from the menu, but not present a doubled border
51
* for lower rows; same thing for toolbars adjacent to each other.
53
* @author Tim Boudreau
55
public class AdaptiveMatteBorder implements Border {
56
private Insets insets;
57
private int shadowDepth;
58
private boolean topLeftInsets;
60
/** Creates a new instance of AdaptiveMatteBorder */
61
public AdaptiveMatteBorder(boolean t, boolean l, boolean b, boolean r, int shadowDepth, boolean topLeftInsets) {
62
insets = new Insets (t ? topLeftInsets ? shadowDepth + 1 : 1 : 0, l ? topLeftInsets ? shadowDepth + 1: 1 : 0, b ? 1 + shadowDepth : shadowDepth, r ? 1 + shadowDepth : shadowDepth);
63
this.shadowDepth = shadowDepth;
64
this.topLeftInsets = topLeftInsets;
67
public AdaptiveMatteBorder(boolean t, boolean l, boolean b, boolean r, int shadowDepth) {
68
this (t, l, b, r, shadowDepth, false);
71
private Insets maybeOmitInsets (Insets ins, Component c) {
72
if (shadowDepth <= 0 || !topLeftInsets) {
75
Insets result = new Insets(ins.top, ins.left, ins.right, ins.bottom);
77
Point p = c.getLocation();
88
public Insets getBorderInsets(Component c) {
89
return maybeOmitInsets(insets, c);
92
public boolean isBorderOpaque() {
97
public void paintBorder(Component c, Graphics g, int x, int y, int w, int h) {
98
Color color = g.getColor();
99
Insets ins = getBorderInsets(c);
100
Point p = c.getLocation();
102
//This will always really come from the theme on GTK
103
g.setColor (UIManager.getColor("controlShadow")); //NOI18N
117
g.fillRect(x, y, w, 1);
120
g.fillRect(x, y, 1, h);
123
g.fillRect(x + w - 1, y, 1, h);
125
if (ins.bottom > 0) {
126
g.fillRect(x, y + h - 1, w, 1);
129
boolean isViewTab = isViewTab(c);
131
if (shadowDepth > 1) {
132
Rectangle clip = g.getClipBounds();
133
boolean clipTouchesRight = ((clip.x + clip.width) >= (x + w));
134
boolean clipTouchesBottom = ((clip.y + clip.height) >= (y + h));
136
if (clipTouchesBottom || clipTouchesRight) {
137
Color ctrl = UIManager.getColor ("control"); //NOI18N
138
Color base = UIManager.getColor("controlShadow");
141
for (int i = 1; i < shadowDepth; i++) {
142
curr = colorTowards (base, ctrl, shadowDepth, i+1);
144
if (clipTouchesRight && ins.right > 0) {
145
g.fillRect(x + w - 1 + i, y + (isViewTab ? 0 : i), 1, h);
147
if (clipTouchesBottom && ins.bottom > 0) {
148
g.fillRect(x + i, y + h - 1 + i, w - 1, 1);
156
// private static int[] xpoints = new int[4];
157
// private static int[] ypoints = new int[4];
159
static boolean isViewTab (Component c) {
160
if (c.getParent() instanceof JComponent) {
161
JComponent jc = (JComponent) c.getParent();
162
Object o = jc.getClientProperty("viewType");
163
if (o != null && o instanceof Integer) {
164
return ((Integer) o).intValue() == 0;
170
private static final float[] comps = new float[4];
171
private static final float[] targs = new float[4];
173
static final Color colorTowards (Color base, Color target, float steps, float step) {
174
base.getColorComponents(comps);
175
target.getColorComponents(targs);
177
comps[3] = 1.0f; //No transparency, performance problems
179
float factor = (step / steps);
181
for (int i=0; i < 3; i++) {
182
comps[i] = saturate(comps[i] - (factor * (comps[i] - targs[i])));
186
// comps[3] = 1f - (step / steps);
187
Color result = new Color (comps[0], comps[1], comps[2], comps[3]);
191
private static final float saturate (float f) {