/*
* Bibliothek - DockingFrames
* Library built on Java/Swing, allows the user to "drag and drop"
* panels containing any Swing-Component the developer likes to add.
*
* Copyright (C) 2008 Benjamin Sigg
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library 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.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
* Benjamin Sigg
* benjamin_sigg@gmx.ch
* CH - Switzerland
*/
package bibliothek.extension.gui.dock.theme.smooth;
import java.awt.Color;
import java.awt.Container;
import bibliothek.gui.Dockable;
import bibliothek.gui.dock.FlapDockStation;
import bibliothek.gui.dock.themes.basic.BasicButtonDockTitle;
import bibliothek.gui.dock.title.DockTitleEvent;
import bibliothek.gui.dock.title.DockTitleVersion;
/**
* A title intended for the {@link FlapDockStation}, this title changes its color
* smoothly.
* @author Benjamin Sigg
*/
public class SmoothDefaultButtonTitle extends BasicButtonDockTitle {
private final int ACTIVE_STATE = 0;
private final int SELECTED_STATE = 1;
private final int INACTIVE_STATE = 2;
/** the current time for each state */
private int[] current;
/** a trigger for the animation */
private SmoothChanger changer = new SmoothChanger( 3 ){
@Override
protected int destination() {
if( isActive() )
return ACTIVE_STATE;
else if( isSelected() )
return SELECTED_STATE;
else
return INACTIVE_STATE;
}
@Override
protected void repaint( int[] current ) {
SmoothDefaultButtonTitle.this.current = current.clone();
updateColors();
}
};
/**
* Creates a new title.
* @param dockable the element for which the title is shown
* @param origin the origin of this title
*/
public SmoothDefaultButtonTitle( Dockable dockable, DockTitleVersion origin ){
super( dockable, origin );
}
@Override
public void setActive( boolean active ) {
super.setActive(active);
if( changer != null )
changer.trigger();
}
@Override
public void changed(DockTitleEvent event) {
super.changed(event);
if( changer != null )
changer.trigger();
}
@Override
protected void updateColors() {
updateForegroundColor();
updateBackgroundColor();
}
/**
* Updates the color used in the foreground
*/
protected void updateForegroundColor(){
if( changer != null && changer.isRunning() && current != null ){
setForeground( triColor( foreground( getActiveTextColor() ), foreground( getSelectedTextColor() ), foreground( getInactiveTextColor() )));
}
else{
if( isActive() )
setForeground( getActiveTextColor() );
else if( isSelected() )
setForeground( getSelectedTextColor() );
else
setForeground( getInactiveTextColor() );
}
}
/**
* Updates the color used in the background
*/
protected void updateBackgroundColor(){
if( changer != null && changer.isRunning() && current != null ){
setBackground( triColor( background( getActiveColor() ), background( getSelectedColor() ), background( getInactiveColor() )));
}
else{
if( isActive() )
setBackground( getActiveColor() );
else if( isSelected() )
setBackground( getSelectedColor() );
else
setBackground( getInactiveColor() );
}
}
/**
* Creates a combination of colors according to the {@link #current}
* states.
* @param a the color for state 0
* @param b the color for state 0
* @param c the color for state 0
* @return the combination of all these colors
*/
private Color triColor( Color a, Color b, Color c ){
int sum = 0;
for( int count : current )
sum += count;
if( sum == 0 )
return Color.BLACK;
double factorA = current[0] / (double)sum;
double factorB = current[1] / (double)sum;
double factorC = current[2] / (double)sum;
double red = factorA * a.getRed() + factorB * b.getRed() + factorC * c.getRed();
double green = factorA * a.getGreen() + factorB * b.getGreen() + factorC * c.getGreen();
double blue = factorA * a.getBlue() + factorB * b.getBlue() + factorC * c.getBlue();
return new Color(
Math.max( 0, Math.min( 255, (int)red )),
Math.max( 0, Math.min( 255, (int)green )),
Math.max( 0, Math.min( 255, (int)blue )));
}
/**
* Tries to find the foreground color used on this title assuming that
* <code>set</code> was given to {@link #setForeground(Color)}.
* @param set the expected color, can be <code>null</code>
* @return the foreground color
*/
private Color foreground( Color set ){
if( set != null )
return set;
Container parent = getParent();
if( parent == null )
return Color.BLACK;
set = parent.getForeground();
if( set != null )
return set;
return Color.BLACK;
}
/**
* Tries to find the background color used on this title assuming that
* <code>set</code> was given to {@link #setBackground(Color)}.
* @param set the expected color, can be <code>null</code>
* @return the background color
*/
private Color background( Color set ){
if( set != null )
return set;
Container parent = getParent();
if( parent == null )
return Color.WHITE;
set = parent.getBackground();
if( set != null )
return set;
return Color.WHITE;
}
}