/*!
* This program is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software
* Foundation.
*
* You should have received a copy of the GNU Lesser General Public License along with this
* program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html
* or from the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* This program 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 Lesser General Public License for more details.
*
* Copyright (c) 2002-2013 Pentaho Corporation.. All rights reserved.
*/
package org.pentaho.reporting.designer.core.util.docking;
import javax.swing.*;
import javax.swing.plaf.ButtonUI;
import javax.swing.text.StyleContext;
import java.awt.*;
import java.awt.font.FontRenderContext;
import java.awt.font.GlyphVector;
import java.awt.font.LineMetrics;
import java.awt.geom.AffineTransform;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
/**
* User: Martin Date: 24.03.2005 Time: 13:50:20
*/
public class ImageToggleButton extends JToggleButton {
private enum FirstIconAlignment {
TOP,
BOTTOM,
LEFT,
RIGHT
}
private static class RotateTextIcon {
public static final int NONE = 0;
public static final int CW = 1;
public static final int CCW = 2;
private RotateTextIcon() {
}
}
static {
UIManager.put( "ImageToggleButton", "javax.swing.plaf.basic.BasicToggleButtonUI" );//NON-NLS
}
private ImageIcon imageIcon;
private String text;
private GlobalPane.Alignment alignment;
public ImageToggleButton( final ImageIcon icon,
final String text ) {
this( icon, text, GlobalPane.Alignment.LEFT );
}
public ImageToggleButton( final ImageIcon icon,
final String text,
final GlobalPane.Alignment alignment ) {
super();
this.imageIcon = icon;
this.text = text;
setMargin( new Insets( 0, 0, 0, 0 ) );
setContentAreaFilled( false );
setBorderPainted( false );
setBorder( BorderFactory.createEmptyBorder( 2, 2, 2, 2 ) );
setFont( StyleContext.getDefaultStyleContext().getFont( getFont().getName(), Font.PLAIN, 10 ) );
setAlignmentX( alignment );
setFocusable( false );
}
public String getUIClassID() {
return "ImageToggleButton";//NON-NLS
}
public void setAlignmentX( final GlobalPane.Alignment alignment ) {
this.alignment = alignment;
switch( alignment ) {
case TOP:
case BOTTOM: {
ImageIcon icon = createRotatedTextIcon( getForeground(), RotateTextIcon.NONE, getFont(), text );
icon = createComposedImageIcon( this.imageIcon, icon, FirstIconAlignment.LEFT );
final ImageIcon normalIcon = createButtonImageIcon( icon, new Insets( 3, 3, 3, 3 ), false, false );
final ImageIcon selectedIcon = createButtonImageIcon( icon, new Insets( 3, 3, 3, 3 ), true, false );
final ImageIcon selectedRolloverIcon = createButtonImageIcon( icon, new Insets( 3, 3, 3, 3 ), true, true );
final ImageIcon rolloverIcon = createButtonImageIcon( icon, new Insets( 3, 3, 3, 3 ), false, true );
setIcon( normalIcon );
setSelectedIcon( selectedIcon );
setRolloverSelectedIcon( selectedRolloverIcon );
setRolloverIcon( rolloverIcon );
break;
}
case LEFT: {
ImageIcon icon = createRotatedTextIcon( getForeground(), RotateTextIcon.CCW, getFont(), text );
icon = createComposedImageIcon( this.imageIcon, icon, FirstIconAlignment.BOTTOM );
final ImageIcon normalIcon = createButtonImageIcon( icon, new Insets( 3, 3, 3, 3 ), false, false );
final ImageIcon selectedIcon = createButtonImageIcon( icon, new Insets( 3, 3, 3, 3 ), true, false );
final ImageIcon selectedRolloverIcon = createButtonImageIcon( icon, new Insets( 3, 3, 3, 3 ), true, true );
final ImageIcon rolloverIcon = createButtonImageIcon( icon, new Insets( 3, 3, 3, 3 ), false, true );
setIcon( normalIcon );
setSelectedIcon( selectedIcon );
setRolloverSelectedIcon( selectedRolloverIcon );
setRolloverIcon( rolloverIcon );
break;
}
case RIGHT: {
ImageIcon icon = createRotatedTextIcon( getForeground(), RotateTextIcon.CW, getFont(), text );
icon = createComposedImageIcon( this.imageIcon, icon, FirstIconAlignment.TOP );
final ImageIcon normalIcon = createButtonImageIcon( icon, new Insets( 3, 3, 3, 3 ), false, false );
final ImageIcon selectedIcon = createButtonImageIcon( icon, new Insets( 3, 3, 3, 3 ), true, false );
final ImageIcon selectedRolloverIcon = createButtonImageIcon( icon, new Insets( 3, 3, 3, 3 ), true, true );
final ImageIcon rolloverIcon = createButtonImageIcon( icon, new Insets( 3, 3, 3, 3 ), false, true );
setIcon( normalIcon );
setSelectedIcon( selectedIcon );
setRolloverSelectedIcon( selectedRolloverIcon );
setRolloverIcon( rolloverIcon );
break;
}
}
}
private static ImageIcon createComposedImageIcon( final ImageIcon firstIcon,
final ImageIcon secondIcon,
final FirstIconAlignment firstIconAlignment ) {
if ( firstIcon == null && secondIcon == null ) {
return null;
}
if ( firstIcon == null ) {
return secondIcon;
}
if ( secondIcon == null ) {
return firstIcon;
}
switch( firstIconAlignment ) {
case TOP: {
final int width = Math.max( firstIcon.getIconWidth(), secondIcon.getIconWidth() );
final int height = firstIcon.getIconHeight() + secondIcon.getIconHeight();
final BufferedImage bi = new BufferedImage( width, height, BufferedImage.TYPE_INT_ARGB );
final Graphics graphics = bi.getGraphics();
graphics.drawImage( firstIcon.getImage(), ( width - firstIcon.getIconWidth() ) / 2, 0, null );
graphics.drawImage( secondIcon.getImage(), ( width - secondIcon.getIconWidth() ) / 2, firstIcon.getIconHeight(),
null );
return new ImageIcon( bi );
}
case BOTTOM: {
final int width = Math.max( firstIcon.getIconWidth(), secondIcon.getIconWidth() );
final int height = firstIcon.getIconHeight() + secondIcon.getIconHeight();
final BufferedImage bi = new BufferedImage( width, height, BufferedImage.TYPE_INT_ARGB );
final Graphics graphics = bi.getGraphics();
graphics.drawImage( firstIcon.getImage(), ( width - firstIcon.getIconWidth() ) / 2,
height - firstIcon.getIconHeight(), null );
graphics.drawImage( secondIcon.getImage(), ( width - secondIcon.getIconWidth() ) / 2, 0, null );
return new ImageIcon( bi );
}
case LEFT: {
final int width = firstIcon.getIconWidth() + secondIcon.getIconWidth();
final int height = Math.max( firstIcon.getIconHeight(), secondIcon.getIconHeight() );
final BufferedImage bi = new BufferedImage( width, height, BufferedImage.TYPE_INT_ARGB );
final Graphics graphics = bi.getGraphics();
graphics.drawImage( firstIcon.getImage(), 0, ( height - firstIcon.getIconHeight() ) / 2, null );
graphics
.drawImage( secondIcon.getImage(), firstIcon.getIconWidth(), ( height - secondIcon.getIconHeight() ) / 2,
null );
return new ImageIcon( bi );
}
case RIGHT: {
final int width = firstIcon.getIconWidth() + secondIcon.getIconWidth();
final int height = Math.max( firstIcon.getIconHeight(), secondIcon.getIconHeight() );
final BufferedImage bi = new BufferedImage( width, height, BufferedImage.TYPE_INT_ARGB );
final Graphics graphics = bi.getGraphics();
graphics.drawImage( firstIcon.getImage(), secondIcon.getIconWidth(), ( height - firstIcon.getIconHeight() ) / 2,
null );
graphics.drawImage( secondIcon.getImage(), 0, ( height - secondIcon.getIconHeight() ) / 2, null );
return new ImageIcon( bi );
}
}
return new ImageIcon();
}
private static ImageIcon createButtonImageIcon( final ImageIcon icon,
final Insets insets,
final boolean selected,
final boolean rollover ) {
final int w = icon.getIconWidth() + insets.left + insets.right;
final int h = icon.getIconHeight() + insets.top + insets.bottom;
final BufferedImage bi = new BufferedImage( w, h, BufferedImage.TYPE_INT_ARGB );
final Graphics2D g = bi.createGraphics();
g.setRenderingHint( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON );
if ( selected ) {
final int o = -5;
int b = 40;
if ( rollover ) {
b = 60;
}
final GradientPaint gp = new GradientPaint( 0, o,
new Color( Math.min( 164 + b, 255 ), Math.min( 166 + b, 255 ), Math.min( 172 + b, 255 ) ), 0, h + o,
new Color( Math.min( 189 + b, 255 ), Math.min( 192 + b, 255 ), Math.min( 198 + b, 255 ) ), true );
g.setPaint( gp );
} else {
final int o = -5;
int b = 0;
if ( rollover ) {
b = 60;
}
final GradientPaint gp = new GradientPaint( 0, o,
new Color( Math.min( 251 + b, 255 ), Math.min( 251 + b, 255 ), Math.min( 252 + b, 255 ) ), 0, h + o,
new Color( Math.min( 215 + b, 255 ), Math.min( 218 + b, 255 ), Math.min( 224 + b, 255 ) ), true );
g.setPaint( gp );
}
final RoundRectangle2D roundRectangle2D = new RoundRectangle2D.Double( 0, 0, w - 1, h - 1, 6, 6 );
//if (!selected || rollover)
{
g.fill( roundRectangle2D );
}
if ( selected ) {
final GradientPaint gp = new GradientPaint( 0, 0,
new Color( Math.min( 125, 255 ), Math.min( 127, 255 ), Math.min( 131, 255 ) ), 0, h,
new Color( Math.min( 162, 255 ), Math.min( 164, 255 ), Math.min( 169, 255 ) ), true );
g.setPaint( gp );
} else {
final GradientPaint gp = new GradientPaint( 0, 0,
new Color( Math.min( 149, 255 ), Math.min( 155, 255 ), Math.min( 158, 255 ) ), 0, h,
new Color( Math.min( 85, 255 ), Math.min( 88, 255 ), Math.min( 94, 255 ) ), true );
g.setPaint( gp );
}
//if (!selected || rollover)
{
g.draw( roundRectangle2D );
}
g.drawImage( icon.getImage(), insets.left, insets.top, null );
return new ImageIcon( bi );
}
private static ImageIcon createRotatedTextIcon( final Color foreground,
final int rotate,
final Font font,
final String text ) {
final FontRenderContext fontRenderContext = new FontRenderContext( null, false, false );
final GlyphVector glyphs = font.createGlyphVector( fontRenderContext, text );
final int width = (int) glyphs.getLogicalBounds().getWidth() + 4;
//height = (int)glyphs.getLogicalBounds().getHeight();
final LineMetrics lineMetrics = font.getLineMetrics( text, fontRenderContext );
final float ascent = lineMetrics.getAscent();
final int height = (int) Math.ceil( lineMetrics.getHeight() );
final int w = rotate == RotateTextIcon.CW || rotate == RotateTextIcon.CCW ? height : width;
final int h = rotate == RotateTextIcon.CW || rotate == RotateTextIcon.CCW ? width : height;
final BufferedImage bufferedImage = new BufferedImage( w, h, BufferedImage.TYPE_INT_ARGB );
final Graphics2D g2d = (Graphics2D) bufferedImage.getGraphics();
g2d.setFont( font );
final AffineTransform oldTransform = g2d.getTransform();
g2d.setColor( foreground );
g2d.setRenderingHint( RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON );
g2d.setRenderingHint( RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON );
if ( rotate == RotateTextIcon.NONE ) {
g2d.drawString( text, 2, ascent );
} else if ( rotate == RotateTextIcon.CW ) {
final AffineTransform trans = new AffineTransform();
trans.concatenate( oldTransform );
trans.translate( 0, 2 );
trans.rotate( Math.PI / 2, height / 2, width / 2 );
g2d.setTransform( trans );
g2d.drawString( text, ( height - width ) / 2, ( width - height ) / 2 + ascent );
} else if ( rotate == RotateTextIcon.CCW ) {
final AffineTransform trans = new AffineTransform();
trans.concatenate( oldTransform );
trans.translate( 0, -2 );
trans.rotate( Math.PI * 3 / 2, height / 2, width / 2 );
g2d.setTransform( trans );
g2d.drawString( text, ( height - width ) / 2, ( width - height ) / 2 + ascent );
}
return new ImageIcon( bufferedImage );
}
public void setUI( final ButtonUI ui ) {
super.setUI( ui );
if ( alignment != null ) {
setAlignmentX( alignment );
}
}
}