282 lines
8.3 KiB
C++
282 lines
8.3 KiB
C++
//=============================================================================
|
|
// Awl
|
|
// Audio Widget Library
|
|
// $Id:$
|
|
//
|
|
// Copyright (C) 2002-2006 by Werner Schweer and others
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License version 2.
|
|
//
|
|
// 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.
|
|
//
|
|
// You should have received a copy of the GNU General Public License
|
|
// along with this program; if not, write to the Free Software
|
|
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
//=============================================================================
|
|
|
|
#include "knob.h"
|
|
|
|
namespace Awl {
|
|
|
|
//---------------------------------------------------------
|
|
// Knob
|
|
/// this is the AwlKnob contructor
|
|
//---------------------------------------------------------
|
|
|
|
Knob::Knob(QWidget* parent)
|
|
: AbstractSlider(parent)
|
|
{
|
|
_scaleSize = 270;
|
|
_markSize = 6;
|
|
_border = 2;
|
|
points = 0;
|
|
}
|
|
|
|
//---------------------------------------------------------
|
|
// Knob
|
|
//---------------------------------------------------------
|
|
|
|
Knob::~Knob()
|
|
{
|
|
if (points)
|
|
delete points;
|
|
}
|
|
|
|
//---------------------------------------------------------
|
|
// setText
|
|
//---------------------------------------------------------
|
|
|
|
void Knob::setText(const QString& s)
|
|
{
|
|
if (s != _text) {
|
|
_text = s;
|
|
update();
|
|
}
|
|
}
|
|
|
|
//---------------------------------------------------------
|
|
// setScaleSize
|
|
//! set the scale size in degrees
|
|
//
|
|
//! the scale size is the max moving angle measured
|
|
//! in degrees
|
|
//---------------------------------------------------------
|
|
|
|
void Knob::setScaleSize(int val)
|
|
{
|
|
if (val != _scaleSize) {
|
|
_scaleSize = val;
|
|
update();
|
|
}
|
|
}
|
|
|
|
//---------------------------------------------------------
|
|
// setMarkSize
|
|
//! set size of the center marker
|
|
//---------------------------------------------------------
|
|
|
|
void Knob::setMarkSize(int val)
|
|
{
|
|
if (val != _markSize) {
|
|
_markSize = val;
|
|
update();
|
|
}
|
|
}
|
|
|
|
//---------------------------------------------------------
|
|
// setBorder
|
|
//! set border size
|
|
//---------------------------------------------------------
|
|
|
|
void Knob::setBorder(int val)
|
|
{
|
|
if (val != _border) {
|
|
_border = val;
|
|
update();
|
|
}
|
|
}
|
|
|
|
//---------------------------------------------------------
|
|
// mousePressEvent
|
|
//---------------------------------------------------------
|
|
|
|
void Knob::mousePressEvent(QMouseEvent* ev)
|
|
{
|
|
startY = ev->y();
|
|
emit sliderPressed(_id);
|
|
if (_center) {
|
|
QRect r(points->boundingRect().toRect());
|
|
if (r.contains(ev->pos())) {
|
|
setValue(.0f);
|
|
valueChange();
|
|
}
|
|
}
|
|
}
|
|
|
|
//---------------------------------------------------------
|
|
// mouseReleaseEvent
|
|
//---------------------------------------------------------
|
|
|
|
void Knob::mouseReleaseEvent(QMouseEvent*)
|
|
{
|
|
emit sliderReleased(_id);
|
|
}
|
|
|
|
//---------------------------------------------------------
|
|
// mouseMoveEvent
|
|
//---------------------------------------------------------
|
|
|
|
void Knob::mouseMoveEvent(QMouseEvent* ev)
|
|
{
|
|
int y = ev->y();
|
|
double delta = (maxValue() - minValue()) / 100.0f;
|
|
if (delta == 0)
|
|
delta = 1;
|
|
_value += (startY - y) * delta;
|
|
if (_value < minValue())
|
|
_value = _minValue;
|
|
else if (_value > maxValue())
|
|
_value = _maxValue;
|
|
startY = y;
|
|
valueChange();
|
|
}
|
|
|
|
//---------------------------------------------------------
|
|
// paintEvent
|
|
// r - phys coord system
|
|
//---------------------------------------------------------
|
|
|
|
void Knob::paintEvent(QPaintEvent* /*ev*/)
|
|
{
|
|
#if 0 // yet(?) unused
|
|
QRect rr(ev->rect());
|
|
#endif
|
|
QPainter p(this);
|
|
p.setRenderHint(QPainter::Antialiasing, true);
|
|
|
|
int markSize2 = _markSize/2;
|
|
int restR = 360 - _scaleSize;
|
|
int w = width() - _scaleWidth - 2 * _border;
|
|
int h = height() - _scaleWidth/2 - 2 * _border;
|
|
|
|
int xoffset, yoffset;
|
|
if (_center)
|
|
h -= _markSize;
|
|
if (w > h) {
|
|
yoffset = 0;
|
|
xoffset = (w - h) / 2;
|
|
w = h;
|
|
}
|
|
else {
|
|
xoffset = 0;
|
|
// yoffset = (h - w) / 2; // center
|
|
yoffset = h - w; // top align
|
|
h = w;
|
|
}
|
|
|
|
int x = xoffset + _scaleWidth / 2 + _border;
|
|
int y = yoffset + _scaleWidth / 2 + _border + (_center ? _markSize+_scaleWidth/2 : 0);
|
|
QRectF ar(x, y, w, h);
|
|
|
|
QColor sc(isEnabled() ? _scaleColor : Qt::gray);
|
|
QColor svc(isEnabled() ? _scaleValueColor : Qt::gray);
|
|
|
|
//-----------------------------------------
|
|
// draw arc
|
|
//-----------------------------------------
|
|
|
|
double dvalue = maxValue() - minValue();
|
|
if (_center) {
|
|
int size = _scaleSize * 8;
|
|
if (_value >= 0) {
|
|
int offset = (restR-180) * 8;
|
|
int r1 = int (size * _value / maxValue());
|
|
int r2 = size - r1;
|
|
p.setPen(QPen(sc, _scaleWidth));
|
|
if (r2 > 1)
|
|
p.drawArc(ar, offset, r2);
|
|
if (size > 1)
|
|
p.drawArc(ar, 90*16, size);
|
|
if (r1 > 1) {
|
|
p.setPen(QPen(svc, _scaleWidth));
|
|
p.drawArc(ar, offset+r2, r1);
|
|
}
|
|
}
|
|
else {
|
|
// int offset = (restR+180) * 8;
|
|
int r1 = int(size * _value / minValue());
|
|
int r2 = size - r1;
|
|
|
|
p.setPen(QPen(sc, _scaleWidth));
|
|
if (size > 1)
|
|
p.drawArc(ar, (restR-180)*8, size);
|
|
if (r2 > 1)
|
|
p.drawArc(ar, 90 * 16 + r1, r2);
|
|
if (r1 > 1) {
|
|
p.setPen(QPen(svc, _scaleWidth));
|
|
p.drawArc(ar, 90*16, r1);
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
int offset = (180-restR) * 8;
|
|
int size = _scaleSize * 16;
|
|
int r1 = int(size * (_value - minValue()) / dvalue);
|
|
int r2 = size - r1;
|
|
if (r2 >= 1) {
|
|
p.setPen(QPen(sc, _scaleWidth));
|
|
p.drawArc(ar, -offset, r2);
|
|
}
|
|
if (r1 >= 1) {
|
|
p.setPen(QPen(svc, _scaleWidth));
|
|
p.drawArc(ar, r2-offset, r1);
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------
|
|
// draw pointer
|
|
//-----------------------------------------
|
|
|
|
p.setPen(QPen(svc, _scaleWidth));
|
|
double r1 = double(_scaleSize) * (_value-minValue()) / dvalue + 90.0
|
|
+ double(restR/2);
|
|
r1 = r1 / 180.0 * M_PI; // convert to radians
|
|
int rd = w/2;
|
|
int x1 = x + rd;
|
|
int y1 = y + rd;
|
|
int x2 = x1 + lrint(cos(r1) * double(rd));
|
|
int y2 = y1 + lrint(sin(r1) * double(rd));
|
|
p.drawLine(x1, y1, x2, y2);
|
|
|
|
//-----------------------------------------
|
|
// draw center mark
|
|
//-----------------------------------------
|
|
|
|
p.setPen(QPen(svc, 0));
|
|
p.setBrush(svc);
|
|
if (_center) {
|
|
if (points)
|
|
delete points;
|
|
qreal x = ar.width() / 2 + ar.x();
|
|
qreal y = ar.y() - _markSize - _scaleWidth/2;
|
|
points = new QPainterPath(QPointF(x - markSize2, y));
|
|
points->lineTo(x + markSize2, y);
|
|
points->lineTo(x, _markSize + y);
|
|
points->closeSubpath();
|
|
p.drawPath(*points);
|
|
}
|
|
|
|
//-----------------------------------------
|
|
// draw text
|
|
//-----------------------------------------
|
|
|
|
if (!_text.isEmpty()) {
|
|
p.drawText(ar, Qt::AlignBottom | Qt::AlignHCenter, _text);
|
|
}
|
|
}
|
|
}
|
|
|