001: /*
002: * Copyright (c) 2005-2008 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 Substance 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.shaperpack.button;
031:
032: import java.awt.*;
033: import java.awt.geom.GeneralPath;
034: import java.io.InputStream;
035:
036: import javax.swing.AbstractButton;
037: import javax.swing.border.Border;
038:
039: import org.jvnet.substance.SubstanceButtonBorder;
040: import org.jvnet.substance.SubstanceButtonUI;
041: import org.jvnet.substance.button.BaseButtonShaper;
042: import org.jvnet.substance.shaperpack.CanonicalPath;
043: import org.jvnet.substance.shaperpack.ShaperRepository;
044: import org.jvnet.substance.utils.SubstanceCoreUtilities;
045:
046: public abstract class BasePolygonShaper extends BaseButtonShaper {
047: protected CanonicalPath canonicalPath;
048:
049: protected double topCoef;
050:
051: protected double leftCoef;
052:
053: protected double bottomCoef;
054:
055: protected double rightCoef;
056:
057: public BasePolygonShaper(String resourceName, double topCoef,
058: double leftCoef, double bottomCoef, double rightCoef) {
059: this .topCoef = topCoef;
060: this .leftCoef = leftCoef;
061: this .bottomCoef = bottomCoef;
062: this .rightCoef = rightCoef;
063:
064: ClassLoader cl = BasePolygonShaper.class.getClassLoader();
065: InputStream is = cl.getResourceAsStream(resourceName);
066: if (is == null) {
067: throw new IllegalArgumentException("Resource '"
068: + resourceName + "' not found");
069: }
070: this .canonicalPath = ShaperRepository.read(is);
071: }
072:
073: public Dimension getPreferredSize(AbstractButton button,
074: Dimension uiPreferredSize) {
075: if (button.getClientProperty(SubstanceButtonUI.BORDER_COMPUTED) == null) {
076: boolean isBorderComputing = (button
077: .getClientProperty(SubstanceButtonUI.BORDER_COMPUTING) != null);
078: Border border = button.getBorder();
079: int uiw = uiPreferredSize.width;
080: int uih = uiPreferredSize.height;
081: if (border instanceof SubstanceButtonBorder) {
082: // SubstanceButtonBorder sborder = (SubstanceButtonBorder)
083: // button
084: // .getBorder();
085: // if (sborder.getButtonShaperClass() != this.getClass()) {
086: Insets bi = border.getBorderInsets(button);
087: if (!isBorderComputing)
088: button.setBorder(null);
089: uiPreferredSize.setSize(uiw - bi.left - bi.right, uih
090: - bi.top - bi.bottom);
091: // }
092: } else {
093: Insets bi = border.getBorderInsets(button);
094: if (!isBorderComputing)
095: button.setBorder(null);
096: uiPreferredSize.setSize(uiw - bi.left - bi.right, uih
097: - bi.top - bi.bottom);
098: }
099: if (!isBorderComputing) {
100: button.setBorder(this .getButtonBorder(button,
101: uiPreferredSize));
102: button
103: .putClientProperty(
104: SubstanceButtonUI.BORDER_COMPUTED,
105: new String());
106: }
107: }
108: return uiPreferredSize;
109: }
110:
111: public Border getButtonBorder(AbstractButton button) {
112: return new SubstanceButtonBorder(this .getClass()) {
113: public Insets getBorderInsets(Component c) {
114: if (c instanceof AbstractButton) {
115: AbstractButton button = (AbstractButton) c;
116: if (SubstanceCoreUtilities.hasText(button)) {
117: if (button
118: .getClientProperty(SubstanceButtonUI.BORDER_COMPUTING) != null)
119: return new Insets(0, 0, 0, 0);
120: button.putClientProperty(
121: SubstanceButtonUI.BORDER_COMPUTING,
122: new String());
123: int width = button.getPreferredSize().width;
124: int height = button.getPreferredSize().height;
125: button.putClientProperty(
126: SubstanceButtonUI.BORDER_COMPUTING,
127: null);
128: double finalWidth = width
129: * (1.0 + leftCoef + rightCoef);
130: double finalHeight = height
131: * (1.0 + topCoef + bottomCoef);
132: double finalRatio = finalWidth / finalHeight;
133: int dx = 0;
134: int dy = 0;
135: if (finalRatio > canonicalPath.getRatio()) {
136: // need dy
137: dy = (int) (finalWidth
138: / canonicalPath.getRatio() - finalHeight);
139: } else {
140: // need dx
141: dx = (int) (canonicalPath.getRatio()
142: * finalHeight - finalWidth);
143: }
144: return new Insets((int) (topCoef * height) + dy
145: / 2, (int) (leftCoef * width) + dx / 2,
146: (int) (bottomCoef * height) + dy / 2,
147: (int) (rightCoef * width) + dx / 2);
148: }
149: }
150: return new Insets(0, 0, 0, 0);
151: }
152: };
153: }
154:
155: public Border getButtonBorder(AbstractButton button,
156: final Dimension preferredSize) {
157: return new SubstanceButtonBorder(this .getClass()) {
158: public Insets getBorderInsets(Component c) {
159: if (c instanceof AbstractButton) {
160: AbstractButton button = (AbstractButton) c;
161: if (SubstanceCoreUtilities.hasText(button)) {
162: int width = preferredSize.width;
163: int height = preferredSize.height;
164: double finalWidth = width
165: * (1.0 + leftCoef + rightCoef);
166: double finalHeight = height
167: * (1.0 + topCoef + bottomCoef);
168: double finalRatio = finalWidth / finalHeight;
169: int dx = 0;
170: int dy = 0;
171: if (finalRatio > canonicalPath.getRatio()) {
172: // need dy
173: dy = (int) (finalWidth
174: / canonicalPath.getRatio() - finalHeight);
175: } else {
176: // need dx
177: dx = (int) (canonicalPath.getRatio()
178: * finalHeight - finalWidth);
179: }
180: return new Insets((int) (topCoef * height) + dy
181: / 2, (int) (leftCoef * width) + dx / 2,
182: (int) (bottomCoef * height) + dy / 2,
183: (int) (rightCoef * width) + dx / 2);
184: }
185: }
186: return new Insets(0, 0, 0, 0);
187: }
188: };
189: }
190:
191: public GeneralPath getButtonOutline(AbstractButton button) {
192: return getButtonOutline(button, null);
193: }
194:
195: /*
196: * (non-Javadoc)
197: *
198: * @see org.jvnet.substance.button.BaseButtonShaper#getButtonOutline(javax.swing.AbstractButton,
199: * java.awt.Insets)
200: */
201: public GeneralPath getButtonOutline(AbstractButton button,
202: Insets insets) {
203: int width = button.getWidth();
204: int height = button.getHeight();
205: return this .getButtonOutline(button, insets, width, height);
206: }
207:
208: /*
209: * (non-Javadoc)
210: *
211: * @see org.jvnet.substance.button.SubstanceButtonShaper#getButtonOutline(javax.swing.AbstractButton,
212: * java.awt.Insets, int, int)
213: */
214: public GeneralPath getButtonOutline(AbstractButton button,
215: Insets insets, int width, int height) {
216: if (SubstanceCoreUtilities.hasText(button))
217: return this .canonicalPath.getPath(width, height, insets);
218:
219: return super .getBaseOutline(width, height, 2, null, insets);
220: }
221:
222: /*
223: * (non-Javadoc)
224: *
225: * @see org.jvnet.substance.button.SubstanceButtonShaper#isProportionate()
226: */
227: public boolean isProportionate() {
228: return false;
229: }
230: }
|