package org.basex.gui.layout; import static org.basex.gui.layout.BaseXKeys.*; import java.awt.Color; import java.awt.Graphics; import java.awt.Window; import java.awt.event.ActionListener; import java.awt.event.FocusAdapter; import java.awt.event.FocusEvent; import java.awt.event.KeyEvent; import java.awt.event.MouseEvent; import org.basex.gui.GUIConstants; import org.basex.gui.GUIConstants.Fill; import org.basex.gui.dialog.Dialog; /** * Project specific slider implementation. * * @author BaseX Team 2005-12, BSD License * @author Christian Gruen */ public final class BaseXSlider extends BaseXPanel { /** Slider width. */ private static final double SLIDERW = 20; /** Listener. */ private final Dialog dl; /** Minimum slider value. */ private final int min; /** Maximum slider value. */ private final int max; /** Listener. */ private ActionListener al; /** Current slider value. */ private int curr; /** Current slider value. */ private int oldCurr = -1; /** Mouse position for dragging operations. */ private int mouseX; /** * Constructor. * @param mn min value * @param mx max value * @param i initial value * @param list listener * @param w reference to the main window */ public BaseXSlider(final ActionListener list, final int mn, final int mx, final int i, final Window w) { this(mn, mx, i, w); al = list; } /** * Constructor. * @param mn min value * @param mx max value * @param i initial value * @param w parent window */ public BaseXSlider(final int mn, final int mx, final int i, final Window w) { super(w); min = mn; max = mx; curr = i; dl = w instanceof Dialog ? (Dialog) w : null; mode(Fill.NONE).setFocusable(true); BaseXLayout.setHeight(this, getFont().getSize() + 3); addFocusListener(new FocusAdapter() { @Override public void focusGained(final FocusEvent e) { repaint(); } @Override public void focusLost(final FocusEvent e) { repaint(); } }); addKeyListener(this); addMouseListener(this); addMouseMotionListener(this); } /** * Returns the current value. * @return current value */ public int value() { return curr; } /** * Sets a slider value. * @param v new value */ public void value(final int v) { curr = v; repaint(); } @Override public void paintComponent(final Graphics g) { super.paintComponent(g); final int w = getWidth(); final int h = getHeight(); final int hh = h / 2; g.setColor(hasFocus() ? Color.white : GUIConstants.LGRAY); g.fillRect(0, hh - 2, w, 4); g.setColor(Color.black); g.drawLine(0, hh - 2, w, hh - 2); g.drawLine(0, hh - 2, 0, hh + 2); g.setColor(GUIConstants.GRAY); g.drawLine(w - 1, hh - 2, w - 1, hh + 2); g.drawLine(0, hh + 2, w, hh + 2); final double x = (curr - min) * (w - SLIDERW) / (max - min); BaseXLayout.drawCell(g, (int) x, (int) (x + SLIDERW), hh - 5, hh + 5, oldCurr != -1); } @Override public void mouseMoved(final MouseEvent e) { mouseX = e.getX(); } @Override public void mousePressed(final MouseEvent e) { requestFocusInWindow(); mouseX = e.getX(); final double w = getWidth() - SLIDERW; final double r = max - min; final double x = (curr - min) * w / r; if(mouseX < x || mouseX >= x + SLIDERW) curr = (int) (mouseX * r / w + min); oldCurr = curr; repaint(); } @Override public void mouseReleased(final MouseEvent e) { oldCurr = -1; repaint(); } @Override public void mouseDragged(final MouseEvent e) { final double prop = (max - min) * (mouseX - e.getX()) / (getWidth() - SLIDERW); final int old = curr; curr = Math.max(min, Math.min(max, (int) (oldCurr - prop))); if(curr != old) { if(dl != null) dl.action(null); else al.actionPerformed(null); repaint(); } } @Override public void keyPressed(final KeyEvent e) { final int old = curr; if(PREV.is(e) || PREVLINE.is(e)) { curr = Math.max(min, curr - 1); } else if(NEXT.is(e) || NEXTLINE.is(e)) { curr = Math.min(max, curr + 1); } else if(NEXTPAGE.is(e)) { curr = Math.max(min, curr + 10); } else if(PREVPAGE.is(e)) { curr = Math.min(max, curr - 10); } else if(LINESTART.is(e)) { curr = min; } else if(LINEEND.is(e)) { curr = max; } if(curr != old) { if(dl != null) dl.action(null); else al.actionPerformed(null); repaint(); } } }