2
* Copyright (c) 2005-2010 Substance Kirill Grouchnikov. All Rights Reserved.
4
* Redistribution and use in source and binary forms, with or without
5
* modification, are permitted provided that the following conditions are met:
7
* o Redistributions of source code must retain the above copyright notice,
8
* this list of conditions and the following disclaimer.
10
* o Redistributions in binary form must reproduce the above copyright notice,
11
* this list of conditions and the following disclaimer in the documentation
12
* and/or other materials provided with the distribution.
14
* o Neither the name of Substance Kirill Grouchnikov nor the names of
15
* its contributors may be used to endorse or promote products derived
16
* from this software without specific prior written permission.
18
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
27
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
28
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
package org.pushingpixels.substance.api;
33
import java.awt.geom.GeneralPath;
37
import org.pushingpixels.substance.api.shaper.SubstanceButtonShaper;
38
import org.pushingpixels.substance.internal.animation.TransitionAwareUI;
39
import org.pushingpixels.substance.internal.utils.*;
42
* <b>Substance</b> constants.
44
* @author Kirill Grouchnikov
46
public class SubstanceConstants {
48
* Enumerates available sides.
50
* @author Kirill Grouchnikov
51
* @see SubstanceLookAndFeel#BUTTON_OPEN_SIDE_PROPERTY
52
* @see SubstanceLookAndFeel#BUTTON_SIDE_PROPERTY
54
public static enum Side {
77
* Enumerates focus indication kinds.
79
* @author Kirill Grouchnikov
80
* @see SubstanceLookAndFeel#FOCUS_KIND
82
public enum FocusKind {
84
* No focus indication.
88
public void paintFocus(Component mainComp, Component focusedComp,
89
TransitionAwareUI transitionAwareUI, Graphics2D graphics,
90
Shape focusShape, Rectangle textRect, int extraPadding) {
95
* Focus indication around the text.
99
public void paintFocus(Component mainComp, Component focusedComp,
100
TransitionAwareUI transitionAwareUI, Graphics2D graphics,
101
Shape focusShape, Rectangle textRect, int extraPadding) {
102
if (textRect == null)
104
if ((textRect.width == 0) || (textRect.height == 0))
107
int fontSize = SubstanceSizeUtils
108
.getComponentFontSize(mainComp);
109
float dashLength = getDashLength(fontSize);
110
float dashGap = getDashGap(fontSize);
111
float dashPhase = (dashLength + dashGap)
112
* (1.0f - transitionAwareUI.getTransitionTracker()
113
.getFocusLoopPosition());
115
graphics.setStroke(new BasicStroke(SubstanceSizeUtils
116
.getFocusStrokeWidth(fontSize), BasicStroke.CAP_BUTT,
117
BasicStroke.JOIN_ROUND, 0.0f, new float[] { dashLength,
118
dashGap }, dashPhase));
120
int delta = ((mainComp instanceof JComboBox) || (mainComp instanceof JSpinner)) ? 0
122
GeneralPath contour = SubstanceOutlineUtilities.getBaseOutline(
123
textRect.width + 2 * delta, textRect.height,
125
.getClassicButtonCornerRadius(fontSize), null);
127
graphics.translate(textRect.x - delta, textRect.y);
128
graphics.draw(contour);
135
* org.pushingpixels.substance.utils.SubstanceConstants.FocusKind
139
public boolean isAnimated() {
145
* Focus indication around the whole component.
149
public void paintFocus(Component mainComp, Component focusedComp,
150
TransitionAwareUI transitionAwareUI, Graphics2D graphics,
151
Shape focusShape, Rectangle textRect, int extraPadding) {
152
if ((focusShape == null)
153
&& ((mainComp instanceof AbstractButton)
154
&& !(mainComp instanceof JCheckBox) && !(mainComp instanceof JRadioButton))) {
155
SubstanceButtonShaper shaper = SubstanceCoreUtilities
156
.getButtonShaper(mainComp);
160
int fontSize = SubstanceSizeUtils
161
.getComponentFontSize(mainComp);
162
float dashLength = getDashLength(fontSize);
163
float dashGap = getDashGap(fontSize);
164
float dashPhase = (dashLength + dashGap)
165
* (1.0f - transitionAwareUI.getTransitionTracker()
166
.getFocusLoopPosition());
167
graphics.setStroke(new BasicStroke(SubstanceSizeUtils
168
.getFocusStrokeWidth(fontSize),
169
BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND, 0.0f,
170
new float[] { dashLength, dashGap }, dashPhase));
172
Shape contour = shaper.getButtonOutline(
173
(AbstractButton) mainComp, null, mainComp
174
.getWidth(), mainComp.getHeight(), false);
175
graphics.draw(contour);
178
// graphics.translate(textRect.x - 1, textRect.y - 1);
179
graphics.translate(1, 1);
180
Shape contour = (focusShape != null) ? focusShape
181
: SubstanceOutlineUtilities
183
mainComp.getWidth() - 2,
184
mainComp.getHeight() - 2,
186
.getClassicButtonCornerRadius(SubstanceSizeUtils
187
.getComponentFontSize(mainComp)),
190
int fontSize = SubstanceSizeUtils
191
.getComponentFontSize(mainComp);
192
float dashLength = getDashLength(fontSize);
193
float dashGap = getDashGap(fontSize);
194
float dashPhase = (dashLength + dashGap)
195
* (1.0f - transitionAwareUI.getTransitionTracker()
196
.getFocusLoopPosition());
197
graphics.setStroke(new BasicStroke(SubstanceSizeUtils
198
.getFocusStrokeWidth(fontSize),
199
BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND, 0.0f,
200
new float[] { dashLength, dashGap }, dashPhase));
201
graphics.draw(contour);
209
* org.pushingpixels.substance.utils.SubstanceConstants.FocusKind
213
public boolean isAnimated() {
219
* Focus indication around the whole component, but moved 1 pixel inside
224
public void paintFocus(Component mainComp, Component focusedComp,
225
TransitionAwareUI transitionAwareUI, Graphics2D graphics,
226
Shape focusShape, Rectangle textRect, int extraPadding) {
228
if ((focusShape == null)
229
&& ((mainComp instanceof AbstractButton)
230
&& !(mainComp instanceof JCheckBox) && !(mainComp instanceof JRadioButton))) {
231
SubstanceButtonShaper shaper = SubstanceCoreUtilities
232
.getButtonShaper(mainComp);
236
if (shaper.isProportionate()) {
237
int fontSize = SubstanceSizeUtils
238
.getComponentFontSize(mainComp);
239
float dashLength = getDashLength(fontSize);
240
float dashGap = getDashGap(fontSize);
241
float dashPhase = (dashLength + dashGap)
242
* (1.0f - transitionAwareUI
243
.getTransitionTracker()
244
.getFocusLoopPosition());
245
float focusStrokeWidth = SubstanceSizeUtils
246
.getFocusStrokeWidth(fontSize);
247
graphics.setStroke(new BasicStroke(focusStrokeWidth,
248
BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND,
249
0.0f, new float[] { dashLength, dashGap },
251
int insetsPix = extraPadding;
252
Insets insets = new Insets(insetsPix, insetsPix,
253
insetsPix, insetsPix);
255
Shape contour = shaper.getButtonOutline(
256
(AbstractButton) mainComp, insets, mainComp
257
.getWidth(), mainComp.getHeight(),
259
graphics.draw(contour);
262
graphics.translate(extraPadding / 2, extraPadding / 2);
263
int fontSize = SubstanceSizeUtils
264
.getComponentFontSize(mainComp);
265
Shape contour = (focusShape != null) ? focusShape
266
: SubstanceOutlineUtilities.getBaseOutline(mainComp
268
- extraPadding, mainComp.getHeight()
269
- extraPadding, SubstanceSizeUtils
270
.getClassicButtonCornerRadius(fontSize),
273
float dashLength = getDashLength(fontSize);
274
float dashGap = getDashGap(fontSize);
275
float dashPhase = (dashLength + dashGap)
276
* (1.0f - transitionAwareUI.getTransitionTracker()
277
.getFocusLoopPosition());
279
graphics.setStroke(new BasicStroke(SubstanceSizeUtils
280
.getFocusStrokeWidth(fontSize),
281
BasicStroke.CAP_BUTT, BasicStroke.JOIN_ROUND, 0.0f,
282
new float[] { dashLength, dashGap }, dashPhase));
283
graphics.draw(contour);
291
* org.pushingpixels.substance.utils.SubstanceConstants.FocusKind
295
public boolean isAnimated() {
301
* Focus indication around the whole component, but moved 1 pixel inside
306
public void paintFocus(Component mainComp, Component focusedComp,
307
TransitionAwareUI transitionAwareUI, Graphics2D graphics,
308
Shape focusShape, Rectangle textRect, int extraPadding) {
309
if ((focusShape == null)
310
&& ((mainComp instanceof AbstractButton)
311
&& !(mainComp instanceof JCheckBox) && !(mainComp instanceof JRadioButton))) {
312
SubstanceButtonShaper shaper = SubstanceCoreUtilities
313
.getButtonShaper(mainComp);
317
if (shaper.isProportionate()) {
318
Insets insets = new Insets(extraPadding, extraPadding,
319
extraPadding, extraPadding);
321
Shape contour = shaper.getButtonOutline(
322
(AbstractButton) mainComp, insets, mainComp
323
.getWidth(), mainComp.getHeight(),
325
graphics.draw(contour);
328
graphics.translate(extraPadding / 2, extraPadding / 2);
329
Shape contour = (focusShape != null) ? focusShape
330
: SubstanceOutlineUtilities
332
mainComp.getWidth() - extraPadding,
333
mainComp.getHeight() - extraPadding,
335
.getClassicButtonCornerRadius(SubstanceSizeUtils
336
.getComponentFontSize(mainComp)),
339
graphics.draw(contour);
345
* Focus indication under the component text.
349
public void paintFocus(Component mainComp, Component focusedComp,
350
TransitionAwareUI transitionAwareUI, Graphics2D graphics,
351
Shape focusShape, Rectangle textRect, int extraPadding) {
352
if (textRect == null)
355
int fontSize = SubstanceSizeUtils
356
.getComponentFontSize(mainComp);
357
float dashLength = getDashLength(fontSize);
358
float dashGap = getDashGap(fontSize);
359
float dashPhase = (dashLength + dashGap)
360
* (1.0f - transitionAwareUI.getTransitionTracker()
361
.getFocusLoopPosition());
363
graphics.setStroke(new BasicStroke(SubstanceSizeUtils
364
.getFocusStrokeWidth(fontSize), BasicStroke.CAP_BUTT,
365
BasicStroke.JOIN_ROUND, 0.0f, new float[] { dashLength,
366
dashGap }, dashPhase));
368
graphics.translate(textRect.x - 1, textRect.y);
369
graphics.drawLine(0, textRect.height - 1, textRect.width,
370
textRect.height - 1);
378
* org.pushingpixels.substance.utils.SubstanceConstants.FocusKind
382
public boolean isAnimated() {
388
* Strong focus indication under the component text.
392
public void paintFocus(Component mainComp, Component focusedComp,
393
TransitionAwareUI transitionAwareUI, Graphics2D graphics,
394
Shape focusShape, Rectangle textRect, int extraPadding) {
395
if (textRect == null)
398
graphics.translate(textRect.x - 1, textRect.y);
399
graphics.drawLine(0, textRect.height - 1, textRect.width,
400
textRect.height - 1);
405
* Paints the focus ring on the specified component.
408
* The main component for the focus painting.
410
* The actual component that has the focus. For example, the
411
* main component can be a {@link JSpinner}, while the
412
* focused component is a text field inside the the spinner
417
* Focus shape. May be <code>null</code> - in this case, the
418
* bounds of <code>mainComp</code> will be used.
420
* Text rectangle (if relevant).
421
* @param extraPadding
422
* Extra padding between the component bounds and the focus
425
public abstract void paintFocus(Component mainComp,
426
Component focusedComp, TransitionAwareUI transitionAwareUI,
427
Graphics2D graphics, Shape focusShape, Rectangle textRect,
431
* Returns DPI-aware dash length for dash-based focus painting.
434
* The font size of the component for focus painting.
435
* @return DPI-aware dash length for dash-based focus painting.
437
protected static float getDashLength(int fontSize) {
438
return 2.0f + SubstanceSizeUtils.getExtraPadding(fontSize);
442
* Returns DPI-aware dash gap for dash-based focus painting.
445
* The font size of the component for focus painting.
446
* @return DPI-aware dash gap for dash-based focus painting.
448
protected static float getDashGap(int fontSize) {
449
return getDashLength(fontSize) / 2.0f;
453
* Returns indication whether <code>this</code> focus kind can be
454
* animated. For example, focus rings painted with solid lines are
457
* @return <code>true</code> if <code>this</code> focus kind can be
458
* animated, <code>false</code> otherwise.
460
public boolean isAnimated() {
466
* Enumerates of image-based watermarks kinds.
468
* @author Kirill Grouchnikov
469
* @see org.pushingpixels.substance.api.watermark.SubstanceImageWatermark#setKind(org.pushingpixels.substance.api.SubstanceConstants.ImageWatermarkKind)
470
* @see org.pushingpixels.substance.api.watermark.SubstanceImageWatermark#getKind()
472
public enum ImageWatermarkKind {
474
* The default behaviour. The image is centered in the screen and scaled
480
* The image is tiled starting from the screen top-left corner and not
486
* The image is anchored to the top-left corner of the application frame
492
* The image is anchored to the center of the application frame and not
498
* The image is tiled starting from the top-left corner of the
499
* application frame and not scaled.
505
* Enumerates possible modes of closing tabs.
507
* @author Kirill Grouchnikov
508
* @see SubstanceLookAndFeel#TABBED_PANE_CLOSE_CALLBACK
510
public enum TabCloseKind {
512
* Indicates that no tabs should be closed.
517
* Indicates that the specified tab should be closed.
522
* Indicates that all tabs should be closed.
527
* Indicates that all tabs except the specified should be closed.
533
* Enumerates possible button policies for scroll panes.
535
* @author Kirill Grouchnikov
536
* @see SubstanceLookAndFeel#SCROLL_PANE_BUTTONS_POLICY
538
public enum ScrollPaneButtonPolicyKind {
540
* The <code>empty</code> button policy - no buttons.
545
* The <code>opposite</code> (default) button policy - the decrease
546
* button is on one side of the scroll bar, and the increase button is
547
* on the other side of the scroll bar.
552
* The <code>adjacent</code> button policy - both the decrease button
553
* and the increase button are on the same side of the scroll bar
554
* adjacent to each other (like on Mac).
559
* The <code>multiple</code> button policy - there are two decrease
560
* buttons on the opposite side of the scroll bar and the increase
561
* button is adjacent to the second decrease button. This combines the
562
* {@link #OPPOSITE} and the {@link #ADJACENT} policies together.
567
* The <code>multiple both</code> button policy - there are two pairs of
568
* decrease-increase buttons on the opposite sides of the scroll bar.
569
* This extends the {@link #MULTIPLE} policy.
575
* Enumerates possible values for menu gutter fill kind.
577
* @author Kirill Grouchnikov
578
* @see SubstanceLookAndFeel#MENU_GUTTER_FILL_KIND
580
public enum MenuGutterFillKind {
582
* The <code>none</code> fill kind - draws no background in the menu
588
* The <code>soft fill</code> fill kind - draws light fill background in
594
* The <code>hard fill</code> fill kind - draws darker fill background
595
* in the menu gutter.
600
* The <code>soft</code> fill kind - draws gradient ranging from darker
601
* to light in the menu gutter.
606
* The <code>hard</code> (default) fill kind - draws gradient ranging
607
* from darker to light in the menu gutter.
613
* Tab content pane border kind.
615
* @author Kirill Grouchnikov
618
public enum TabContentPaneBorderKind {
620
* The content pane has full border on all sides plus an additional line
621
* along the tab placement side (as in Firefox 2.0, Internet Explorer
622
* 7.0 and Nimbus). This is the default kind starting from version 4.1.
627
* The content pane has full single border on all sides. This has been
628
* the default kind prior to version 4.1.
633
* The content pane has double border along the tab placement side.
638
* The content pane has single border along the tab placement side.
644
* Enumerates configurable Substance-specific widget types for
645
* {@link SubstanceLookAndFeel#setWidgetVisible(javax.swing.JRootPane, boolean, org.pushingpixels.substance.api.SubstanceConstants.SubstanceWidgetType...)}
648
* @author Kirill Grouchnikov
650
public enum SubstanceWidgetType {
652
* Menu search widget.
657
* Title pane heap status widget.
659
TITLE_PANE_HEAP_STATUS