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.ribbon.ui;
031:
032: import java.awt.*;
033:
034: import javax.swing.*;
035: import javax.swing.border.Border;
036: import javax.swing.plaf.ComponentUI;
037: import javax.swing.plaf.basic.BasicHTML;
038: import javax.swing.text.View;
039:
040: import org.jvnet.flamingo.ribbon.ui.BasicToggleTabButtonUI;
041: import org.jvnet.lafwidget.animation.FadeStateListener;
042: import org.jvnet.substance.SubstanceLookAndFeel;
043: import org.jvnet.substance.flamingo.ribbon.RibbonBackgroundDelegate;
044: import org.jvnet.substance.painter.text.SubstanceTextPainter;
045: import org.jvnet.substance.utils.*;
046:
047: /**
048: * UI for toggle buttons of ribbon tasks in <b>Substance</b> look and feel.
049: *
050: * @author Kirill Grouchnikov
051: */
052: public class SubstanceToggleTabButtonUI extends BasicToggleTabButtonUI {
053: /**
054: * UI instance.
055: */
056: private static final SubstanceToggleTabButtonUI INSTANCE = new SubstanceToggleTabButtonUI();
057:
058: /**
059: * Color of disabled text.
060: */
061: protected Color disabledTextColor;
062:
063: /**
064: * Listener for fade state transitions.
065: */
066: protected FadeStateListener substanceFadeStateListener;
067:
068: /**
069: * The rollover button listener.
070: */
071: private RolloverButtonListener substanceButtonListener;
072:
073: /*
074: * (non-Javadoc)
075: *
076: * @see javax.swing.plaf.ComponentUI#createUI(javax.swing.JComponent)
077: */
078: public static ComponentUI createUI(JComponent b) {
079: ((AbstractButton) b).setRolloverEnabled(true);
080: return new SubstanceToggleTabButtonUI();
081: }
082:
083: /**
084: * Painting delegate.
085: */
086: private RibbonBackgroundDelegate delegate;
087:
088: /**
089: * Simple constructor.
090: */
091: public SubstanceToggleTabButtonUI() {
092: this .delegate = new RibbonBackgroundDelegate();
093: }
094:
095: /*
096: * (non-Javadoc)
097: *
098: * @see javax.swing.plaf.basic.BasicButtonUI#installDefaults(javax.swing.AbstractButton)
099: */
100: @Override
101: public void installDefaults(AbstractButton b) {
102: super .installDefaults(b);
103: b.setOpaque(false);
104: this .disabledTextColor = UIManager
105: .getColor("ToggleTabButton.disabledText");
106: b.setBorder(new Border() {
107: public Insets getBorderInsets(Component c) {
108: return new Insets(0, 6, 0, 6);
109: }
110:
111: public boolean isBorderOpaque() {
112: return false;
113: }
114:
115: public void paintBorder(Component c, Graphics g, int x,
116: int y, int width, int height) {
117: }
118: });
119: }
120:
121: /*
122: * (non-Javadoc)
123: *
124: * @see javax.swing.plaf.basic.BasicButtonUI#installListeners(javax.swing.AbstractButton)
125: */
126: @Override
127: protected void installListeners(AbstractButton b) {
128: super .installListeners(b);
129:
130: this .substanceButtonListener = new RolloverButtonListener(b);
131: b.addMouseListener(this .substanceButtonListener);
132: b.addMouseMotionListener(this .substanceButtonListener);
133: b.addFocusListener(this .substanceButtonListener);
134: b.addPropertyChangeListener(this .substanceButtonListener);
135: b.addChangeListener(this .substanceButtonListener);
136:
137: this .substanceFadeStateListener = new FadeStateListener(b, b
138: .getModel(), SubstanceCoreUtilities.getFadeCallback(b,
139: false));
140: this .substanceFadeStateListener.registerListeners();
141: }
142:
143: /*
144: * (non-Javadoc)
145: *
146: * @see javax.swing.plaf.basic.BasicButtonUI#uninstallListeners(javax.swing.AbstractButton)
147: */
148: @Override
149: protected void uninstallListeners(AbstractButton b) {
150: b.removeMouseListener(this .substanceButtonListener);
151: b.removeMouseMotionListener(this .substanceButtonListener);
152: b.removeFocusListener(this .substanceButtonListener);
153: b.removePropertyChangeListener(this .substanceButtonListener);
154: b.removeChangeListener(this .substanceButtonListener);
155: this .substanceButtonListener = null;
156:
157: this .substanceFadeStateListener.unregisterListeners();
158: this .substanceFadeStateListener = null;
159:
160: super .uninstallListeners(b);
161: }
162:
163: @Override
164: public void paint(Graphics g, JComponent c) {
165: final AbstractButton b = (AbstractButton) c;
166:
167: // trackGlowingIcon(button);
168: SubstanceTextPainter textPainter = SubstanceLookAndFeel
169: .getCurrentTextPainter();
170: textPainter.init(c, null, false);
171: if (textPainter.needsBackgroundImage()) {
172: // TODO : check correct alpha for flat buttons and translucent
173: // themes
174: textPainter.setBackgroundFill(b, b.getParent()
175: .getBackground(), true, 0, 0);
176: textPainter
177: .attachCallback(new SubstanceTextPainter.BackgroundPaintingCallback() {
178: public void paintBackground(Graphics g) {
179: delegate.updateBackground(g, b, 0);
180: };
181: });
182: } else {
183: this .delegate.updateBackground(g, b, 0);
184: }
185:
186: FontMetrics fm = g.getFontMetrics();
187:
188: Insets i = c.getInsets();
189:
190: Rectangle viewRect = new Rectangle();
191: Rectangle iconRect = new Rectangle();
192: Rectangle textRect = new Rectangle();
193:
194: viewRect.x = i.left;
195: viewRect.y = i.top;
196: viewRect.width = b.getWidth() - (i.right + viewRect.x);
197: viewRect.height = b.getHeight() - (i.bottom + viewRect.y);
198:
199: textRect.x = textRect.y = textRect.width = textRect.height = 0;
200: iconRect.x = iconRect.y = iconRect.width = iconRect.height = 0;
201:
202: Font f = c.getFont();
203: g.setFont(f);
204:
205: // layout the text and icon
206: String text = SwingUtilities.layoutCompoundLabel(c, fm, b
207: .getText(), b.getIcon(), b.getVerticalAlignment(), b
208: .getHorizontalAlignment(), b.getVerticalTextPosition(),
209: b.getHorizontalTextPosition(), viewRect, iconRect,
210: textRect, b.getText() == null ? 0 : b.getIconTextGap());
211:
212: if (text != null && !text.equals("")) {
213: View v = (View) c.getClientProperty(BasicHTML.propertyKey);
214: if (v != null) {
215: v.paint(g, textRect);
216: } else {
217: paintText(g, b, textRect, text);
218: }
219: }
220: textPainter.renderSurface(g);
221: //
222: //
223: // this.paint(g, c);
224: }
225:
226: /*
227: * (non-Javadoc)
228: *
229: * @see org.jvnet.flamingo.ribbon.ui.BasicToggleTabButtonUI#update(java.awt.Graphics,
230: * javax.swing.JComponent)
231: */
232: @Override
233: public void update(Graphics g, JComponent c) {
234: this .paint(g, c);
235: }
236:
237: /*
238: * (non-Javadoc)
239: *
240: * @see javax.swing.plaf.basic.BasicButtonUI#paintFocus(java.awt.Graphics,
241: * javax.swing.AbstractButton, java.awt.Rectangle, java.awt.Rectangle,
242: * java.awt.Rectangle)
243: */
244: @Override
245: protected void paintFocus(Graphics g, AbstractButton b,
246: Rectangle viewRect, Rectangle textRect, Rectangle iconRect) {
247: // overriden to remove default metal effect
248: }
249:
250: /*
251: * (non-Javadoc)
252: *
253: * @see javax.swing.plaf.basic.BasicButtonUI#paintButtonPressed(java.awt.Graphics,
254: * javax.swing.AbstractButton)
255: */
256: @Override
257: protected void paintButtonPressed(Graphics g, AbstractButton b) {
258: // overriden to remove default metal effect
259: }
260:
261: /*
262: * (non-Javadoc)
263: *
264: * @see javax.swing.plaf.basic.BasicButtonUI#paintText(java.awt.Graphics,
265: * javax.swing.JComponent, java.awt.Rectangle, java.lang.String)
266: */
267: @Override
268: protected void paintText(Graphics g, JComponent c,
269: Rectangle textRect, String text) {
270: SubstanceCoreUtilities.paintText((AbstractButton) c, textRect,
271: text, ((AbstractButton) c).getDisplayedMnemonicIndex());
272: }
273:
274: /*
275: * (non-Javadoc)
276: *
277: * @see javax.swing.plaf.ComponentUI#getPreferredSize(javax.swing.JComponent)
278: */
279: @Override
280: public Dimension getPreferredSize(JComponent c) {
281: Dimension result;
282: boolean toTweakWidth = false;
283: boolean toTweakHeight = false;
284: AbstractButton button = (AbstractButton) c;
285:
286: Icon icon = button.getIcon();
287: boolean hasIcon = SubstanceCoreUtilities.hasIcon(button);
288: boolean hasText = SubstanceCoreUtilities.hasText(button);
289:
290: Dimension baseDimension = super .getPreferredSize(c);
291: result = baseDimension;
292:
293: if (hasText) {
294: int baseWidth = baseDimension.width;
295: baseWidth = Math.max(baseWidth, SubstanceSizeUtils
296: .getMinButtonWidth(button.getFont().getSize()));
297: result = new Dimension(baseWidth, baseDimension.height);
298: int baseHeight = result.height;
299: baseHeight = Math.max(baseHeight, SubstanceSizeUtils
300: .getMinButtonHeight(button.getFont().getSize()));
301: result = new Dimension(result.width, baseHeight);
302: }
303:
304: if (hasIcon) {
305: // check the icon height
306: int iconHeight = icon.getIconHeight();
307: if (iconHeight > (result.getHeight() - 6)) {
308: result = new Dimension(result.width, iconHeight);
309: toTweakHeight = true;
310: }
311: int iconWidth = icon.getIconWidth();
312: if (iconWidth > (result.getWidth() - 6)) {
313: result = new Dimension(iconWidth, result.height);
314: toTweakWidth = true;
315: }
316: }
317:
318: if (toTweakWidth) {
319: result = new Dimension(result.width + 6, result.height);
320: }
321: if (toTweakHeight) {
322: result = new Dimension(result.width, result.height + 6);
323: }
324:
325: return result;
326: }
327: }
|