Package org.openquark.gems.client.utilities

Source Code of org.openquark.gems.client.utilities.SmoothHighlightBorder

/*
* Copyright (c) 2007 BUSINESS OBJECTS SOFTWARE LIMITED
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
*     * Redistributions of source code must retain the above copyright notice,
*       this list of conditions and the following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright
*       notice, this list of conditions and the following disclaimer in the
*       documentation and/or other materials provided with the distribution.
*     * Neither the name of Business Objects nor the names of its contributors
*       may be used to endorse or promote products derived from this software
*       without specific prior written permission.
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/


/*
* NavEditorPanel.java
* Creation date: Oct 18, 2003
* By: Frank Worsley
*/
package org.openquark.gems.client.utilities;

import java.awt.Color;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.image.BufferedImage;

import javax.swing.border.Border;

/**
* A smooth, partly transparent border with an optional color highlight for the value editors
* and the Intellicut panel.
* @author Frank Worsley
*/
public class SmoothHighlightBorder implements Border {

    /** The size of the border. If you change this you MUST update the getShades() method. */
    private static final int SIZE = 8;
   
    /** Height of the drag area at the top of the border. */
    private static final int TITLE_BAR_HEIGHT = 6;
   
    /** The insets of the border without a title bar. */
    public static final Insets NORMAL_INSETS = new Insets(SIZE, SIZE, SIZE, SIZE);
   
    /** The insets of the border with a title bar. */
    private static final Insets TITLE_BAR_INSETS = new Insets(SIZE + TITLE_BAR_HEIGHT, SIZE, SIZE, SIZE);
       
    /** The highlight colour to use. */
    private final Color highlight;
   
    /** Whether to draw a title bar. */
    private final boolean drawTitleBar;
       
    /** The background colour of the component when the shades were last calculated. */
    private Color lastBackground = null;
       
    /** The shade colours that were last calculated. */
    private Color[] shades;

    /**
     * Constructs a new IntellicutPanelBorder with the given highlight colour.
     * @param highlight the highlight colour
     * @param drawTitleBar whether to draw a small titlebar at the top of the border
     */
    public SmoothHighlightBorder(Color highlight, boolean drawTitleBar) {
           
        if (highlight == null) {
            throw new NullPointerException();
        }
           
        this.highlight = highlight;
        this.drawTitleBar = drawTitleBar;
    }
       
    /**
     * Calculates the shades of colour we want to use for shading from the component background,
     * to the highlight colour and then to transparency. The shades are only re-calculated if the
     * background colour changes. The inner shade is at index 0, the most outer shade at index 7.
     * @param background the component background colour
     * @return an array of shade colours from inside to outside
     */
    private Color[] getShades(Color background) {

        if (shades != null && background.equals(lastBackground)) {
            return shades;
        }

        lastBackground = background;

        shades = new Color[SIZE];

        // Figure out the inital color we fade to. From that color we fade to complete transparency.
        // If the highlight is a light color we want to fade to a dark color and vice versa.
        // We say the highlight is a light color if two RGB values are over 128.

        boolean redOver = highlight.getRed() >= 128;
        boolean greenOver = highlight.getGreen() >= 128;
        boolean blueOver = highlight.getBlue() >= 128;

        int iRed = -1;
        int iGreen = -1;
        int iBlue = -1;

        if ((redOver && greenOver) || (redOver && blueOver) || (greenOver && blueOver)) {
            iRed = iGreen = iBlue = 50;
        } else {
            iRed = iGreen = iBlue = 150;
        }

        Color initialFade = new Color(iRed, iGreen, iBlue, highlight.getAlpha() / 2);
        Color finalFade = new Color(iRed, iGreen, iBlue, 0);

        // Fade from component background to the higlight color over a 3 pixel range.

        int rDiff = (highlight.getRed() - background.getRed()) / 3;
        int gDiff = (highlight.getGreen() - background.getGreen()) / 3;
        int bDiff = (highlight.getBlue() - background.getBlue()) / 3;
        int aDiff = (highlight.getAlpha() - background.getAlpha()) / 3;
           
        for (int i = 1; i <= 3; i++) {
            shades[8 - i] = new Color(background.getRed()   + rDiff * i,
                                      background.getGreen() + gDiff * i,
                                      background.getBlue()  + bDiff * i,
                                      background.getAlpha() + aDiff * i);
        }
           
        // The 4th pixel is the initial fade color.
           
        shades[4] = initialFade;
           
        // Then fade from inital fade to transparency over 4 pixels.
           
        rDiff = (finalFade.getRed()   - initialFade.getRed())   / 4;
        gDiff = (finalFade.getGreen() - initialFade.getGreen()) / 4;
        bDiff = (finalFade.getBlue()  - initialFade.getBlue())  / 4;
        aDiff = (finalFade.getAlpha() - initialFade.getAlpha()) / 4;
           
        for (int i = 1; i <= 4; i++) {
            shades[4 - i] = new Color(initialFade.getRed()   + rDiff * i,
                                      initialFade.getGreen() + gDiff * i,
                                      initialFade.getBlue()  + bDiff * i,
                                      initialFade.getAlpha() + aDiff * i);
        }
           
        return shades;
    }

    /**
     * @see javax.swing.border.Border#paintBorder(java.awt.Component, java.awt.Graphics, int, int, int, int)
     */
    public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) {

        Color[] shades = getShades(c.getBackground());

        BufferedImage buffer = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
        Graphics bg = buffer.getGraphics();

        // Setup some constant values.
        int cx0 = x + SIZE + 1;
        int cy0 = y + SIZE + 1;

        int cx1 = x + width - SIZE - 2;
        int cy1 = y + height - SIZE - 2;
           
        // Setup values that will be manipulated in the loop.
        int x1 = x + width - 1;
        int y1 = y + height - 1;
           
        int x2 = x + width - 2*SIZE - 1;
        int y2 = y + height - 2*SIZE - 1;

        for (int i = 0; i < SIZE; i++) {

            // We draw the outermost lines first, then move inwards.

            Color color = shades[i];
            bg.setColor(color);
               
            // draw top & bottom
            bg.drawLine(cx0, y, cx1, y);
            bg.drawLine(cx0, y1, cx1, y1);
               
            // draw left & right
            bg.drawLine(x, cy0, x, cy1);
            bg.drawLine(x1, cy0, x1, cy1);

            int arcSize = 2 * (SIZE - i);
               
            // draw top-left & right corners
            bg.drawArc(x, y, arcSize, arcSize, 180, -90);
            bg.drawArc(x2, y, arcSize, arcSize, 0, 90);
               
            // draw bottom-left & right corners
            bg.drawArc(x, y2, arcSize, arcSize, 180, 90);
            bg.drawArc(x2, y2, arcSize, arcSize, 0, -90);
               
            // update coordinates
            x++;
            y++;
               
            x1--;
            y1--;
               
            y2++;
            x2++;
        }
       
        if (drawTitleBar) {
            // Draw the title bar.
            bg.setColor(highlight);
            bg.fillRect(SIZE, SIZE, width - 2 * SIZE, TITLE_BAR_HEIGHT);
           
            bg.setColor(shades[SIZE - 1]);
            bg.drawRect(SIZE - 1, SIZE - 1, width - 2 * SIZE + 1, TITLE_BAR_HEIGHT);
        }
       
        // Draw the image to the main graphics context
        g.drawImage(buffer, 0, 0, null);

        bg.dispose();
        buffer.flush();
    }

    /**
     * @see javax.swing.border.Border#getBorderInsets(java.awt.Component)
     */
    public Insets getBorderInsets(Component c) {
        return drawTitleBar ? (Insets) TITLE_BAR_INSETS.clone() : (Insets) NORMAL_INSETS.clone();
    }
   
    /**
     * @see javax.swing.border.Border#isBorderOpaque()
     */
    public boolean isBorderOpaque() {
        return false;
    }
}
TOP

Related Classes of org.openquark.gems.client.utilities.SmoothHighlightBorder

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.