/*
* Copyright (c) 2009 Kathryn Huxtable and Kenneth Orr.
*
* This file is part of the SeaGlass Pluggable Look and Feel.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* $Id$
*/
package com.seaglasslookandfeel.painter;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.Shape;
import javax.swing.JComponent;
import javax.swing.JSpinner;
import javax.swing.JSpinner.DefaultEditor;
import com.seaglasslookandfeel.painter.AbstractRegionPainter.PaintContext.CacheMode;
import com.seaglasslookandfeel.painter.util.ShapeGenerator.CornerSize;
import com.seaglasslookandfeel.painter.util.ShapeGenerator.CornerStyle;
/**
* SpinnerNextButtonPainter implementation.
*/
public final class SpinnerNextButtonPainter extends AbstractCommonColorsPainter {
public static enum Which {
BACKGROUND_DISABLED,
BACKGROUND_ENABLED,
BACKGROUND_FOCUSED,
BACKGROUND_PRESSED_FOCUSED,
BACKGROUND_PRESSED,
FOREGROUND_DISABLED,
FOREGROUND_ENABLED,
FOREGROUND_FOCUSED,
FOREGROUND_PRESSED_FOCUSED,
FOREGROUND_PRESSED,
}
private Color spinnerNextBorderBottomEnabled = decodeColor("spinnerNextBorderBottomEnabled");
private Color spinnerNextBorderBottomPressed = decodeColor("spinnerNextBorderBottomPressed");
private Color spinnerNextInteriorBottomEnabled = decodeColor("spinnerNextInteriorBottomEnabled");
private Color spinnerNextInteriorBottomPressed = decodeColor("spinnerNextInteriorBottomPressed");
private TwoColors pressedButtonBorder = getCommonBorderColors(CommonControlState.PRESSED);
private TwoColors spinnerNextBorderEnabled = new TwoColors(pressedButtonBorder.top, spinnerNextBorderBottomEnabled);
private TwoColors spinnerNextBorderPressed = new TwoColors(pressedButtonBorder.top, spinnerNextBorderBottomPressed);
private TwoColors spinnerNextBorderDisabled = disable(spinnerNextBorderEnabled);
private FourColors pressedButtonInterior = getCommonInteriorColors(CommonControlState.PRESSED);
private FourColors selectedButtonInterior = getCommonInteriorColors(CommonControlState.SELECTED);
private TwoColors spinnerNextInteriorEnabled = new TwoColors(selectedButtonInterior.top, spinnerNextInteriorBottomEnabled);
private TwoColors spinnerNextInteriorPressed = new TwoColors(pressedButtonInterior.top, spinnerNextInteriorBottomPressed);
private TwoColors spinnerNextInteriorDisabled = desaturate(desaturate(spinnerNextInteriorEnabled));
private PaintContext ctx;
private CommonControlState type;
private boolean focused;
private boolean isForeground;
public SpinnerNextButtonPainter(Which state) {
super();
this.ctx = new PaintContext(CacheMode.NO_CACHING);
type = getButtonType(state);
focused = (state == Which.BACKGROUND_FOCUSED || state == Which.BACKGROUND_PRESSED_FOCUSED
|| state == Which.FOREGROUND_FOCUSED || state == Which.FOREGROUND_PRESSED_FOCUSED);
isForeground = isForeground(state);
}
@Override
protected void doPaint(Graphics2D g, JComponent c, int width, int height, Object[] extendedCacheKeys) {
if (isForeground) {
paintArrow(g, width, height);
} else {
paintButton(g, c, width, height);
}
}
@Override
protected PaintContext getPaintContext() {
return ctx;
}
private CommonControlState getButtonType(Which state) {
switch (state) {
case BACKGROUND_DISABLED:
case FOREGROUND_DISABLED:
return CommonControlState.DISABLED;
case BACKGROUND_ENABLED:
case BACKGROUND_FOCUSED:
case FOREGROUND_ENABLED:
case FOREGROUND_FOCUSED:
return CommonControlState.ENABLED;
case BACKGROUND_PRESSED_FOCUSED:
case BACKGROUND_PRESSED:
case FOREGROUND_PRESSED_FOCUSED:
case FOREGROUND_PRESSED:
return CommonControlState.PRESSED;
}
return null;
}
private boolean isForeground(Which state) {
switch (state) {
case FOREGROUND_DISABLED:
case FOREGROUND_ENABLED:
case FOREGROUND_FOCUSED:
case FOREGROUND_PRESSED_FOCUSED:
case FOREGROUND_PRESSED:
return true;
default:
return false;
}
}
private void paintButton(Graphics2D g, JComponent c, int width, int height) {
boolean useToolBarColors = isInToolBar(c);
Shape s;
JSpinner spinner = (JSpinner) c.getParent();
boolean editorFocused = false;
JComponent editor = spinner.getEditor();
if (editor instanceof DefaultEditor) {
editorFocused = ((DefaultEditor)editor).getTextField().isFocusOwner();
}
if (focused || editorFocused) {
s = createButtonShape(0, 0, width, height, CornerSize.OUTER_FOCUS);
g.setPaint(getFocusPaint(s, FocusType.OUTER_FOCUS, useToolBarColors));
g.fill(s);
s = createButtonShape(0, 1, width - 1, height - 1, CornerSize.INNER_FOCUS);
g.setPaint(getFocusPaint(s, FocusType.INNER_FOCUS, useToolBarColors));
g.fill(s);
}
s = createButtonShape(0, 2, width - 2, height - 2, CornerSize.BORDER);
g.setPaint(getSpinnerNextBorderPaint(s, type));
g.fill(s);
s = createButtonShape(1, 3, width - 4, height - 4, CornerSize.INTERIOR);
g.setPaint(getSpinnerNextInteriorPaint(s, type));
g.fill(s);
}
private void paintArrow(Graphics2D g, int width, int height) {
Shape s = createArrowShape(width, height);
g.setPaint(getCommonArrowPaint(s, type));
g.fill(s);
}
private Shape createButtonShape(int x, int y, int width, int height, CornerSize size) {
return shapeGenerator.createRoundRectangle(x, y, width, height, size, CornerStyle.SQUARE, CornerStyle.SQUARE, CornerStyle.SQUARE,
CornerStyle.ROUNDED);
}
private Shape createArrowShape(int left, int height) {
int centerX = left / 2 -3;
int centerY = height / 2;
return shapeGenerator.createArrowUp(centerX, centerY, 4, 3);
}
public Paint getSpinnerNextBorderPaint(Shape s, CommonControlState type) {
TwoColors colors = getSpinnerNextBorderColors(type);
return createVerticalGradient(s, colors);
}
public Paint getSpinnerNextInteriorPaint(Shape s, CommonControlState type) {
TwoColors colors = getSpinnerNextInteriorColors(type);
return createVerticalGradient(s, colors);
}
private TwoColors getSpinnerNextBorderColors(CommonControlState type) {
switch (type) {
case DISABLED:
return spinnerNextBorderDisabled;
case ENABLED:
return spinnerNextBorderEnabled;
case PRESSED:
return spinnerNextBorderPressed;
}
return null;
}
private TwoColors getSpinnerNextInteriorColors(CommonControlState type) {
switch (type) {
case DISABLED:
return spinnerNextInteriorDisabled;
case ENABLED:
return spinnerNextInteriorEnabled;
case PRESSED:
return spinnerNextInteriorPressed;
}
return null;
}
}