Package org.gephi.ui.components.gradientslider

Source Code of org.gephi.ui.components.gradientslider.GradientSlider$ColorPickerPopup

/*
Copyright 2008-2010 Gephi
Authors : Mathieu Bastian <mathieu.bastian@gephi.org>
Website : http://www.gephi.org

This file is part of Gephi.

Gephi is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as
published by the Free Software Foundation, either version 3 of the
License, or (at your option) any later version.

Gephi is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU Affero General Public License for more details.

You should have received a copy of the GNU Affero General Public License
along with Gephi.  If not, see <http://www.gnu.org/licenses/>.
*/
package org.gephi.ui.components.gradientslider;

import com.bric.swing.ColorPicker;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Window;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.lang.reflect.Constructor;

import javax.swing.JColorChooser;
import javax.swing.JPopupMenu;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;
import javax.swing.plaf.ComponentUI;

/** This component lets the user manipulate the colors in a gradient.
* A <code>GradientSlider</code> can contain any number of thumbs.  The
* slider itself represents a range of values from zero to one, so the thumbs
* must always be within this range.  Each thumb maps to a specific <code>Color</code>.
* <P>There are some specific properties you can set to customize the look-and-feel
* of this slider in the default {@link org.gephi.ui.components.gradientslider.GradientSliderUI} class.
* <P>The UI for each slider is loaded from the UIManager property: "GradientSliderUI".
* By default this is "org.gephi.ui.components.gradientslider.GradientSliderUI".
*/
//Author Jeremy Wood
public class GradientSlider extends MultiThumbSlider {

    private static final long serialVersionUID = 1L;


    static {
        if (UIManager.getString("GradientSliderUI") == null) {
            UIManager.put("GradientSliderUI", "org.gephi.ui.components.gradientslider.GradientSliderUI");
        }
    }

    /** Create a horizontal <code>GradientSlider</code> that
     * represents a gradient from white to black.
     */
    public GradientSlider() {
        this(HORIZONTAL);
    }

    /** Create a <code>GradientSlider</code> that represents a
     * gradient form white to black.
     * @param orientation HORIZONTAL or VERTICAL
     */
    public GradientSlider(int orientation) {
        this(orientation, new float[]{0f, 1f}, new Color[]{Color.white, Color.black});
    }

    /** Create a new <code>GradientSlider</code>.
     *
     * @param orientation HORIZONTAL or VERTICAL
     * @param thumbPositions the initial positions of each thumb
     * @param values the initial colors at each position
     * @throws IllegalArgumentException if the number of elements in
     * <code>thumbPositions</code> does not equal the number of elements
     * in <code>values</code>.
     *
     */
    public GradientSlider(int orientation, float[] thumbPositions, Color[] values) {
        super(orientation, thumbPositions, values);
    }

    /** Returns the Color at the specified position.
     */
    public Object getValue(float pos) {
        for (int a = 0; a < thumbPositions.length - 1; a++) {
            if (thumbPositions[a] == pos) {
                return values[a];
            }
            if (thumbPositions[a] < pos && pos < thumbPositions[a + 1]) {
                float v = (pos - thumbPositions[a]) / (thumbPositions[a + 1] - thumbPositions[a]);
                return tween((Color) values[a], (Color) values[a + 1], v);
            }
        }
        if (pos < thumbPositions[0]) {
            return (Color) values[0];
        }
        if (pos > thumbPositions[thumbPositions.length - 1]) {
            return (Color) values[values.length - 1];
        }
        return null;
    }

    /** This is identical to <code>getValues()</code>,
     * except the return value is an array of <code>Colors</code>.
     */
    public Color[] getColors() {
        Color[] c = new Color[values.length];
        for (int a = 0; a < c.length; a++) {
            c[a] = (Color) values[a];
        }
        return c;
    }

    private static Color tween(Color c1, Color c2, float p) {
        return new Color(
                (int) (c1.getRed() * (1 - p) + c2.getRed() * (p)),
                (int) (c1.getGreen() * (1 - p) + c2.getGreen() * (p)),
                (int) (c1.getBlue() * (1 - p) + c2.getBlue() * (p)),
                (int) (c1.getAlpha() * (1 - p) + c2.getAlpha() * (p)));
    }

    /** This invokes a <code>ColorPicker</code> dialog to edit
     * the thumb at the selected index.
     *
     */
    public boolean doDoubleClick(int x, int y) {
        int i = getSelectedThumb();
        if (i != -1) {
            showColorPicker();
            //showJColorChooser();
            SwingUtilities.invokeLater(new SelectThumbRunnable(i));
            return true;
        } else {
            return false;
        }
    }

    class SelectThumbRunnable implements Runnable {

        int index;

        public SelectThumbRunnable(int i) {
            index = i;
        }

        public void run() {
            setSelectedThumb(index);
        }
    }
    /** The popup for contextual menus. */
    JPopupMenu popup;

    private JPopupMenu createPopup() {
        return new ColorPickerPopup();
    }

    abstract class AbstractPopup extends JPopupMenu {

        private static final long serialVersionUID = 1L;
        int lastSelectedThumb;
        PopupMenuListener popupMenuListener = new PopupMenuListener() {

            public void popupMenuCanceled(PopupMenuEvent e) {
                setValueIsAdjusting(false);
                SwingUtilities.invokeLater(new SelectThumbRunnable(lastSelectedThumb));
            }

            public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
                setValueIsAdjusting(false);
                SwingUtilities.invokeLater(new SelectThumbRunnable(lastSelectedThumb));
            }

            public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
                setValueIsAdjusting(true);
                SwingUtilities.invokeLater(new Runnable() {

                    public void run() {
                        getFocusableComponent().requestFocus();
                    }
                });
            }
        };

        public AbstractPopup() {
            addPopupMenuListener(popupMenuListener);
        }

        public abstract Component getFocusableComponent();

        public void show(Component c, int x, int y) {
            Color[] colors = getColors();
            lastSelectedThumb = getSelectedThumb();
            if (lastSelectedThumb != -1) {
                setColor(colors[lastSelectedThumb]);
                super.show(c, x, y);
            }
        }

        public abstract void setColor(Color c);
    }

    class ColorPickerPopup extends AbstractPopup {

        private static final long serialVersionUID = 1L;
        ColorPicker mini;
        KeyListener commitListener = new KeyAdapter() {

            public void keyPressed(KeyEvent e) {
                if (e.getKeyCode() == KeyEvent.VK_SPACE || e.getKeyCode() == KeyEvent.VK_ENTER) {
                    ColorPickerPopup.this.setVisible(false);
                }
            }
        };

        public ColorPickerPopup() {
            super();
            boolean includeOpacity = MultiThumbSliderUI.getProperty(GradientSlider.this, "GradientSlider.includeOpacity", "true").equals("true");

            mini = new ColorPicker(false, includeOpacity);
            mini.setMode(0);
            mini.setPreferredSize(new Dimension(220, 200));
            PropertyChangeListener p = new PropertyChangeListener() {

                public void propertyChange(PropertyChangeEvent evt) {
                    ColorPicker p = (ColorPicker) evt.getSource();
                    Color[] colors = getColors();
                    colors[lastSelectedThumb] = p.getColor();
                    setValues(getThumbPositions(), colors);
                }
            };
            mini.addPropertyChangeListener(ColorPicker.SELECTED_COLOR_PROPERTY, p);
            mini.addPropertyChangeListener(ColorPicker.OPACITY_PROPERTY, p);
            for (int a = 0; a < mini.getComponentCount(); a++) {
                Component c = mini.getComponent(a);
                c.addKeyListener(commitListener);
            }
            add(mini);
        }

        public Component getFocusableComponent() {
            return mini.getColorPanel();
        }

        public void setColor(Color c) {
            mini.setRGB(c.getRed(), c.getGreen(), c.getBlue());
        }
    }

    /** This shows a mini ColorPicker panel to let the user
     * change the selected color.
     */
    public boolean doPopup(int x, int y) {
        if (popup == null) {
            popup = createPopup();
        }
        popup.show(this, x, y);
        return true;
    }

    private Frame getFrame() {
        Window w = SwingUtilities.getWindowAncestor(this);
        if (w instanceof Frame) {
            return ((Frame) w);
        }
        return null;
    }

    private boolean showColorPicker() {
        Color[] colors = getColors();
        int i = getSelectedThumb();

        Frame frame = getFrame();

        boolean includeOpacity = MultiThumbSliderUI.getProperty(this, "GradientSlider.includeOpacity", "true").equals("true");
        colors[i] = ColorPicker.showDialog(frame, colors[i], includeOpacity);
        if (colors[i] != null) {
            setValues(getThumbPositions(), colors);
        }
        return true;
    }

    /** TODO: If developers don't want to bundle the ColorPicker with their programs,
     * they can use this method instead of <code>showColorPicker()</code>.
     */
    private void showJColorChooser() {
        Color[] colors = getColors();
        int i = getSelectedThumb();
        if (i >= 0 && i < colors.length) {
            colors[i] = JColorChooser.showDialog(this, "Choose a Color", colors[i]);
            if (colors[i] != null) {
                setValues(getThumbPositions(), colors);
            }
        }
    }

    public void updateUI() {
        String name = UIManager.getString("GradientSliderUI");
        try {
            Class c = Class.forName(name);
            Constructor[] constructors = c.getConstructors();
            for (int a = 0; a < constructors.length; a++) {
                Class[] types = constructors[a].getParameterTypes();
                if (types.length == 1 && types[0].equals(GradientSlider.class)) {
                    ComponentUI ui = (ComponentUI) constructors[a].newInstance(new Object[]{this});
                    setUI(ui);
                    return;
                }
            }
        } catch (ClassNotFoundException e) {
            throw new RuntimeException("The class \"" + name + "\" could not be found.");
        } catch (Throwable t) {
            RuntimeException e = new RuntimeException("The class \"" + name + "\" could not be constructed.");
            e.initCause(t);
            throw e;
        }
    }
}
TOP

Related Classes of org.gephi.ui.components.gradientslider.GradientSlider$ColorPickerPopup

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.