274 lines
7.8 KiB
C++
274 lines
7.8 KiB
C++
//=============================================================================
|
|
// Awl
|
|
// Audio Widget Library
|
|
//
|
|
// 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 constructor
|
|
//---------------------------------------------------------
|
|
|
|
Knob::Knob(QWidget* parent)
|
|
: AbstractSlider(parent)
|
|
{
|
|
_spanDegrees = 270;
|
|
_markSize = 6;
|
|
_border = 2;
|
|
points = 0;
|
|
startY = 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::setSpanDegrees(double val)
|
|
{
|
|
if (val != _spanDegrees) {
|
|
_spanDegrees = 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();
|
|
}
|
|
}
|
|
|
|
//---------------------------------------------------------
|
|
// setKnobIcon
|
|
//---------------------------------------------------------
|
|
|
|
void Knob::setKnobIcon(const QIcon& icon)
|
|
{
|
|
_knobIcon = icon;
|
|
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())) {
|
|
auto centerVal = (maxValue() - minValue()) / 2 + 0.5;
|
|
setValue(centerVal);
|
|
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 emptyDegrees = 360 - _spanDegrees;
|
|
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; // top align
|
|
h = w;
|
|
}
|
|
|
|
int x = xoffset + _scaleWidth / 2 + _border;
|
|
int y = yoffset + _scaleWidth / 2 + _border + (_center ? _markSize+_scaleWidth/2 : 0);
|
|
QRectF dialArea(x, y, w, h);
|
|
|
|
QColor dialBgCol(isEnabled() ? _scaleColor : Qt::gray);
|
|
QColor dialCol(isEnabled() ? _scaleValueColor : Qt::lightGray);
|
|
|
|
//-----------------------------------------
|
|
// draw arc
|
|
//-----------------------------------------
|
|
|
|
double maxVal = maxValue();
|
|
double minVal = minValue();
|
|
double val = value();
|
|
|
|
double span = maxVal - minVal;
|
|
|
|
p.setPen(QPen(dialBgCol, _scaleWidth));
|
|
p.drawArc(dialArea, (90 + (_spanDegrees / 2)) * 16, -_spanDegrees * 16);
|
|
|
|
if (_center) {
|
|
double frac = (val - minVal) / span - 0.5;
|
|
|
|
p.setPen(QPen(dialCol, _scaleWidth));
|
|
p.drawArc(dialArea, 90 * 16, -frac * _spanDegrees * 16);
|
|
}
|
|
else {
|
|
double frac = (val - minVal) / span;
|
|
|
|
p.setPen(QPen(dialBgCol, _scaleWidth));
|
|
p.drawArc(dialArea, (90 + (_spanDegrees / 2)) * 16, frac * -_spanDegrees * 16);
|
|
}
|
|
|
|
//-----------------------------------------
|
|
// draw pointer
|
|
//-----------------------------------------
|
|
|
|
//knob image
|
|
if (!_knobIcon.isNull()) {
|
|
QRect r((int)dialArea.x(), (int)dialArea.y(), (int)dialArea.width(), (int)dialArea.height());
|
|
_knobIcon.paint(&p, r);
|
|
}
|
|
|
|
//indicator line
|
|
p.setPen(QPen(dialCol, _scaleWidth));
|
|
double r1 = double(_spanDegrees) * (_value - _minValue) / span + 90.0
|
|
+ double(emptyDegrees / 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(dialCol, 0));
|
|
p.setBrush(dialCol);
|
|
if (_center) {
|
|
if (points)
|
|
delete points;
|
|
qreal x3 = dialArea.width() / 2 + dialArea.x();
|
|
qreal y3 = dialArea.y() - _markSize - _scaleWidth/2;
|
|
points = new QPainterPath(QPointF(x3 - markSize2, y3));
|
|
points->lineTo(x3 + markSize2, y3);
|
|
points->lineTo(x3, _markSize + y3);
|
|
points->closeSubpath();
|
|
p.drawPath(*points);
|
|
}
|
|
|
|
//-----------------------------------------
|
|
// draw text
|
|
//-----------------------------------------
|
|
|
|
if (!_text.isEmpty()) {
|
|
p.drawText(dialArea, Qt::AlignBottom | Qt::AlignHCenter, _text);
|
|
}
|
|
}
|
|
}
|
|
|