/*
* Jampa
* Copyright (C) 2008-2009 J. Devauchelle and contributors.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 3 as published by the Free Software Foundation.
*
* This program 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 General Public License for more details.
*/
package org.jampa.gui.components.sliders;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.events.MouseTrackAdapter;
import org.eclipse.swt.events.MouseWheelListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
public class BalanceSlider extends Composite {
private int mSelection;
private int mMinimum = -100;
private int mMaximum = 100;
private int mIncrement = 10;
private int mGauge = 10;
private int mMousePos = -1;
private boolean mMouseDown;
private List<SelectionListener> mListenerList = new ArrayList<SelectionListener>();
public BalanceSlider(final Composite parent, final int style) {
super(parent, SWT.NONE);
setForeground(parent.getDisplay().getSystemColor(SWT.COLOR_TITLE_INACTIVE_BACKGROUND));
addPaintListener(new PaintListener() {
public void paintControl(PaintEvent e) {
int x = 0;
int y = (getHeight() - getGauge()) / 2;
int width = getWidth() - 1;
int height = getGauge();
// Border.
if ((style & SWT.BORDER) > 0) {
e.gc.setForeground(parent.getDisplay().getSystemColor(SWT.COLOR_BLACK));
e.gc.drawLine(x, y, x + width, y);
e.gc.drawLine(x, y, x, y + height - 1);
e.gc.drawLine(x, y + height - 1, x + width, y + height - 1);
e.gc.drawLine(x + width, y, x + width, y + height - 1);
}
// Background
e.gc.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_WHITE));
e.gc.fillRectangle(x + 1, y + 1, width - 1, height - 2);
// Selection
int selectionX = (getWidth() / 2) + ((mSelection * getWidth()) / (2 * mMaximum));
if (isEnabled()) {
if (mSelection >= 0)
e.gc.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_GREEN));
else
e.gc.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_RED));
} else {
e.gc.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_TITLE_INACTIVE_FOREGROUND));
}
if (mSelection > 0) {
e.gc.fillRectangle(getWidth() / 2, y + 1, selectionX - (width / 2), height - 2);
} else if (mSelection < 0) {
e.gc.fillRectangle((selectionX == 0 ? 1 : selectionX), y + 1, (getWidth() / 2) - selectionX, height - 2);
}
// Center pos
e.gc.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_WIDGET_FOREGROUND));
e.gc.fillRectangle(x + (width / 2), y + 1, 1, height - 2);
// Mouse cursor
if (mMousePos >= 0) {
e.gc.setBackground(parent.getDisplay().getSystemColor(SWT.COLOR_WIDGET_FOREGROUND));
e.gc.fillRectangle(mMousePos, y, 2, height);
}
}
});
addMouseTrackListener(new MouseTrackAdapter() {
public void mouseExit(MouseEvent e) {
mMousePos = -1;
redraw();
update();
}
});
addMouseMoveListener(new MouseMoveListener() {
public void mouseMove(MouseEvent e) {
mMousePos = e.x;
if (mMouseDown) {
setSelection((int) (((2 * e.x * mMaximum) / getWidth()) - mMaximum));
fireSelectionEvent();
}
redraw();
update();
}
});
addMouseListener(new MouseAdapter() {
public void mouseDown(MouseEvent e) {
if (e.button == 1) {
mMouseDown = true;
setSelection((int) (((2 * e.x * mMaximum) / getWidth()) - mMaximum));
fireSelectionEvent();
}
}
public void mouseUp(MouseEvent e) {
if (e.button == 1) {
mMouseDown = false;
setSelection((int) (((2 * e.x * mMaximum) / getWidth()) - mMaximum));
fireSelectionEvent();
}
}
});
addMouseWheelListener(new MouseWheelListener() {
public void mouseScrolled(MouseEvent e) {
if (e.count > 0) {
setSelection(getSelection() + getIncrement());
fireSelectionEvent();
} else if (e.count < 0) {
setSelection(getSelection() - getIncrement());
fireSelectionEvent();
}
}
});
addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent e) {
if (e.keyCode == SWT.ARROW_LEFT || e.keyCode == SWT.PAGE_DOWN) {
setSelection(getSelection() - getIncrement());
fireSelectionEvent();
} else if (e.keyCode == SWT.ARROW_RIGHT || e.keyCode == SWT.PAGE_UP) {
setSelection(getSelection() + getIncrement());
fireSelectionEvent();
}
}
});
}
public int getMinimum() {
return mMinimum;
}
public void setMaximum(final int max) {
assert max > 0;
mMaximum = max;
mMinimum = -max;
redraw();
update();
}
public int getMaximum() {
return mMaximum;
}
public void setIncrement(final int inc) {
assert inc >= 0;
mIncrement = inc;
}
public int getIncrement() {
return mIncrement;
}
public void setSelection(final int value) {
mSelection = Math.max(-mMaximum, Math.min(value, mMaximum));
redraw();
update();
}
public int getSelection() {
return mSelection;
}
private int getWidth() {
return getBounds().width;
}
private int getHeight() {
return getBounds().height;
}
public void setGauge(final int gauge) {
mGauge = gauge;
redraw();
update();
}
public int getGauge() {
return mGauge > 0 ? mGauge : getHeight();
}
public void setEnabled(final boolean enabled) {
super.setEnabled(enabled);
redraw();
update();
}
public void addSelectionListener(final SelectionListener listener) {
mListenerList.add(listener);
}
private void fireSelectionEvent() {
for (SelectionListener l : mListenerList) {
Event e = new Event();
e.widget = this;
e.detail = mMouseDown ? SWT.DRAG : SWT.NONE;
l.widgetSelected(new SelectionEvent(e));
}
}
}