/* Copyright (C) 2005-2011 Fabio Riccardi */
package com.lightcrafts.ui.operation;
import java.awt.event.*;
import java.awt.geom.Point2D;
import java.awt.*;
import java.beans.PropertyChangeSupport;
import java.util.Enumeration;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.undo.AbstractUndoableEdit;
import com.lightcrafts.model.ColorSelection;
import com.lightcrafts.model.Operation;
import com.lightcrafts.model.RGBColorSelection;
import com.lightcrafts.model.RGBColorSelectionPreset;
import com.lightcrafts.ui.LightZoneSkin;
import com.lightcrafts.ui.editor.EditorMode;
import com.lightcrafts.ui.toolkit.LCSliderUI;
import com.lightcrafts.ui.toolkit.DropperButton;
import com.lightcrafts.ui.mode.DropperMode;
import com.lightcrafts.ui.swing.*;
import com.lightcrafts.utils.xml.XMLException;
import com.lightcrafts.utils.xml.XmlNode;
import com.lightcrafts.utils.LCMS;
import static com.lightcrafts.ui.operation.Locale.LOCALE;
import com.lightcrafts.jai.JAIContext;
import com.lightcrafts.app.ComboFrame;
import org.jvnet.substance.SubstanceLookAndFeel;
import org.jvnet.substance.theme.SubstanceTheme;
import org.jvnet.substance.color.ColorScheme;
/**
* A <code>ColorSelectionControls</code> is-a {@link Box} that contains all
* the controls to do color-based selection.
*/
final class ColorSelectionControls extends Box {
private final PropertyChangeSupport pcs;
public static final String COLOR_SELECTION = "Color Selection";
private static LCMS.Transform ts = new LCMS.Transform(
new LCMS.Profile( JAIContext.linearProfile ), LCMS.TYPE_RGB_8,
new LCMS.Profile( JAIContext.systemProfile ), LCMS.TYPE_RGB_8,
LCMS.INTENT_PERCEPTUAL, 0
);
public static JRadioButton getSelection( ButtonGroup group ) {
for ( Enumeration e = group.getElements(); e.hasMoreElements(); ) {
final JRadioButton b = (JRadioButton)e.nextElement();
if ( b.getModel() == group.getSelection() ) {
return b;
}
}
return null;
}
private final class ColorPresets extends Box {
private final class ColorButton extends JRadioButton {
final RGBColorSelectionPreset m_preset;
ColorButton( RGBColorSelectionPreset preset ) {
m_preset = preset;
setFocusable( false );
}
}
ButtonGroup group = new ButtonGroup();
ColorPresets() {
super(BoxLayout.X_AXIS);
for ( final RGBColorSelectionPreset p : RGBColorSelectionPreset.values() ) {
if (!p.equals(RGBColorSelectionPreset.SampledColors)) {
final ColorButton button = new ColorButton(p);
group.add(button);
add(button);
if (p.equals(RGBColorSelectionPreset.AllColors)) {
button.setText("All");
button.setSelected(true);
button.setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 3));
} else {
final RGBColorSelection cs =
new RGBColorSelection(p, false);
final byte[] systemColor = new byte[3];
ts.doTransform(
new byte[]{
(byte)(0xff * cs.red),
(byte)(0xff * cs.green),
(byte)(0xff * cs.blue)
},
systemColor
);
final Color color = new Color(0xff & systemColor[0],
0xff & systemColor[1],
0xff & systemColor[2]);
final ColorScheme colorScheme = new LightZoneSkin.CustomColorScheme(color);
final SubstanceTheme theme = LightZoneSkin.makeTheme(colorScheme, p.name());
button.putClientProperty(SubstanceLookAndFeel.THEME_PROPERTY, theme);
button.putClientProperty(SubstanceLookAndFeel.PAINT_ACTIVE_PROPERTY, Boolean.TRUE);
button.setBorder(BorderFactory.createEmptyBorder(1, 2, 1, 3));
}
button.addItemListener(
new ItemListener() {
public void itemStateChanged( ItemEvent ie ) {
if ( ie.getStateChange() == ItemEvent.SELECTED ) {
final ColorButton b =
(ColorButton)ie.getItem();
selectPreset( b.m_preset );
}
}
}
);
}
}
add(Box.createHorizontalGlue());
}
RGBColorSelectionPreset getSelectedItem() {
final ColorButton selection = (ColorButton) getSelection(group);
if (selection == null)
return RGBColorSelectionPreset.SampledColors;
return selection.m_preset;
}
void setSelectedItem( RGBColorSelectionPreset p ) {
if ( !p.equals( RGBColorSelectionPreset.SampledColors ) ) {
final Enumeration e = group.getElements();
while ( e.hasMoreElements() ) {
final ColorButton b = (ColorButton)e.nextElement();
if ( b.m_preset.equals( p ) ) {
b.setSelected( true );
break;
}
}
} else {
final ColorButton selection = (ColorButton)getSelection( group );
if ( selection != null ) {
group.remove( selection );
selection.setSelected( false );
group.add( selection );
}
}
}
}
ColorSelectionControls( OpControl control, PropertyChangeSupport pcs ) {
super(BoxLayout.X_AXIS);
this.pcs = pcs;
m_op = control.getOperation();
m_undoSupport = control.undoSupport;
m_hueEnabled = new JCheckBox();
m_hueEnabled.setFocusable( false );
m_hueEnabled.setSelected( true );
m_hueEnabled.setToolTipText(
LOCALE.get( "HueDisableToolTip" )
);
m_hueEnabled.addItemListener(
new EnablerListener(
LOCALE.get( "HueDisableToolTip" ),
LOCALE.get( "HueEnableToolTip" )
)
);
m_luminosityEnabled = new JCheckBox();
m_luminosityEnabled.setFocusable( false );
m_luminosityEnabled.setSelected( true );
m_luminosityEnabled.setToolTipText(
LOCALE.get( "BrightnessDisableToolTip" )
);
m_luminosityEnabled.addItemListener(
new EnablerListener(
LOCALE.get( "BrightnessDisableToolTip" ),
LOCALE.get( "BrightnessEnableToolTip" )
)
);
final LocalListener localListener = new LocalListener();
m_colorSwatch = new ColorSwatch( COLOR_SWATCH_DEFAULT );
final JLabel colorRadiusLabel =
new JLabel( LOCALE.get( "ColorRangeLabel" ) + ':' );
colorRadiusLabel.setBackground( OpControl.Background );
colorRadiusLabel.setFocusable( false );
colorRadiusLabel.setFont( LightZoneSkin.fontSet.getSmallFont() );
m_colorRangeSlider = new JSlider(
SLIDER_RADIUS_MIN, SLIDER_RADIUS_MAX,
COLOR_RADIUS_DEFAULT
);
m_colorRangeSlider.setBackground( OpControl.Background );
m_colorRangeSlider.setFocusable( false );
m_colorRangeSlider.setUI( new LCSliderUI( m_colorRangeSlider ) );
m_colorRangeSlider.setToolTipText( LOCALE.get( "ColorRangeToolTip" ) );
m_colorRangeSlider.addChangeListener( localListener );
m_colorRangeSlider.addMouseListener( localListener );
m_colorPresets = new ColorPresets();
m_luminositySelector = new RangeSelector(
SELECTOR_LUMINOSITY_MIN, SELECTOR_LUMINOSITY_MAX
);
m_luminositySelector.setTrack( new RangeSelectorZoneTrack() );
m_luminositySelector.addChangeListener( localListener );
m_luminositySelector.addMouseListener( localListener );
m_luminositySelector.setToolTipText(
LOCALE.get( "BrightnessSelectorToolTip" )
);
initDropper( control );
m_invertSelection = new JCheckBox( "Invert" );
m_invertSelection.setFont(LightZoneSkin.fontSet.getSmallFont());
m_invertSelection.setFocusable( false );
m_invertSelection.setToolTipText(
LOCALE.get( "InvertColorSelectionEnableToolTip" )
);
m_invertSelection.addItemListener(
new EnablerListener(
LOCALE.get( "InvertColorSelectionDisableToolTip" ),
LOCALE.get( "InvertColorSelectionEnableToolTip" ),
LOCALE.get( "InvertColorSelectionEditName" ),
LOCALE.get( "NormalColorSelectionEditName" )
)
);
final ResetColorSelectionButton resetButton =
new ResetColorSelectionButton(
new ActionListener() {
public void actionPerformed( ActionEvent ae ) {
resetColorSelection();
}
}
);
setBackground( LightZoneSkin.Colors.ToolPanesBackground );
////////// Color controls /////////////////////////////////////////////
final JPanel presets = new JPanel();
presets.setBackground( LightZoneSkin.Colors.ToolPanesBackground );
presets.setLayout(
new BoxLayout( presets, BoxLayout.X_AXIS )
);
presets.add( Box.createHorizontalStrut( 10 ) );
presets.add( m_colorPresets );
presets.add( Box.createHorizontalGlue() );
final JPanel radius = new JPanel();
radius.setBackground( LightZoneSkin.Colors.ToolPanesBackground );
radius.setLayout( new BoxLayout( radius, BoxLayout.X_AXIS ) );
radius.add( Box.createHorizontalStrut( 5 ) );
radius.add( colorRadiusLabel );
radius.add( m_colorRangeSlider );
final JPanel presetsAndRadius = new JPanel();
presetsAndRadius.setBackground( LightZoneSkin.Colors.ToolPanesBackground );
presetsAndRadius.setLayout(
new BoxLayout( presetsAndRadius, BoxLayout.Y_AXIS )
);
presetsAndRadius.add( Box.createVerticalStrut( 10 ) );
presetsAndRadius.add( presets );
presetsAndRadius.add( radius );
final JPanel colorControls = new JPanel();
colorControls.setBackground( LightZoneSkin.Colors.ToolPanesBackground );
colorControls.setLayout(
new BoxLayout( colorControls, BoxLayout.X_AXIS )
);
colorControls.add( m_hueEnabled );
colorControls.add( m_colorSwatch );
colorControls.add( presetsAndRadius );
////////// Luminosity controls ////////////////////////////////////////
final JPanel luminosityControls = new JPanel();
luminosityControls.setBackground( LightZoneSkin.Colors.ToolPanesBackground );
luminosityControls.setLayout(
new BoxLayout( luminosityControls, BoxLayout.X_AXIS )
);
luminosityControls.add( m_luminosityEnabled );
luminosityControls.add( m_luminositySelector );
////////// Color & Luminosity /////////////////////////////////////////
final JPanel colorAndLuminosity = new JPanel();
colorAndLuminosity.setBackground( LightZoneSkin.Colors.ToolPanesBackground );
colorAndLuminosity.setLayout(
new BoxLayout( colorAndLuminosity, BoxLayout.Y_AXIS )
);
colorAndLuminosity.add( colorControls );
colorAndLuminosity.add( luminosityControls );
////////// Reset & Dropper ////////////////////////////////////////////
final JPanel resetAndDropper = new JPanel();
resetAndDropper.setBackground( LightZoneSkin.Colors.ToolPanesBackground );
resetAndDropper.setLayout(
new BoxLayout( resetAndDropper, BoxLayout.X_AXIS )
);
resetAndDropper.add( m_dropperButton );
resetAndDropper.add( resetButton );
////////// Invert, Reset & Dropper ////////////////////////////////////
final JPanel invertEtc = new JPanel();
invertEtc.setBackground( LightZoneSkin.Colors.ToolPanesBackground );
invertEtc.setLayout( new BoxLayout( invertEtc, BoxLayout.Y_AXIS ) );
invertEtc.add( Box.createVerticalGlue() );
invertEtc.add( resetAndDropper );
invertEtc.add( Box.createVerticalStrut(8) );
invertEtc.add( m_invertSelection );
m_invertSelection.setAlignmentX( Component.LEFT_ALIGNMENT );
resetAndDropper.setAlignmentX( Component.LEFT_ALIGNMENT );
////////// This component itself //////////////////////////////////////
add( invertEtc );
add( Box.createHorizontalStrut(4) );
add( colorAndLuminosity );
add( Box.createHorizontalGlue() );
m_currentEdit = new ColorSelectionEdit();
}
void operationChanged( Operation op ) {
m_op = op;
}
void save( XmlNode node ) {
final RGBColorSelection cs = m_op.getColorSelection();
final XmlNode colorNode = node.addChild( ColorSelectionKey );
colorNode.setAttribute(
HueRedKey, Float.toString( cs.red )
);
colorNode.setAttribute(
HueGreenKey, Float.toString( cs.green )
);
colorNode.setAttribute(
HueBlueKey, Float.toString( cs.blue )
);
colorNode.setAttribute(
HueRadiusKey, Float.toString( cs.radius )
);
colorNode.setAttribute(
HueEnabledKey, Boolean.toString( cs.isColorEnabled )
);
colorNode.setAttribute(
LuminosityLowerKey,
Float.toString( cs.luminosityLower )
);
colorNode.setAttribute(
LuminosityLowerFeatherKey,
Float.toString( cs.luminosityLowerFeather )
);
colorNode.setAttribute(
LuminosityUpperKey,
Float.toString( cs.luminosityUpper )
);
colorNode.setAttribute(
LuminosityUpperFeatherKey,
Float.toString( cs.luminosityUpperFeather )
);
colorNode.setAttribute(
LuminosityEnabledKey,
Boolean.toString( cs.isLuminosityEnabled )
);
colorNode.setAttribute(
InvertedKey,
Boolean.toString( cs.isInverted )
);
}
void restore( XmlNode node ) throws XMLException {
if ( node.hasChild( ColorSelectionKey ) ) {
node = node.getChild( ColorSelectionKey );
try {
final float red = Float.parseFloat(
node.getAttribute( HueRedKey )
);
final float green = Float.parseFloat(
node.getAttribute( HueGreenKey )
);
final float blue = Float.parseFloat(
node.getAttribute( HueBlueKey )
);
final float radius = Float.parseFloat(
node.getAttribute( HueRadiusKey )
);
final boolean isHueEnabled = Boolean.parseBoolean(
node.getAttribute( HueEnabledKey )
);
final float blv = Float.parseFloat(
node.getAttribute( LuminosityLowerKey )
);
final float blfv = Float.parseFloat(
node.getAttribute( LuminosityLowerFeatherKey )
);
final float buv = Float.parseFloat(
node.getAttribute( LuminosityUpperKey )
);
final float bufv = Float.parseFloat(
node.getAttribute( LuminosityUpperFeatherKey )
);
final boolean isLuminosityEnabled = Boolean.parseBoolean(
node.getAttribute( LuminosityEnabledKey )
);
final boolean isInverted = Boolean.parseBoolean(
node.getAttribute( InvertedKey )
);
final RGBColorSelection cs = new RGBColorSelection(
red, green, blue, radius, blv, blfv, buv, bufv,
isInverted, isHueEnabled, isLuminosityEnabled
);
colorSelectionToControls( cs, false );
m_op.setColorSelection( cs );
m_currentEdit = new ColorSelectionEdit();
}
catch ( IllegalArgumentException e ) {
throw new XMLException( e );
}
}
}
////////// private ////////////////////////////////////////////////////////
private class ColorSelectionEdit extends AbstractUndoableEdit {
ColorSelectionEdit() {
m_beforeHueModel = controlsToColorSelection();
}
void end( String name ) {
m_name = name;
m_afterHueModel = controlsToColorSelection();
}
public String getPresentationName() {
return m_name;
}
public void undo() {
super.undo();
colorSelectionToControls( m_beforeHueModel, true );
m_op.setColorSelection( m_beforeHueModel );
m_currentEdit = new ColorSelectionEdit();
}
public void redo() {
super.redo();
colorSelectionToControls( m_afterHueModel, true );
m_op.setColorSelection( m_afterHueModel );
}
private RGBColorSelection m_afterHueModel;
private final RGBColorSelection m_beforeHueModel;
private String m_name = "";
}
// Handle ColorSelection updates and undo for events coming from the
// enable/disable checkboxes.
private final class EnablerListener implements ItemListener {
public void itemStateChanged( ItemEvent ie ) {
if ( !m_isUpdatingControls ) {
m_op.setColorSelection( controlsToColorSelection() );
final JComponent comp = (JComponent)ie.getSource();
if ( ie.getStateChange() == ItemEvent.SELECTED ) {
postEdit( m_enabledEditName );
comp.setToolTipText( m_selectedTip );
} else {
postEdit( m_disabledEditName );
comp.setToolTipText( m_unselectedTip );
}
}
}
EnablerListener( String selectedTip, String unselectedTip ) {
this(
selectedTip, unselectedTip,
LOCALE.get( "ColorSelectorEnabledEditName" ),
LOCALE.get( "ColorSelectorDisabledEditName" )
);
}
EnablerListener( String selectedTip, String unselectedTip,
String enabledEditName, String disabledEditName ) {
m_enabledEditName = enabledEditName;
m_disabledEditName = disabledEditName;
m_selectedTip = selectedTip;
m_unselectedTip = unselectedTip;
}
private final String m_enabledEditName, m_disabledEditName;
private final String m_selectedTip, m_unselectedTip;
}
/**
* This is listener for both the color feathering radius slider and the
* luminosity selector.
*/
private final class LocalListener
extends MouseAdapter implements ChangeListener
{
public void mousePressed( MouseEvent me ) {
m_op.changeBatchStarted();
}
public void mouseReleased( MouseEvent me ) {
m_op.changeBatchEnded();
postEdit( LOCALE.get( "ColorSelectorEditName" ) );
}
public void stateChanged( ChangeEvent ce ) {
if ( !m_isUpdatingControls ) {
final RGBColorSelection cs = controlsToColorSelection();
m_lowerLuminosityFeather = cs.luminosityLowerFeather;
m_upperLuminosityFeather = cs.luminosityUpperFeather;
m_op.setColorSelection( cs );
m_prevCS = cs;
}
}
}
/**
* Sets the values of the color selection controls from the given
* {@link ColorSelection}.
*
* @param cs The {@link ColorSelection}.
* @param force If <code>true</code>, force updating of controls.
* (This is used during undo/redo.)
* @see #controlsToColorSelection()
*/
private void colorSelectionToControls( RGBColorSelection cs,
boolean force ) {
m_isUpdatingControls = true;
try {
if ( m_hueEnabled.isSelected() && cs.isColorEnabled || force ) {
m_colorSwatch.setColor( cs.toColor() );
final int radius;
if ( cs.getPreset() == RGBColorSelectionPreset.AllColors )
radius = COLOR_RADIUS_DEFAULT;
else
radius = (int)(cs.radius * SLIDER_RADIUS_MAX);
m_colorRangeSlider.setValue( radius );
m_hueEnabled.setSelected( cs.isColorEnabled );
}
if ( m_luminosityEnabled.isSelected() && cs.isLuminosityEnabled ||
force ) {
final float cblv = cs.luminosityLower;
final float cblfv = cs.luminosityLowerFeather;
final float cbuv = cs.luminosityUpper;
final float cbufv = cs.luminosityUpperFeather;
final int bMin = m_luminositySelector.getMinimumThumbValue();
final int bMax = m_luminositySelector.getMaximumThumbValue();
final int bWidth = bMax - bMin;
m_luminositySelector.setProperties(
bMin, bMax,
(int)(cblv * bWidth), (int)((cblv - cblfv) * bWidth),
(int)(cbuv * bWidth), (int)((cbuv + cbufv) * bWidth),
m_luminositySelector.getMinimumTrackValue(),
m_luminositySelector.getMaximumTrackValue(),
m_luminositySelector.getTrackValue(),
m_luminositySelector.getTrackValueWraps()
);
m_luminosityEnabled.setSelected( cs.isLuminosityEnabled );
}
m_invertSelection.setSelected( cs.isInverted );
m_skipSelectPresetCode = true;
m_colorPresets.setSelectedItem( cs.getPreset() );
m_skipSelectPresetCode = false;
if (cs.isAllSelected())
pcs.firePropertyChange(
COLOR_SELECTION, Boolean.TRUE, Boolean.FALSE
);
else
pcs.firePropertyChange(
COLOR_SELECTION, Boolean.FALSE, Boolean.TRUE
);
}
finally {
m_isUpdatingControls = false;
}
}
/**
* Converts the current values of the color selection controls into a
* {@link ColorSelection} that is used by the imaging engine.
*
* @return Returns a {@link ColorSelection} that represents the current
* values of the color selection controls.
* @see #colorSelectionToControls(RGBColorSelection,boolean)
*/
private RGBColorSelection controlsToColorSelection() {
final Color c = m_colorSwatch.getColor();
final int hMin = m_colorRangeSlider.getMinimum();
final int hMax = m_colorRangeSlider.getMaximum();
final float hWidth = hMax - hMin;
final float radius = m_colorPresets.getSelectedItem() == RGBColorSelectionPreset.AllColors ? -1 : m_colorRangeSlider.getValue() / hWidth;
final int lMin = m_luminositySelector.getMinimumThumbValue();
final int lMax = m_luminositySelector.getMaximumThumbValue();
final float lWidth = lMax - lMin;
final int llv = m_luminositySelector.getLowerThumbValue();
final int llfv = m_luminositySelector.getLowerThumbFeatheringValue();
final int luv = m_luminositySelector.getUpperThumbValue();
final int lufv = m_luminositySelector.getUpperThumbFeatheringValue();
final float cllv = llv / lWidth;
final float cllfv = (llv - llfv) / lWidth;
final float cluv = luv / lWidth;
final float clufv = (lufv - luv) / lWidth;
final RGBColorSelection cs = new RGBColorSelection(
c.getRed() / 255F, c.getGreen() / 255F, c.getBlue() / 255F,
radius,
cllv, cllfv, cluv, clufv,
m_invertSelection.isSelected(),
m_hueEnabled.isSelected(), m_luminosityEnabled.isSelected()
);
if ( cs.isAllSelected() )
pcs.firePropertyChange(
COLOR_SELECTION, Boolean.TRUE, Boolean.FALSE
);
else
pcs.firePropertyChange(
COLOR_SELECTION, Boolean.FALSE, Boolean.TRUE
);
return cs;
}
public ComboFrame getComboFrame() {
return (ComboFrame)SwingUtilities.getAncestorOfClass(
ComboFrame.class, this
);
}
private void initDropper( final OpControl control ) {
m_dropperButton = new DropperButton();
m_dropperButton.setToolTips(
ColorSelectStartToolTip, ColorSelectEndToolTip
);
m_dropperButton.addItemListener(
new ItemListener() {
public void itemStateChanged( ItemEvent ie ) {
if ( ie.getStateChange() == ItemEvent.SELECTED ) {
getComboFrame().getEditor().setMode( EditorMode.ARROW );
control.notifyListenersEnterMode( m_dropperMode );
} else if ( !m_isDropperModeCancelling )
control.notifyListenersExitMode( m_dropperMode );
}
}
);
m_dropperMode = new DropperMode( control );
m_dropperMode.addListener(
new DropperMode.Listener() {
public void pointSelected( Point2D p ) {
selectColorAt( p );
}
public void modeCancelled() {
// Reset the toggle button, without firing notifications:
m_isDropperModeCancelling = true;
m_dropperButton.setSelected( false );
m_isDropperModeCancelling = false;
}
}
);
}
private RGBColorSelection mergeColorSelections( RGBColorSelection cs ) {
if ( cs.getPreset() != RGBColorSelectionPreset.AllColors ) {
final float radius;
final float luminosityLowerFeather;
final float luminosityUpperFeather;
if ( m_prevCS != null ) {
radius = m_prevCS.radius;
luminosityLowerFeather =
Math.min( cs.luminosityLower, m_lowerLuminosityFeather );
luminosityUpperFeather =
Math.min( 1-cs.luminosityUpper, m_upperLuminosityFeather );
} else {
radius = cs.radius;
luminosityLowerFeather =
Math.min( cs.luminosityLower, cs.luminosityLowerFeather );
luminosityUpperFeather =
Math.min( 1-cs.luminosityUpper, cs.luminosityUpperFeather );
}
cs = new RGBColorSelection(
cs.red, cs.green, cs.blue, radius,
cs.luminosityLower, luminosityLowerFeather,
cs.luminosityUpper, luminosityUpperFeather,
false,
m_hueEnabled.isSelected(),
m_luminosityEnabled.isSelected()
);
m_prevCS = cs;
m_lowerLuminosityFeather = cs.luminosityLowerFeather;
m_upperLuminosityFeather = cs.luminosityUpperFeather;
}
return cs;
}
private void postEdit( String name ) {
m_currentEdit.end( name );
m_undoSupport.postEdit( m_currentEdit );
m_currentEdit = new ColorSelectionEdit();
}
private void resetColorSelection() {
m_isUpdatingControls = true;
m_op.changeBatchStarted();
boolean undoable = false;
try {
if ( m_hueEnabled.isSelected() ) {
m_prevCS = null;
m_colorPresets.setSelectedItem( RGBColorSelectionPreset.AllColors );
undoable = true;
}
if ( m_luminosityEnabled.isSelected() ) {
m_luminositySelector.setProperties(
m_luminositySelector.getMinimumThumbValue(),
m_luminositySelector.getMaximumThumbValue(),
m_luminositySelector.getMinimumThumbValue(),
m_luminositySelector.getMinimumThumbValue(),
m_luminositySelector.getMaximumThumbValue(),
m_luminositySelector.getMaximumThumbValue(),
m_luminositySelector.getMinimumTrackValue(),
m_luminositySelector.getMaximumTrackValue(),
m_luminositySelector.getTrackValue(),
m_luminositySelector.getTrackValueWraps()
);
undoable = true;
}
if ( undoable )
postEdit( LOCALE.get( "ResetColorSelectionEditName" ) );
}
finally {
m_op.changeBatchEnded();
m_isUpdatingControls = false;
}
}
private void selectColorAt( Point2D p ) {
RGBColorSelection cs = m_op.getColorSelectionAt( p );
cs = mergeColorSelections( cs );
m_op.setColorSelection( cs );
colorSelectionToControls( cs, false );
postEdit( LOCALE.get( "ColorDropperEditName" ) );
}
private void selectPreset( RGBColorSelectionPreset p ) {
if ( !m_skipSelectPresetCode ) {
final boolean wasUpdatingControls = m_isUpdatingControls;
m_skipSelectPresetCode = true;
m_isUpdatingControls = true;
m_hueEnabled.setSelected( true );
RGBColorSelection cs =
new RGBColorSelection( p, m_invertSelection.isSelected() );
//cs = mergeColorSelections( cs );
m_op.setColorSelection( cs );
colorSelectionToControls( cs, false );
m_skipSelectPresetCode = false;
if ( !wasUpdatingControls )
postEdit(
LOCALE.get( "SelectColorPresetEditName", p.toString() )
);
m_prevCS = null;
m_isUpdatingControls = wasUpdatingControls;
}
}
private boolean m_skipSelectPresetCode;
private final ColorSwatch m_colorSwatch;
private final JSlider m_colorRangeSlider;
private final ColorPresets m_colorPresets;
private ColorSelectionEdit m_currentEdit;
private DropperButton m_dropperButton;
private DropperMode m_dropperMode;
private final JCheckBox m_invertSelection;
private Operation m_op;
private final RangeSelector m_luminositySelector;
private float m_lowerLuminosityFeather, m_upperLuminosityFeather;
private RGBColorSelection m_prevCS;
private JCheckBox m_hueEnabled;
private JCheckBox m_luminosityEnabled;
// Flag dropper button state changes that just synchronize the button
// when the dropper Mode is externally cancelled, so OpControlModeListener
// notifications won't fire:
private boolean m_isDropperModeCancelling;
// Disable callbacks from the selectors and the checkboxes when these
// controls are being slewed to a new ColorSelection.
private boolean m_isUpdatingControls;
private OpControl.OpControlUndoSupport m_undoSupport;
private final static String ColorSelectStartToolTip =
LOCALE.get( "ColorSelectStartToolTip" );
private final static String ColorSelectEndToolTip =
LOCALE.get( "ColorSelectEndToolTip" );
private final static String ColorSelectionKey = "ColorSelection";
private final static String HueRedKey = "HueRed";
private final static String HueGreenKey = "HueGreen";
private final static String HueBlueKey = "HueBlue";
private final static String HueRadiusKey = "HueRadius";
private final static String HueEnabledKey = "HueEnabled";
private final static String LuminosityLowerKey = "LuminosityLower";
private final static String LuminosityUpperKey = "LuminosityUpper";
private final static String LuminosityLowerFeatherKey = "LuminosityLowerFeather";
private final static String LuminosityUpperFeatherKey = "LuminosityUpperFeather";
private final static String LuminosityEnabledKey = "LuminosityEnabled";
private final static String InvertedKey = "Inverted";
private static final int SLIDER_RADIUS_MIN = 0;
private static final int SLIDER_RADIUS_MAX = 100;
private static final int SELECTOR_LUMINOSITY_MIN = 0;
private static final int SELECTOR_LUMINOSITY_MAX = 1000;
private static final Color COLOR_SWATCH_DEFAULT = Color.GRAY;
private static final int COLOR_RADIUS_DEFAULT = 20;
}
/* vim:set et sw=4 ts=4: */