/*
* Copyright (C) 2010-2016 JPEXS
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.jpexs.decompiler.flash.gui;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.LinearGradientPaint;
import java.awt.MultipleGradientPaint;
import java.awt.RadialGradientPaint;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.event.MouseEvent;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;
import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.plaf.ComponentUI;
import org.pushingpixels.flamingo.api.common.model.PopupButtonModel;
import org.pushingpixels.flamingo.internal.ui.ribbon.appmenu.BasicRibbonApplicationMenuButtonUI;
import org.pushingpixels.flamingo.internal.ui.ribbon.appmenu.JRibbonApplicationMenuButton;
import org.pushingpixels.lafwidget.animation.effects.GhostingListener;
import org.pushingpixels.substance.api.DecorationAreaType;
import org.pushingpixels.substance.api.SubstanceLookAndFeel;
import org.pushingpixels.substance.api.SubstanceSkin;
import org.pushingpixels.substance.flamingo.common.ui.ActionPopupTransitionAwareUI;
import org.pushingpixels.substance.flamingo.utils.CommandButtonVisualStateTracker;
import org.pushingpixels.substance.internal.animation.StateTransitionTracker;
/**
* UI for {@link JRibbonApplicationMenuButton} components in <b>Substance</b>
* look and feel.
*
* @author Kirill Grouchnikov
*/
/**
*
* @author JPEXS
*/
public class MyRibbonApplicationMenuButtonUI extends BasicRibbonApplicationMenuButtonUI implements
ActionPopupTransitionAwareUI {
private MyResizableIcon hoverIcon = null;
private MyResizableIcon clickIcon = null;
private MyResizableIcon normalIcon = null;
private MyResizableIcon clearIcon = null;
private final boolean buttonResized = false;
public MyResizableIcon getClickIcon() {
return clickIcon;
}
public static MyResizableIcon[] getIcons() {
MyResizableIcon clearIcon = View.getMyResizableIcon("buttonicon_clear_256");
return new MyResizableIcon[]{
clearIcon,
//normal
new MyResizableIcon(clearIcon.originalImage) {
@Override
public void paintIcon(Component c, Graphics g, int x, int y) {
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
SubstanceSkin skin = SubstanceLookAndFeel.getCurrentSkin();
g2.setPaint(new LinearGradientPaint(0, 0, 0, getIconHeight(), new float[]{0f, 1f}, new Color[]{
Color.white,
Color.black
}, MultipleGradientPaint.CycleMethod.NO_CYCLE
));
Shape s = new Ellipse2D.Double(x, y, getIconWidth(), getIconHeight());
g2.fill(s);
float border = (0.0625f * getIconWidth());
float wborder = (0.00625f * getIconWidth());
g2.setPaint(Color.white);
s = new Ellipse2D.Double(x + border, y + border, getIconWidth() - 2 * border, getIconHeight() - 2 * border);
g2.fill(s);
g2.setPaint(new RadialGradientPaint(getIconWidth() / 2.0f, getIconHeight() / 2.0f, getIconWidth() / 2.0f - border - wborder, new float[]{0f, 0.42236024f, 0.69565213f, 0.97722566f, 1f}, new Color[]{
new Color(0xff, 0xff, 0xff),
new Color(0xff, 0xff, 0xff),
new Color(0xec, 0xec, 0xec),
new Color(0xb6, 0xb6, 0xb6),
new Color(0xff, 0xff, 0xff)
}, MultipleGradientPaint.CycleMethod.NO_CYCLE));
s = new Ellipse2D.Double(x + border + wborder, y + border + wborder, getIconWidth() - 2 * border - 2 * wborder, getIconHeight() - 2 * border - 2 * wborder);
g2.fill(s);
g2.setPaint(skin.getEnabledColorScheme(DecorationAreaType.PRIMARY_TITLE_PANE).getMidColor());
super.paintIcon(c, g, x, y);
}
},
//hover
new MyResizableIcon(clearIcon.originalImage) {
@Override
public void paintIcon(Component c, Graphics g, int x, int y) {
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
SubstanceSkin skin = SubstanceLookAndFeel.getCurrentSkin();
/*Color lightColor = skin.getColorScheme(DecorationAreaType.SECONDARY_TITLE_PANE, ColorSchemeAssociationKind.HIGHLIGHT, ComponentState.ROLLOVER_UNSELECTED).
getUltraLightColor();
Color midColor = skin.getColorScheme(DecorationAreaType.SECONDARY_TITLE_PANE, ColorSchemeAssociationKind.FILL, ComponentState.ROLLOVER_UNSELECTED).getMidColor();
Color darkColor = skin.getColorScheme(DecorationAreaType.SECONDARY_TITLE_PANE, ColorSchemeAssociationKind.BORDER, ComponentState.ROLLOVER_UNSELECTED).getUltraDarkColor();
*/
g2.setPaint(new LinearGradientPaint(0, 0, 0, getIconHeight(), new float[]{0f, 1f}, new Color[]{
Color.white,
Color.black
}, MultipleGradientPaint.CycleMethod.NO_CYCLE));
Shape s = new Ellipse2D.Double(x, y, getIconWidth(), getIconHeight());
g2.fill(s);
float border = (0.0625f * getIconWidth());
float wborder = (0.00625f * getIconWidth());
g2.setPaint(Color.white);
s = new Ellipse2D.Double(x + border, y + border, getIconWidth() - 2 * border, getIconHeight() - 2 * border);
g2.fill(s);
g2.setPaint(new RadialGradientPaint(getIconWidth() / 2.0f, getIconHeight() / 2.0f, getIconWidth() / 2.0f - border - wborder, new float[]{0f, 0.42236024f, 0.69565213f, 0.97722566f, 1f}, new Color[]{
new Color(0xff, 0xff, 0xff),
new Color(0xff, 0xff, 0xff),
new Color(0xec, 0xec, 0xec),
new Color(0xb6, 0xb6, 0xb6),
new Color(0xff, 0xff, 0xff)
}, MultipleGradientPaint.CycleMethod.NO_CYCLE));
s = new Ellipse2D.Double(x + border + wborder, y + border + wborder, getIconWidth() - 2 * border - 2 * wborder, getIconHeight() - 2 * border - 2 * wborder);
g2.fill(s);
super.paintIcon(c, g, x, y);
}
},
//click
new MyResizableIcon(clearIcon.originalImage) {
@Override
public void paintIcon(Component c, Graphics g, int x, int y) {
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
SubstanceSkin skin = SubstanceLookAndFeel.getCurrentSkin();
/*Color lightColor = skin.getColorScheme(DecorationAreaType.SECONDARY_TITLE_PANE, ColorSchemeAssociationKind.FILL, ComponentState.ROLLOVER_SELECTED).getUltraLightColor();
Color midColor = skin.getColorScheme(DecorationAreaType.SECONDARY_TITLE_PANE, ColorSchemeAssociationKind.FILL, ComponentState.ROLLOVER_SELECTED).getMidColor();
Color darkColor = skin.getColorScheme(DecorationAreaType.SECONDARY_TITLE_PANE, ColorSchemeAssociationKind.FILL, ComponentState.ROLLOVER_SELECTED).shiftBackground(Color.black, 0.7).getUltraDarkColor();
*/
g2.setPaint(new LinearGradientPaint(0, 0, 0, getIconHeight(), new float[]{0f, 1f}, new Color[]{
Color.white,
Color.black
}, MultipleGradientPaint.CycleMethod.NO_CYCLE));
Shape s = new Ellipse2D.Double(x, y, getIconWidth(), getIconHeight());
g2.fill(s);
float border = (0.0625f * getIconWidth());
float wborder = (0.00625f * getIconWidth());
g2.setPaint(Color.white);
s = new Ellipse2D.Double(x + border, y + border, getIconWidth() - 2 * border, getIconHeight() - 2 * border);
g2.fill(s);
g2.setPaint(new RadialGradientPaint(getIconWidth() / 2.0f, getIconHeight() / 2.0f, getIconWidth() / 2.0f - border - wborder, new float[]{0f, 0.1f, 0.5f, 0.97722566f, 1f}, new Color[]{
new Color(0xff, 0xff, 0xff),
new Color(0xff, 0xff, 0xff),
new Color(0xec, 0xec, 0xec),
new Color(0xb6, 0xb6, 0xb6),
new Color(0xff, 0xff, 0xff)
}, MultipleGradientPaint.CycleMethod.NO_CYCLE));
s = new Ellipse2D.Double(x + border + wborder, y + border + wborder, getIconWidth() - 2 * border - 2 * wborder, getIconHeight() - 2 * border - 2 * wborder);
g2.fill(s);
AffineTransform origt = g2.getTransform();
AffineTransform t = (AffineTransform) origt.clone();
t.translate(-getIconWidth() / 2, -getIconHeight() / 2);
t.scale(0.8, 0.8);
t.translate(getIconWidth() / 2 + getIconWidth() / 4, getIconHeight() / 2 + getIconHeight() / 4);
g2.setTransform(t);
g2.setPaint(Color.BLACK);
super.paintIcon(c, g, x, y);
g2.setTransform(origt);
}
}
};
}
public MyRibbonApplicationMenuButtonUI() {
super();
MyResizableIcon[] icons = getIcons();
clearIcon = icons[0];
normalIcon = icons[1];
hoverIcon = icons[2];
clickIcon = icons[3];
}
/**
* Model change listener for ghost image effects.
*/
private GhostingListener substanceModelChangeListener;
/**
* Tracker for visual state transitions.
*/
protected CommandButtonVisualStateTracker substanceVisualStateTracker;
public static ComponentUI createUI(JComponent c) {
return new MyRibbonApplicationMenuButtonUI();
}
/*
* (non-Javadoc)
*
* @see org.jvnet.flamingo.common.ui.BasicCommandButtonUI#installListeners()
*/
@Override
protected void installListeners() {
super.installListeners();
this.substanceVisualStateTracker = new CommandButtonVisualStateTracker();
this.substanceVisualStateTracker.installListeners(this.commandButton);
this.substanceModelChangeListener = new GhostingListener(
this.commandButton, this.commandButton.getActionModel());
this.substanceModelChangeListener.registerListeners();
}
/*
* (non-Javadoc)
*
* @see
* org.jvnet.flamingo.common.ui.BasicCommandButtonUI#uninstallListeners()
*/
@Override
protected void uninstallListeners() {
this.substanceVisualStateTracker.uninstallListeners(this.commandButton);
this.substanceVisualStateTracker = null;
this.substanceModelChangeListener.unregisterListeners();
this.substanceModelChangeListener = null;
super.uninstallListeners();
}
private void updateIcons(JComponent c) {
Dimension dim = c.getPreferredSize();
hoverIcon.setDimension(dim);
clickIcon.setDimension(dim);
normalIcon.setDimension(dim);
}
/*
* (non-Javadoc)
*
* @see javax.swing.plaf.basic.BasicButtonUI#paint(java.awt.Graphics,
* javax.swing.JComponent)
*/
@Override
public void paint(Graphics g, JComponent c) {
JRibbonApplicationMenuButton b = (JRibbonApplicationMenuButton) c;
updateIcons(c);
this.layoutInfo = this.layoutManager.getLayoutInfo(this.commandButton, g);
commandButton.putClientProperty("icon.bounds", layoutInfo.iconRect);
Graphics2D g2d = (Graphics2D) g.create();
// Paint the icon
Icon icon = getCurrentIcon(b);
if (icon != null) {
paintButtonIcon(g2d);
}
g2d.dispose();
}
private Icon getCurrentIcon(JRibbonApplicationMenuButton button) {
PopupButtonModel mod = button.getPopupModel();
if (mod.isPopupShowing()) {
if (clickIcon != null) {
return clickIcon;
}
}
if (mod.isRollover()) {
if (hoverIcon != null) {
return hoverIcon;
}
}
if (normalIcon != null) {
return normalIcon;
}
return button.getIcon();
}
/*
* (non-Javadoc)
*
* @see
* org.jvnet.flamingo.common.ui.BasicCommandButtonUI#paintButtonIcon(java
* .awt.Graphics, java.awt.Rectangle)
*/
protected void paintButtonIcon(Graphics g) {
Icon regular = getCurrentIcon(this.applicationMenuButton);
if (regular == null) {
return;
}
//SubstanceLookAndFeel.getCurrentSkin().getActiveColorScheme(DecorationAreaType.GENERAL);
Graphics2D g2d = (Graphics2D) g.create();
regular.paintIcon(this.applicationMenuButton, g2d, 0, 0);
g2d.dispose();
}
/*
* (non-Javadoc)
*
* @see
* org.jvnet.flamingo.ribbon.ui.appmenu.BasicRibbonApplicationMenuButtonUI
* #update(java.awt.Graphics, javax.swing.JComponent)
*/
@Override
public void update(Graphics g, JComponent c) {
this.paint(g, c);
}
/*
* (non-Javadoc)
*
* @see
* org.jvnet.substance.SubstanceButtonUI#contains(javax.swing.JComponent,
* int, int)
*/
@Override
public boolean contains(JComponent c, int x, int y) {
// allow clicking anywhere in the area (around the button
// round outline as well) to activate the button.
return (x >= 0) && (x < c.getWidth()) && (y >= 0)
&& (y < c.getHeight());
}
@Override
public StateTransitionTracker getActionTransitionTracker() {
return this.substanceVisualStateTracker
.getActionStateTransitionTracker();
}
@Override
public StateTransitionTracker getPopupTransitionTracker() {
return this.substanceVisualStateTracker
.getPopupStateTransitionTracker();
}
@Override
public StateTransitionTracker getTransitionTracker() {
return this.substanceVisualStateTracker
.getPopupStateTransitionTracker();
}
@Override
public boolean isInside(MouseEvent me) {
return true;
}
}