kopia lustrzana https://gitlab.com/Teuniz/DSRemote
490 wiersze
8.3 KiB
C++
490 wiersze
8.3 KiB
C++
/*
|
|
***************************************************************************
|
|
*
|
|
* Author: Teunis van Beelen
|
|
*
|
|
* Copyright (C) 2016 - 2023 Teunis van Beelen
|
|
*
|
|
* Email: teuniz@protonmail.com
|
|
*
|
|
***************************************************************************
|
|
*
|
|
* This program is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* 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, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
***************************************************************************
|
|
*/
|
|
|
|
|
|
|
|
#include "tdial.h"
|
|
|
|
#include <math.h>
|
|
|
|
|
|
TDial::TDial(QWidget *w_parent) : QWidget(w_parent)
|
|
{
|
|
fg_color = QColor(100, 100, 100);
|
|
bg_color = Qt::lightGray;
|
|
notch_visible = false;
|
|
wrap = false;
|
|
dmin = 0;
|
|
dmax = 2;
|
|
step = 1;
|
|
slider_down = false;
|
|
dval = 1;
|
|
dval_old = 1;
|
|
enabled = true;
|
|
mouse_grad_old=180;
|
|
dial_grad = 180;
|
|
degr_per_step = 1;
|
|
}
|
|
|
|
|
|
void TDial::paintEvent(QPaintEvent *)
|
|
{
|
|
int w, h, r0, hor_a, hor_b, vert_a, vert_b, gr;
|
|
|
|
double r1, r2, r3, r4, dtmp;
|
|
|
|
QPainter p(this);
|
|
#if (QT_VERSION >= 0x050000) && (QT_VERSION < 0x060000)
|
|
p.setRenderHint(QPainter::Qt4CompatiblePainting, true);
|
|
#endif
|
|
|
|
p.save();
|
|
|
|
w = width();
|
|
h = height();
|
|
|
|
r0 = w;
|
|
if(r0 > h) r0 = h;
|
|
|
|
r0 /= 2;
|
|
|
|
p.setRenderHint(QPainter::Antialiasing);
|
|
|
|
if(enabled == true)
|
|
{
|
|
QRadialGradient gradient((w / 2) - (r0 * 0.5), (h / 2) - (r0 * 0.5), r0);
|
|
gradient.setColorAt(0.001, QColor(250, 250, 250));
|
|
gradient.setColorAt(0.9, QColor(228, 228, 228));
|
|
gradient.setColorAt(1, QColor(215, 215, 215));
|
|
p.setBrush(gradient);
|
|
draw_fill_circ(w / 2, h / 2, r0 * 0.8, &p);
|
|
|
|
p.setPen(fg_color);
|
|
}
|
|
else
|
|
{
|
|
p.setPen(fg_color);
|
|
|
|
draw_circ(w / 2, h / 2, r0 * 0.8, &p);
|
|
}
|
|
|
|
if(notch_visible == true)
|
|
{
|
|
r1 = r0;
|
|
r2 = r0 * 0.85;
|
|
r3 = r0 * 0.98;
|
|
r4 = r0 * 0.9;
|
|
|
|
if(r0 < 30)
|
|
{
|
|
step = 20;
|
|
}
|
|
else
|
|
{
|
|
step = 12;
|
|
}
|
|
|
|
for(gr=0; gr<360; gr+=step)
|
|
{
|
|
if(wrap == false)
|
|
{
|
|
if((gr > 240) && (gr < 300)) continue;
|
|
}
|
|
if(gr % 60)
|
|
{
|
|
vert_a = r3 * sin(gr * M_PI / 180.0);
|
|
hor_a = r3 * cos(gr * M_PI / 180.0);
|
|
|
|
vert_b = r4 * sin(gr * M_PI / 180.0);
|
|
hor_b = r4 * cos(gr * M_PI / 180.0);
|
|
}
|
|
else
|
|
{
|
|
vert_a = r1 * sin(gr * M_PI / 180.0);
|
|
hor_a = r1 * cos(gr * M_PI / 180.0);
|
|
|
|
vert_b = r2 * sin(gr * M_PI / 180.0);
|
|
hor_b = r2 * cos(gr * M_PI / 180.0);
|
|
}
|
|
|
|
p.drawLine((w / 2) - hor_b, (h / 2) - vert_b, (w / 2) - hor_a, (h / 2) - vert_a);
|
|
}
|
|
}
|
|
|
|
dtmp = dial_grad - 90;
|
|
if(dtmp < 0) dtmp += 360;
|
|
|
|
vert_a = r0 * 0.55 * sin(dtmp * M_PI / 180.0);
|
|
hor_a = r0 * 0.55 * cos(dtmp * M_PI / 180.0);
|
|
|
|
if(enabled == true)
|
|
{
|
|
p.setBrush(QBrush(QColor(210, 210, 210)));
|
|
}
|
|
else
|
|
{
|
|
p.setBrush(QBrush(QColor(220, 220, 220)));
|
|
}
|
|
|
|
draw_fill_circ(w / 2 - hor_a, h / 2 - vert_a, r0 * 0.15, &p);
|
|
|
|
p.restore();
|
|
}
|
|
|
|
|
|
void TDial::mousePressEvent(QMouseEvent *press_event)
|
|
{
|
|
if(press_event->button()==Qt::LeftButton)
|
|
{
|
|
slider_down = true;
|
|
setMouseTracking(true);
|
|
#if QT_VERSION < 0x060000
|
|
mouse_grad_old = polar_to_degr(press_event->x() - (width() / 2), press_event->y() - (height() / 2));
|
|
#else
|
|
mouse_grad_old = polar_to_degr(press_event->position().x() - (width() / 2), press_event->position().y() - (height() / 2));
|
|
#endif
|
|
}
|
|
|
|
press_event->accept();
|
|
}
|
|
|
|
|
|
void TDial::mouseReleaseEvent(QMouseEvent *release_event)
|
|
{
|
|
if(release_event->button()==Qt::LeftButton)
|
|
{
|
|
setMouseTracking(false);
|
|
slider_down = false;
|
|
|
|
emit sliderReleased();
|
|
}
|
|
|
|
release_event->accept();
|
|
}
|
|
|
|
|
|
void TDial::mouseMoveEvent(QMouseEvent *move_event)
|
|
{
|
|
double gr_new,
|
|
gr_diff;
|
|
|
|
if(slider_down == false) return;
|
|
#if QT_VERSION < 0x060000
|
|
gr_new = polar_to_degr(move_event->x() - (width() / 2), move_event->y() - (height() / 2));
|
|
#else
|
|
gr_new = polar_to_degr(move_event->position().x() - (width() / 2), move_event->position().y() - (height() / 2));
|
|
#endif
|
|
gr_diff = gr_new - mouse_grad_old;
|
|
|
|
mouse_grad_old = gr_new;
|
|
|
|
dial_grad += gr_diff;
|
|
|
|
process_rotation();
|
|
|
|
move_event->accept();
|
|
}
|
|
|
|
|
|
bool TDial::isSliderDown(void)
|
|
{
|
|
return slider_down;
|
|
}
|
|
|
|
|
|
void TDial::setWrapping(bool wr)
|
|
{
|
|
wrap = wr;
|
|
update();
|
|
}
|
|
|
|
|
|
void TDial::setNotchesVisible(bool vis)
|
|
{
|
|
notch_visible = vis;
|
|
update();
|
|
}
|
|
|
|
|
|
void TDial::setMaximum(int m)
|
|
{
|
|
dmax = m;
|
|
if(dmax < 2) dmax = 2;
|
|
if(dmin >= dmax) dmin = dmax - 1;
|
|
if(dmin < 0) dmin = 0;
|
|
if(wrap == true)
|
|
{
|
|
degr_per_step = 360.0 / ((double)(dmax - dmin) / (double)step);
|
|
}
|
|
else
|
|
{
|
|
degr_per_step = 300.0 / ((double)(dmax - dmin) / (double)step);
|
|
}
|
|
|
|
dval = (dmax + dmin) / 2;
|
|
|
|
dval_old = dval;
|
|
|
|
update();
|
|
}
|
|
|
|
|
|
void TDial::setMinimum(int m)
|
|
{
|
|
dmin = m;
|
|
if(dmin >= dmax) dmax = dmin + 1;
|
|
if(dmax < 2) dmax = 2;
|
|
if(dmin >= dmax) dmin = dmax - 1;
|
|
if(dmin < 0) dmin = 0;
|
|
if(wrap == true)
|
|
{
|
|
degr_per_step = 360.0 / ((double)(dmax - dmin) / (double)step);
|
|
}
|
|
else
|
|
{
|
|
degr_per_step = 300.0 / ((double)(dmax - dmin) / (double)step);
|
|
}
|
|
|
|
dval = (dmax + dmin) / 2;
|
|
|
|
dval_old = dval;
|
|
|
|
update();
|
|
}
|
|
|
|
|
|
void TDial::setValue(int v)
|
|
{
|
|
dval = v;
|
|
|
|
if(dval > dmax) dval = dmax;
|
|
if(dval < dmin) dval = dmin;
|
|
|
|
if(wrap == true)
|
|
{
|
|
dial_grad = ((double)(dval - dmin) / (double)(dmax - dmin)) * 360.0;
|
|
}
|
|
else
|
|
{
|
|
dial_grad = (((double)(dval - dmin) / (double)(dmax - dmin)) * 300.0) + 30.0;
|
|
}
|
|
|
|
dval_old = dval;
|
|
|
|
update();
|
|
}
|
|
|
|
|
|
void TDial::setSliderPosition(int v)
|
|
{
|
|
dval = v;
|
|
|
|
if(dval > dmax) dval = dmax;
|
|
if(dval < dmin) dval = dmin;
|
|
|
|
if(wrap == true)
|
|
{
|
|
dial_grad = ((double)(dval - dmin) / (double)(dmax - dmin)) * 360.0;
|
|
}
|
|
else
|
|
{
|
|
dial_grad = (((double)(dval - dmin) / (double)(dmax - dmin)) * 300.0) + 30.0;
|
|
}
|
|
|
|
dval_old = dval;
|
|
|
|
update();
|
|
}
|
|
|
|
|
|
int TDial::value(void)
|
|
{
|
|
return dval;
|
|
}
|
|
|
|
|
|
void TDial::setSingleStep(int s)
|
|
{
|
|
step = s;
|
|
if(step > dmax) step = dmax;
|
|
if(step < 1) step = 1;
|
|
if(wrap == true)
|
|
{
|
|
degr_per_step = 360.0 / ((double)(dmax - dmin) / (double)step);
|
|
}
|
|
else
|
|
{
|
|
degr_per_step = 300.0 / ((double)(dmax - dmin) / (double)step);
|
|
}
|
|
update();
|
|
}
|
|
|
|
|
|
void TDial::set_fg_color(QColor new_color)
|
|
{
|
|
fg_color = new_color;
|
|
update();
|
|
}
|
|
|
|
|
|
void TDial::set_bg_color(QColor new_color)
|
|
{
|
|
bg_color = new_color;
|
|
update();
|
|
}
|
|
|
|
|
|
QColor TDial::get_fg_color(void)
|
|
{
|
|
return fg_color;
|
|
}
|
|
|
|
|
|
QColor TDial::get_bg_color(void)
|
|
{
|
|
return bg_color;
|
|
}
|
|
|
|
|
|
void TDial::draw_circ(int px, int py, int r, QPainter *p)
|
|
{
|
|
p->drawArc(px - r, py - r, r * 2, r * 2, 0, 5760);
|
|
}
|
|
|
|
|
|
void TDial::draw_fill_circ(int px, int py, int r, QPainter *p)
|
|
{
|
|
p->drawEllipse(px - r, py - r, r * 2, r * 2);
|
|
}
|
|
|
|
|
|
void TDial::setEnabled(bool enab)
|
|
{
|
|
enabled = enab;
|
|
update();
|
|
}
|
|
|
|
|
|
double TDial::polar_to_degr(double px, double py)
|
|
{
|
|
int quad=0;
|
|
|
|
double gr;
|
|
|
|
if(px < 0)
|
|
{
|
|
quad += 2;
|
|
|
|
px *= -1;
|
|
}
|
|
|
|
if(py < 0)
|
|
{
|
|
quad += 1;
|
|
|
|
py *= -1;
|
|
}
|
|
|
|
if(px < 0.01) px = 0.01;
|
|
if(py < 0.01) py = 0.01;
|
|
|
|
gr = atan(py / px) * 180.0 / M_PI;
|
|
|
|
switch(quad)
|
|
{
|
|
case 0: gr += 270;
|
|
break;
|
|
case 1: gr = 270 - gr;
|
|
break;
|
|
case 2: gr = 90 - gr;
|
|
break;
|
|
case 3: gr += 90;
|
|
break;
|
|
}
|
|
|
|
return gr;
|
|
}
|
|
|
|
|
|
void TDial::wheelEvent(QWheelEvent *wheel_event)
|
|
{
|
|
#if QT_VERSION >= 0x050C00
|
|
dial_grad += (wheel_event->angleDelta().y() / 8);
|
|
#else
|
|
dial_grad += (wheel_event->delta() / 8);
|
|
#endif
|
|
|
|
process_rotation();
|
|
|
|
wheel_event->accept();
|
|
}
|
|
|
|
|
|
void TDial::process_rotation(void)
|
|
{
|
|
if(dial_grad > 360) dial_grad -= 360;
|
|
|
|
if(dial_grad < 0) dial_grad += 360;
|
|
|
|
if(wrap == false)
|
|
{
|
|
if(dial_grad > 330)
|
|
{
|
|
dial_grad = 330;
|
|
}
|
|
else if(dial_grad < 30)
|
|
{
|
|
dial_grad = 30;
|
|
}
|
|
}
|
|
|
|
if(wrap == false)
|
|
{
|
|
dval = (dial_grad - 30) * ((double)(dmax - dmin) / 300.0);
|
|
}
|
|
else
|
|
{
|
|
dval = dial_grad * ((double)(dmax - dmin) / 360.0);
|
|
}
|
|
|
|
if(dval == dval_old) return;
|
|
|
|
dval_old = dval;
|
|
|
|
emit valueChanged(dval);
|
|
|
|
update();
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|