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.skin;
32
import java.awt.Color;
34
import org.pushingpixels.substance.api.*;
35
import org.pushingpixels.substance.api.painter.border.ClassicBorderPainter;
36
import org.pushingpixels.substance.api.painter.border.CompositeBorderPainter;
37
import org.pushingpixels.substance.api.painter.border.DelegateFractionBasedBorderPainter;
38
import org.pushingpixels.substance.api.painter.border.FractionBasedBorderPainter;
39
import org.pushingpixels.substance.api.painter.border.SubstanceBorderPainter;
40
import org.pushingpixels.substance.api.painter.decoration.MatteDecorationPainter;
41
import org.pushingpixels.substance.api.painter.fill.FractionBasedFillPainter;
42
import org.pushingpixels.substance.api.painter.highlight.ClassicHighlightPainter;
43
import org.pushingpixels.substance.api.painter.overlay.BottomLineOverlayPainter;
44
import org.pushingpixels.substance.api.painter.overlay.BottomShadowOverlayPainter;
45
import org.pushingpixels.substance.api.painter.overlay.TopBezelOverlayPainter;
46
import org.pushingpixels.substance.api.painter.overlay.TopLineOverlayPainter;
47
import org.pushingpixels.substance.api.shaper.ClassicButtonShaper;
50
* <code>Gemini</code> skin. This class is part of officially supported API.
52
* @author Kirill Grouchnikov
55
public class GeminiSkin extends SubstanceSkin {
57
* Display name for <code>this</code> skin.
59
public static final String NAME = "Gemini";
62
* Overlay painter to paint a dark line along the bottom edge of the
65
private BottomLineOverlayPainter menuOverlayPainter;
68
* Overlay painter to paint a light line along the top edge of the toolbars.
70
private TopLineOverlayPainter toolbarOverlayPainter;
73
* Overlay painter to paint a dark line along the bottom edge of the
76
private BottomLineOverlayPainter toolbarBottomLineOverlayPainter;
79
* Overlay painter to paint a bezel line along the top edge of the footer.
81
private TopBezelOverlayPainter footerTopBezelOverlayPainter;
84
* Creates a new <code>Gemini</code> skin.
87
SubstanceSkin.ColorSchemes schemes = SubstanceSkin
88
.getColorSchemes("org/pushingpixels/substance/api/skin/gemini.colorschemes");
90
SubstanceColorScheme grayScheme = schemes.get("Gemini Gray");
91
SubstanceColorScheme lightGrayScheme = schemes.get("Gemini Light Gray");
93
// use the same color scheme for active and enabled controls
94
SubstanceColorSchemeBundle defaultSchemeBundle = new SubstanceColorSchemeBundle(
95
grayScheme, grayScheme, lightGrayScheme);
97
// highlight fill scheme + custom alpha for rollover unselected state
98
SubstanceColorScheme highlightScheme = schemes.get("Gemini Highlight");
99
SubstanceColorScheme highlightBorderScheme = schemes
100
.get("Gemini Highlight Border");
101
applyHighlightColorScheme(defaultSchemeBundle, highlightScheme,
102
highlightBorderScheme);
104
// borders, separators, marks
105
SubstanceColorScheme grayBorderScheme = schemes
106
.get("Gemini Gray Border");
107
SubstanceColorScheme lightGrayBorderScheme = schemes
108
.get("Gemini Light Gray Border");
109
SubstanceColorScheme lightGraySeparatorScheme = schemes
110
.get("Gemini Light Gray Separator");
111
defaultSchemeBundle.registerColorScheme(grayBorderScheme,
112
ColorSchemeAssociationKind.BORDER);
113
defaultSchemeBundle.registerColorScheme(lightGrayBorderScheme,
114
ColorSchemeAssociationKind.BORDER,
115
ComponentState.DISABLED_DEFAULT,
116
ComponentState.DISABLED_SELECTED,
117
ComponentState.DISABLED_UNSELECTED);
118
defaultSchemeBundle.registerColorScheme(grayScheme,
119
ComponentState.ROLLOVER_UNSELECTED);
120
defaultSchemeBundle.registerColorScheme(lightGraySeparatorScheme,
121
ColorSchemeAssociationKind.SEPARATOR);
122
defaultSchemeBundle.registerColorScheme(grayScheme,
123
ColorSchemeAssociationKind.MARK);
125
defaultSchemeBundle.registerColorScheme(lightGrayScheme, 0.5f,
126
ComponentState.DISABLED_UNSELECTED);
127
defaultSchemeBundle.registerColorScheme(lightGrayScheme, 0.7f,
128
ComponentState.DISABLED_SELECTED);
130
SubstanceColorScheme whiteBackgroundScheme = schemes
131
.get("Gemini White Background");
133
this.registerDecorationAreaSchemeBundle(defaultSchemeBundle,
134
whiteBackgroundScheme, DecorationAreaType.NONE);
136
// general color scheme bundle
137
SubstanceColorSchemeBundle generalSchemeBundle = new SubstanceColorSchemeBundle(
138
grayScheme, grayScheme, lightGrayScheme);
139
generalSchemeBundle.registerColorScheme(grayScheme,
140
ComponentState.ROLLOVER_UNSELECTED);
141
generalSchemeBundle.registerColorScheme(grayScheme,
142
ColorSchemeAssociationKind.MARK);
143
generalSchemeBundle.registerColorScheme(grayBorderScheme,
144
ColorSchemeAssociationKind.BORDER);
145
applyHighlightColorScheme(generalSchemeBundle, highlightScheme,
146
highlightBorderScheme);
147
this.registerDecorationAreaSchemeBundle(generalSchemeBundle,
148
grayScheme, DecorationAreaType.GENERAL,
149
DecorationAreaType.FOOTER);
151
// header color scheme bundle
152
SubstanceColorScheme blackColorScheme = schemes.get("Gemini Black");
153
SubstanceColorSchemeBundle headerSchemeBundle = new SubstanceColorSchemeBundle(
154
blackColorScheme, blackColorScheme, blackColorScheme);
155
headerSchemeBundle.registerColorScheme(blackColorScheme, 0.5f,
156
ComponentState.DISABLED_SELECTED,
157
ComponentState.DISABLED_UNSELECTED);
158
headerSchemeBundle.registerColorScheme(blackColorScheme,
159
ComponentState.ROLLOVER_UNSELECTED);
160
headerSchemeBundle.registerColorScheme(blackColorScheme,
161
ColorSchemeAssociationKind.MARK);
162
headerSchemeBundle.registerColorScheme(blackColorScheme,
163
ColorSchemeAssociationKind.BORDER);
164
applyHighlightColorScheme(headerSchemeBundle, highlightScheme,
165
highlightBorderScheme);
166
this.registerDecorationAreaSchemeBundle(headerSchemeBundle,
167
blackColorScheme, DecorationAreaType.PRIMARY_TITLE_PANE,
168
DecorationAreaType.SECONDARY_TITLE_PANE,
169
DecorationAreaType.HEADER);
171
// toolbar color scheme bundle
172
SubstanceColorScheme darkBlueColorScheme = schemes
173
.get("Gemini Dark Blue");
174
SubstanceColorScheme darkBlueBackgroundColorScheme = schemes
175
.get("Gemini Dark Blue Background");
176
SubstanceColorSchemeBundle toolbarSchemeBundle = new SubstanceColorSchemeBundle(
177
blackColorScheme, darkBlueColorScheme, darkBlueColorScheme);
178
toolbarSchemeBundle.registerColorScheme(blackColorScheme, 0.5f,
179
ComponentState.DISABLED_SELECTED);
180
toolbarSchemeBundle.registerColorScheme(darkBlueColorScheme, 0.5f,
181
ComponentState.DISABLED_UNSELECTED);
182
toolbarSchemeBundle.registerColorScheme(blackColorScheme,
183
ComponentState.ROLLOVER_UNSELECTED);
184
toolbarSchemeBundle.registerColorScheme(darkBlueColorScheme,
185
ColorSchemeAssociationKind.MARK);
186
toolbarSchemeBundle.registerColorScheme(darkBlueColorScheme,
187
ColorSchemeAssociationKind.BORDER);
188
applyHighlightColorScheme(toolbarSchemeBundle, highlightScheme,
189
darkBlueColorScheme);
190
this.registerDecorationAreaSchemeBundle(toolbarSchemeBundle,
191
darkBlueBackgroundColorScheme, DecorationAreaType.TOOLBAR);
193
this.setSelectedTabFadeStart(0.15);
194
this.setSelectedTabFadeEnd(0.25);
196
// add an overlay painter to paint a bezel line along the top
198
this.footerTopBezelOverlayPainter = new TopBezelOverlayPainter(
199
ColorSchemeSingleColorQuery.DARK,
200
ColorSchemeSingleColorQuery.ULTRALIGHT);
201
this.addOverlayPainter(this.footerTopBezelOverlayPainter,
202
DecorationAreaType.FOOTER);
204
// add two overlay painters to create a bezel line between
205
// menu bar and toolbars
206
this.menuOverlayPainter = new BottomLineOverlayPainter(
207
new ColorSchemeSingleColorQuery() {
209
public Color query(SubstanceColorScheme scheme) {
210
return scheme.getUltraDarkColor().darker();
213
this.toolbarOverlayPainter = new TopLineOverlayPainter(
214
new ColorSchemeSingleColorQuery() {
216
public Color query(SubstanceColorScheme scheme) {
217
Color fg = scheme.getForegroundColor();
218
return new Color(fg.getRed(), fg.getGreen(), fg
222
this.addOverlayPainter(this.menuOverlayPainter,
223
DecorationAreaType.HEADER);
224
this.addOverlayPainter(this.toolbarOverlayPainter,
225
DecorationAreaType.TOOLBAR);
227
// add overlay painter to paint drop shadows along the bottom
229
this.addOverlayPainter(BottomShadowOverlayPainter.getInstance(),
230
DecorationAreaType.TOOLBAR);
232
// add overlay painter to paint a dark line along the bottom
234
this.toolbarBottomLineOverlayPainter = new BottomLineOverlayPainter(
235
ColorSchemeSingleColorQuery.ULTRADARK);
236
this.addOverlayPainter(this.toolbarBottomLineOverlayPainter,
237
DecorationAreaType.TOOLBAR);
239
this.buttonShaper = new ClassicButtonShaper();
240
this.watermark = null;
241
this.fillPainter = new FractionBasedFillPainter("Gemini", new float[] {
242
0.0f, 0.5f, 1.0f }, new ColorSchemeSingleColorQuery[] {
243
ColorSchemeSingleColorQuery.EXTRALIGHT,
244
ColorSchemeSingleColorQuery.LIGHT,
245
ColorSchemeSingleColorQuery.MID });
247
this.decorationPainter = new MatteDecorationPainter();
248
this.highlightPainter = new ClassicHighlightPainter();
250
FractionBasedBorderPainter outerBorderPainter = new FractionBasedBorderPainter(
251
"Gemini Outer", new float[] { 0.0f, 0.5f, 1.0f },
252
new ColorSchemeSingleColorQuery[] {
253
ColorSchemeSingleColorQuery.ULTRADARK,
254
ColorSchemeSingleColorQuery.ULTRADARK,
255
ColorSchemeSingleColorQuery.ULTRADARK });
256
SubstanceBorderPainter innerBorderPainter = new DelegateFractionBasedBorderPainter(
257
"Gemini Inner", outerBorderPainter, new int[] { 0x60FFFFFF,
258
0x40FFFFFF, 0x20FFFFFF }, new ColorSchemeTransform() {
260
public SubstanceColorScheme transform(
261
SubstanceColorScheme scheme) {
262
return scheme.tint(0.7f);
266
this.borderPainter = new CompositeBorderPainter("Gemini",
267
outerBorderPainter, innerBorderPainter);
268
this.highlightBorderPainter = new ClassicBorderPainter();
272
* Applies the specified highlight schemes on the relevant parts of the
273
* specified scheme bundle.
275
* @param schemeBundle
277
* @param highlightScheme
279
* @param highlightBorderScheme
280
* Highlight border scheme.
282
private static void applyHighlightColorScheme(
283
SubstanceColorSchemeBundle schemeBundle,
284
SubstanceColorScheme highlightScheme,
285
SubstanceColorScheme highlightBorderScheme) {
287
// specify custom alpha values for the highlights
288
schemeBundle.registerHighlightColorScheme(highlightScheme, 0.75f,
289
ComponentState.ROLLOVER_UNSELECTED);
290
schemeBundle.registerHighlightColorScheme(highlightScheme, 0.9f,
291
ComponentState.SELECTED);
292
schemeBundle.registerHighlightColorScheme(highlightScheme, 1.0f,
293
ComponentState.ROLLOVER_SELECTED);
294
schemeBundle.registerHighlightColorScheme(highlightScheme, 1.0f,
295
ComponentState.ARMED, ComponentState.ROLLOVER_ARMED);
297
// use for borders on rollover controls
298
schemeBundle.registerColorScheme(highlightBorderScheme,
299
ColorSchemeAssociationKind.BORDER,
300
ComponentState.ROLLOVER_ARMED,
301
ComponentState.ROLLOVER_SELECTED,
302
ComponentState.ROLLOVER_UNSELECTED);
304
// use for fill of selected controls
305
schemeBundle.registerColorScheme(highlightScheme,
306
ColorSchemeAssociationKind.FILL, ComponentState.SELECTED,
307
ComponentState.ROLLOVER_SELECTED);
309
// use for borders of highlights
310
schemeBundle.registerColorScheme(highlightScheme,
311
ColorSchemeAssociationKind.HIGHLIGHT_BORDER, ComponentState
314
// use for text highlight
315
schemeBundle.registerColorScheme(highlightScheme,
316
ColorSchemeAssociationKind.TEXT_HIGHLIGHT,
317
ComponentState.SELECTED, ComponentState.ROLLOVER_SELECTED);
319
// use for armed controls
320
schemeBundle.registerColorScheme(highlightScheme, ComponentState.ARMED,
321
ComponentState.ROLLOVER_ARMED);
327
* @see org.pushingpixels.substance.skin.SubstanceSkin#getDisplayName()
330
public String getDisplayName() {