001: /*
002: * Copyright (c) 2005-2008 Flamingo / Substance Kirill Grouchnikov. All Rights Reserved.
003: *
004: * Redistribution and use in source and binary forms, with or without
005: * modification, are permitted provided that the following conditions are met:
006: *
007: * o Redistributions of source code must retain the above copyright notice,
008: * this list of conditions and the following disclaimer.
009: *
010: * o Redistributions in binary form must reproduce the above copyright notice,
011: * this list of conditions and the following disclaimer in the documentation
012: * and/or other materials provided with the distribution.
013: *
014: * o Neither the name of Flamingo Kirill Grouchnikov nor the names of
015: * its contributors may be used to endorse or promote products derived
016: * from this software without specific prior written permission.
017: *
018: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
019: * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
020: * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
021: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
022: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
023: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
024: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
025: * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
026: * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
027: * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
028: * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
029: */
030: package org.jvnet.substance.flamingo.bcb.ui;
031:
032: import java.awt.AlphaComposite;
033: import java.awt.Graphics2D;
034: import java.awt.event.*;
035: import java.awt.geom.GeneralPath;
036: import java.awt.image.BufferedImage;
037: import java.util.HashMap;
038: import java.util.Map;
039:
040: import javax.swing.*;
041: import javax.swing.plaf.ComponentUI;
042:
043: import org.jvnet.flamingo.bcb.ui.*;
044: import org.jvnet.lafwidget.animation.FadeKind;
045: import org.jvnet.lafwidget.animation.FadeTracker;
046: import org.jvnet.substance.SubstanceImageCreator;
047: import org.jvnet.substance.SubstanceLookAndFeel;
048: import org.jvnet.substance.border.SubstanceBorderPainter;
049: import org.jvnet.substance.button.BaseButtonShaper;
050: import org.jvnet.substance.color.ColorScheme;
051: import org.jvnet.substance.painter.SubstanceGradientPainter;
052: import org.jvnet.substance.theme.SubstanceTheme;
053: import org.jvnet.substance.utils.*;
054: import org.jvnet.substance.utils.ComponentState.ColorSchemeKind;
055:
056: /**
057: * UI delegate for choices selector.
058: *
059: * @author Kirill Grouchnikov
060: */
061: public class SubstanceChoicesSelectorUI extends BasicChoicesSelectorUI {
062: /**
063: * Background images.
064: */
065: private static Map<String, BufferedImage> backgrounds = new HashMap<String, BufferedImage>();
066:
067: /**
068: * Mouse listener for fade animation effects.
069: */
070: protected MouseListener fadeMouseListener;
071:
072: /**
073: * Down-pointing arrows.
074: */
075: private static Map<SubstanceTheme, Icon> downArrows = new HashMap<SubstanceTheme, Icon>();
076:
077: /**
078: * Right-pointing arrows.
079: */
080: private static Map<SubstanceTheme, Icon> rightArrows = new HashMap<SubstanceTheme, Icon>();
081:
082: /*
083: * (non-Javadoc)
084: *
085: * @see javax.swing.plaf.ComponentUI#createUI(javax.swing.JComponent)
086: */
087: public static ComponentUI createUI(JComponent c) {
088: return new SubstanceChoicesSelectorUI();
089: }
090:
091: /*
092: * (non-Javadoc)
093: *
094: * @see org.jvnet.flamingo.bcb.ui.BasicChoicesSelectorUI#installListeners(org.jvnet.flamingo.bcb.ChoicesSelector)
095: */
096: @Override
097: protected void installListeners(final ChoicesSelector selector) {
098: super .installListeners(selector);
099: this .fadeMouseListener = new MouseAdapter() {
100: @Override
101: public void mouseEntered(MouseEvent e) {
102: FadeTracker.getInstance().trackFadeIn(
103: FadeKind.ROLLOVER, selector, false, null);
104: }
105:
106: @Override
107: public void mouseExited(MouseEvent e) {
108: FadeTracker.getInstance().trackFadeOut(
109: FadeKind.ROLLOVER, selector, false, null);
110: }
111: };
112: selector.addMouseListener(this .fadeMouseListener);
113: }
114:
115: /*
116: * (non-Javadoc)
117: *
118: * @see org.jvnet.flamingo.bcb.ui.BasicChoicesSelectorUI#uninstallListeners(org.jvnet.flamingo.bcb.ChoicesSelector)
119: */
120: @Override
121: protected void uninstallListeners(ChoicesSelector selector) {
122: selector.removeMouseListener(this .fadeMouseListener);
123: this .fadeMouseListener = null;
124: super .uninstallListeners(selector);
125: }
126:
127: /*
128: * (non-Javadoc)
129: *
130: * @see org.jvnet.flamingo.bcb.ui.BasicChoicesSelectorUI#paintBackground(java.awt.Graphics2D,
131: * javax.swing.JComponent, org.jvnet.flamingo.bcb.BreadcrumbParticle)
132: */
133: @Override
134: protected synchronized void paintBackground(Graphics2D graphics,
135: JComponent c, BreadcrumbParticle particle) {
136: Graphics2D g2 = (Graphics2D) graphics.create();
137: try {
138: ChoicesSelector selector = (ChoicesSelector) c;
139: ComponentState state = ComponentState.getState(selector
140: .getModel(), null);
141: ComponentState.ColorSchemeKind kind = state
142: .getColorSchemeKind();
143: // compute cycle count (for animation)
144: int cyclePos = state.getCycleCount();
145: // compute color scheme
146: ColorScheme colorScheme = null;
147: if (kind == ColorSchemeKind.DISABLED) {
148: colorScheme = SubstanceLookAndFeel
149: .getDisabledColorScheme();
150: } else {
151: if (kind == ColorSchemeKind.CURRENT) {
152: colorScheme = SubstanceLookAndFeel
153: .getActiveColorScheme();
154: } else {
155: colorScheme = SubstanceLookAndFeel
156: .getDefaultColorScheme();
157: }
158: }
159:
160: // colorScheme = state.isEnabled() ? SubstanceLookAndFeel.getTheme()
161: // .getColorScheme() : SubstanceLookAndFeel
162: // .getDisabledColorScheme();
163:
164: int width = c.getWidth();
165: int height = c.getHeight();
166: GeneralPath contour = BaseButtonShaper.getBaseOutline(
167: width, height, 0.0f, null);
168: SubstanceGradientPainter painter = SubstanceLookAndFeel
169: .getCurrentGradientPainter();
170: SubstanceBorderPainter borderPainter = SubstanceCoreUtilities
171: .getBorderPainter(selector);
172:
173: String key = width + ":" + height + ":" + kind.name() + ":"
174: + cyclePos + ":"
175: + SubstanceCoreUtilities.getSchemeId(colorScheme)
176: + ":" + painter.getDisplayName() + ":"
177: + borderPainter.getDisplayName() + ":" + particle;
178: if (!backgrounds.containsKey(key)) {
179: BufferedImage newBackground;
180:
181: newBackground = painter.getContourBackground(width,
182: height, contour, false, colorScheme,
183: colorScheme, cyclePos, true, false);
184: borderPainter.paintBorder(newBackground.getGraphics(),
185: c, width, height, contour, null, colorScheme,
186: colorScheme, cyclePos, false);
187:
188: backgrounds.put(key, newBackground);
189: }
190:
191: float comp = 0.8f;
192: BufferedImage background = backgrounds.get(key);
193: if (FadeTracker.getInstance().isTracked(selector,
194: FadeKind.ROLLOVER)
195: && !state.isKindActive(FadeKind.SELECTION)
196: && state.isKindActive(FadeKind.ENABLE)) {
197: float fadeCoef = FadeTracker.getInstance().getFade10(
198: selector, FadeKind.ROLLOVER);
199: g2.setComposite(AlphaComposite.getInstance(
200: AlphaComposite.SRC_OVER, comp * fadeCoef
201: / 10.0f));
202: } else {
203: if (state == ComponentState.DEFAULT)
204: return;
205: g2.setComposite(AlphaComposite.getInstance(
206: AlphaComposite.SRC_OVER, comp));
207: }
208: if (state != ComponentState.DISABLED_UNSELECTED)
209: g2.drawImage(background, 0, 0, null);
210: } finally {
211: g2.dispose();
212: }
213: }
214:
215: /*
216: * (non-Javadoc)
217: *
218: * @see org.jvnet.flamingo.bcb.ui.BasicChoicesSelectorUI#paintPressedState(java.awt.Graphics2D,
219: * javax.swing.JComponent)
220: */
221: @Override
222: protected synchronized void paintPressedState(Graphics2D graphics,
223: JComponent c) {
224: SubstanceTheme theme = SubstanceThemeUtilities.getTheme(null,
225: ComponentState.PRESSED_SELECTED);
226: if (!downArrows.containsKey(theme)) {
227: downArrows.put(theme, SubstanceImageCreator.getArrowIcon(c
228: .getWidth() - 6, 2 * c.getHeight() / 5,
229: SubstanceSizeUtils.getArrowStrokeWidth(c.getFont()
230: .getSize()), SwingConstants.SOUTH, theme));
231: }
232: downArrows.get(theme).paintIcon(c, graphics, 3,
233: 2 * c.getHeight() / 5);
234: }
235:
236: /*
237: * (non-Javadoc)
238: *
239: * @see org.jvnet.flamingo.bcb.ui.BasicChoicesSelectorUI#paintRegularState(java.awt.Graphics2D,
240: * javax.swing.JComponent)
241: */
242: @Override
243: protected synchronized void paintRegularState(Graphics2D graphics,
244: JComponent c) {
245: SubstanceTheme theme = SubstanceThemeUtilities.getTheme(null,
246: ComponentState.DEFAULT);
247: if (!rightArrows.containsKey(theme)) {
248: rightArrows.put(theme, SubstanceImageCreator.getArrowIcon(c
249: .getHeight() - 7, 2 * c.getWidth() / 5,
250: SubstanceSizeUtils.getArrowStrokeWidth(c.getFont()
251: .getSize()), SwingConstants.EAST, theme));
252: }
253: rightArrows.get(theme).paintIcon(c, graphics, c.getWidth() / 3,
254: 4);
255: }
256:
257: /*
258: * (non-Javadoc)
259: *
260: * @see org.jvnet.flamingo.bcb.ui.BasicChoicesSelectorUI#synchronizeWithParticle()
261: */
262: @Override
263: protected BreadcrumbParticle synchronizeWithParticle() {
264: BreadcrumbParticle particle = super .synchronizeWithParticle();
265: if (particle != null) {
266: ButtonModel model = particle.getModel();
267: boolean isFadeIn = model.isSelected() || model.isPressed()
268: || model.isArmed() || model.isRollover();
269: FadeTracker.getInstance().trackFade(particle,
270: FadeKind.ROLLOVER, isFadeIn, false, null);
271: }
272: return particle;
273: }
274: }
|