mirror of
https://github.com/f4exb/sdrangel.git
synced 2024-12-23 10:05:46 -05:00
ValueDialZ: new value dial that handles negative values. Application in TCPsrc plugin
This commit is contained in:
parent
93d1a5bae7
commit
e317f3762c
@ -165,6 +165,7 @@ set(sdrbase_SOURCES
|
||||
sdrbase/gui/scale.cpp
|
||||
sdrbase/gui/scaleengine.cpp
|
||||
sdrbase/gui/valuedial.cpp
|
||||
sdrbase/gui/valuedialz.cpp
|
||||
|
||||
sdrbase/dsp/devicesamplesource.cpp
|
||||
sdrbase/dsp/devicesamplesink.cpp
|
||||
@ -285,6 +286,7 @@ set(sdrbase_HEADERS
|
||||
sdrbase/gui/scale.h
|
||||
sdrbase/gui/scaleengine.h
|
||||
sdrbase/gui/valuedial.h
|
||||
sdrbase/gui/valuedialz.h
|
||||
|
||||
sdrbase/dsp/devicesamplesource.h
|
||||
sdrbase/dsp/devicesamplesink.h
|
||||
|
@ -207,7 +207,7 @@ TCPSrcGUI::TCPSrcGUI(PluginAPI* pluginAPI, DeviceSourceAPI *deviceAPI, QWidget*
|
||||
m_deviceAPI->addThreadedSink(m_threadedChannelizer);
|
||||
|
||||
ui->deltaFrequency->setColorMapper(ColorMapper(ColorMapper::GrayGold));
|
||||
ui->deltaFrequency->setValueRange(7, 0U, 9999999U);
|
||||
ui->deltaFrequency->setValueRange(false, 7, -9999999, 9999999);
|
||||
|
||||
ui->glSpectrum->setCenterFrequency(0);
|
||||
ui->glSpectrum->setSampleRate(ui->sampleRate->text().toInt());
|
||||
@ -282,8 +282,7 @@ void TCPSrcGUI::applySettings()
|
||||
int boost = ui->boost->value();
|
||||
|
||||
setTitleColor(m_channelMarker.getColor());
|
||||
ui->deltaFrequency->setValue(abs(m_channelMarker.getCenterFrequency()));
|
||||
ui->deltaMinus->setChecked(m_channelMarker.getCenterFrequency() < 0);
|
||||
ui->deltaFrequency->setValue(m_channelMarker.getCenterFrequency());
|
||||
ui->sampleRate->setText(QString("%1").arg(outputSampleRate, 0));
|
||||
ui->rfBandwidth->setText(QString("%1").arg(rfBandwidth, 0));
|
||||
ui->tcpPort->setText(QString("%1").arg(tcpPort));
|
||||
@ -332,24 +331,9 @@ void TCPSrcGUI::applySettings()
|
||||
}
|
||||
}
|
||||
|
||||
void TCPSrcGUI::on_deltaMinus_toggled(bool minus)
|
||||
void TCPSrcGUI::on_deltaFrequency_changed(qint64 value)
|
||||
{
|
||||
int deltaFrequency = m_channelMarker.getCenterFrequency();
|
||||
bool minusDelta = (deltaFrequency < 0);
|
||||
|
||||
if (minus ^ minusDelta) // sign change
|
||||
{
|
||||
m_channelMarker.setCenterFrequency(-deltaFrequency);
|
||||
}
|
||||
}
|
||||
|
||||
void TCPSrcGUI::on_deltaFrequency_changed(quint64 value)
|
||||
{
|
||||
if (ui->deltaMinus->isChecked()) {
|
||||
m_channelMarker.setCenterFrequency(-value);
|
||||
} else {
|
||||
m_channelMarker.setCenterFrequency(value);
|
||||
}
|
||||
m_channelMarker.setCenterFrequency(value);
|
||||
}
|
||||
|
||||
void TCPSrcGUI::on_sampleFormat_currentIndexChanged(int index)
|
||||
|
@ -42,8 +42,7 @@ public:
|
||||
|
||||
private slots:
|
||||
void channelMarkerChanged();
|
||||
void on_deltaFrequency_changed(quint64 value);
|
||||
void on_deltaMinus_toggled(bool minus);
|
||||
void on_deltaFrequency_changed(qint64 value);
|
||||
void on_sampleFormat_currentIndexChanged(int index);
|
||||
void on_sampleRate_textEdited(const QString& arg1);
|
||||
void on_rfBandwidth_textEdited(const QString& arg1);
|
||||
|
@ -149,29 +149,7 @@
|
||||
<number>2</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QToolButton" name="deltaMinus">
|
||||
<property name="toolTip">
|
||||
<string>Frequency shift direction</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
<property name="icon">
|
||||
<iconset>
|
||||
<selectedoff>:/plus.png</selectedoff>
|
||||
<selectedon>:/minus.png</selectedon>
|
||||
</iconset>
|
||||
</property>
|
||||
<property name="checkable">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="ValueDial" name="deltaFrequency" native="true">
|
||||
<widget class="ValueDialZ" name="deltaFrequency" native="true">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Maximum" vsizetype="Maximum">
|
||||
<horstretch>0</horstretch>
|
||||
@ -457,12 +435,6 @@
|
||||
<header>gui/rollupwidget.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>ValueDial</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>gui/valuedial.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>GLSpectrum</class>
|
||||
<extends>QWidget</extends>
|
||||
@ -475,6 +447,12 @@
|
||||
<header>gui/glspectrumgui.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
<customwidget>
|
||||
<class>ValueDialZ</class>
|
||||
<extends>QWidget</extends>
|
||||
<header>gui/valuedialz.h</header>
|
||||
<container>1</container>
|
||||
</customwidget>
|
||||
</customwidgets>
|
||||
<tabstops>
|
||||
<tabstop>sampleFormat</tabstop>
|
||||
@ -484,8 +462,6 @@
|
||||
<tabstop>applyBtn</tabstop>
|
||||
<tabstop>connections</tabstop>
|
||||
</tabstops>
|
||||
<resources>
|
||||
<include location="../../../sdrbase/resources/res.qrc"/>
|
||||
</resources>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
||||
|
@ -1,79 +1,79 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany //
|
||||
// written by Christian Daniel //
|
||||
// //
|
||||
// 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 as version 3 of the License, or //
|
||||
// //
|
||||
// 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 V3 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 <QWidget>
|
||||
#include <QTimer>
|
||||
#include "gui/colormapper.h"
|
||||
#include "util/export.h"
|
||||
|
||||
class SDRANGEL_API ValueDial : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ValueDial(QWidget* parent = NULL, ColorMapper colorMapper = ColorMapper(ColorMapper::Normal));
|
||||
|
||||
void setValue(quint64 value);
|
||||
void setValueRange(uint numDigits, quint64 min, quint64 max);
|
||||
void setFont(const QFont& font);
|
||||
void setBold(bool bold);
|
||||
void setColorMapper(ColorMapper colorMapper);
|
||||
quint64 getValue() const { return m_value; }
|
||||
quint64 getValueNew() const { return m_valueNew; }
|
||||
|
||||
signals:
|
||||
void changed(quint64 value);
|
||||
|
||||
private:
|
||||
QLinearGradient m_background;
|
||||
int m_numDigits;
|
||||
int m_numDecimalPoints;
|
||||
int m_digitWidth;
|
||||
int m_digitHeight;
|
||||
int m_hightlightedDigit;
|
||||
int m_cursor;
|
||||
bool m_cursorState;
|
||||
quint64 m_value;
|
||||
quint64 m_valueMax;
|
||||
quint64 m_valueMin;
|
||||
QString m_text;
|
||||
|
||||
quint64 m_valueNew;
|
||||
QString m_textNew;
|
||||
int m_animationState;
|
||||
QTimer m_animationTimer;
|
||||
QTimer m_blinkTimer;
|
||||
|
||||
ColorMapper m_colorMapper;
|
||||
|
||||
quint64 findExponent(int digit);
|
||||
QChar digitNeigh(QChar c, bool dir);
|
||||
QString formatText(quint64 value);
|
||||
|
||||
void paintEvent(QPaintEvent*);
|
||||
|
||||
void mousePressEvent(QMouseEvent*);
|
||||
void mouseMoveEvent(QMouseEvent*);
|
||||
void wheelEvent(QWheelEvent*);
|
||||
void leaveEvent(QEvent*);
|
||||
void keyPressEvent(QKeyEvent*);
|
||||
void focusInEvent(QFocusEvent*);
|
||||
void focusOutEvent(QFocusEvent*);
|
||||
|
||||
private slots:
|
||||
void animate();
|
||||
void blink();
|
||||
};
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany //
|
||||
// written by Christian Daniel //
|
||||
// //
|
||||
// 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 as version 3 of the License, or //
|
||||
// //
|
||||
// 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 V3 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 <QWidget>
|
||||
#include <QTimer>
|
||||
#include "gui/colormapper.h"
|
||||
#include "util/export.h"
|
||||
|
||||
class SDRANGEL_API ValueDial : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ValueDial(QWidget* parent = NULL, ColorMapper colorMapper = ColorMapper(ColorMapper::Normal));
|
||||
|
||||
void setValue(quint64 value);
|
||||
void setValueRange(uint numDigits, quint64 min, quint64 max);
|
||||
void setFont(const QFont& font);
|
||||
void setBold(bool bold);
|
||||
void setColorMapper(ColorMapper colorMapper);
|
||||
quint64 getValue() const { return m_value; }
|
||||
quint64 getValueNew() const { return m_valueNew; }
|
||||
|
||||
signals:
|
||||
void changed(quint64 value);
|
||||
|
||||
private:
|
||||
QLinearGradient m_background;
|
||||
int m_numDigits;
|
||||
int m_numDecimalPoints;
|
||||
int m_digitWidth;
|
||||
int m_digitHeight;
|
||||
int m_hightlightedDigit;
|
||||
int m_cursor;
|
||||
bool m_cursorState;
|
||||
quint64 m_value;
|
||||
quint64 m_valueMax;
|
||||
quint64 m_valueMin;
|
||||
QString m_text;
|
||||
|
||||
quint64 m_valueNew;
|
||||
QString m_textNew;
|
||||
int m_animationState;
|
||||
QTimer m_animationTimer;
|
||||
QTimer m_blinkTimer;
|
||||
|
||||
ColorMapper m_colorMapper;
|
||||
|
||||
quint64 findExponent(int digit);
|
||||
QChar digitNeigh(QChar c, bool dir);
|
||||
QString formatText(quint64 value);
|
||||
|
||||
void paintEvent(QPaintEvent*);
|
||||
|
||||
void mousePressEvent(QMouseEvent*);
|
||||
void mouseMoveEvent(QMouseEvent*);
|
||||
void wheelEvent(QWheelEvent*);
|
||||
void leaveEvent(QEvent*);
|
||||
void keyPressEvent(QKeyEvent*);
|
||||
void focusInEvent(QFocusEvent*);
|
||||
void focusOutEvent(QFocusEvent*);
|
||||
|
||||
private slots:
|
||||
void animate();
|
||||
void blink();
|
||||
};
|
||||
|
621
sdrbase/gui/valuedialz.cpp
Normal file
621
sdrbase/gui/valuedialz.cpp
Normal file
@ -0,0 +1,621 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2017 F4EXB //
|
||||
// written by Edouard Griffiths //
|
||||
// //
|
||||
// Same as ValueDial but handles optionally positive and negative numbers with //
|
||||
// sign display. //
|
||||
// //
|
||||
// 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 as version 3 of the License, or //
|
||||
// //
|
||||
// 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 V3 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 <QPainter>
|
||||
#include <QMouseEvent>
|
||||
#include <QWheelEvent>
|
||||
#include <QKeyEvent>
|
||||
#include "gui/valuedialz.h"
|
||||
|
||||
ValueDialZ::ValueDialZ(bool positiveOnly, QWidget* parent, ColorMapper colorMapper) :
|
||||
m_positiveOnly(positiveOnly),
|
||||
QWidget(parent),
|
||||
m_animationState(0),
|
||||
m_colorMapper(colorMapper)
|
||||
{
|
||||
setAutoFillBackground(false);
|
||||
setAttribute(Qt::WA_OpaquePaintEvent, true);
|
||||
setAttribute(Qt::WA_NoSystemBackground, true);
|
||||
setMouseTracking(true);
|
||||
setFocusPolicy(Qt::StrongFocus);
|
||||
|
||||
m_background.setStart(0, 0);
|
||||
m_background.setFinalStop(0, 1);
|
||||
m_background.setCoordinateMode(QGradient::ObjectBoundingMode);
|
||||
|
||||
ColorMapper::colormap::const_iterator cmit = m_colorMapper.getDialBackgroundColorMap().begin();
|
||||
ColorMapper::colormap::const_iterator cmitEnd = m_colorMapper.getDialBackgroundColorMap().end();
|
||||
|
||||
for (; cmit != cmitEnd; ++ cmit) {
|
||||
m_background.setColorAt(cmit->first, cmit->second);
|
||||
}
|
||||
|
||||
m_value = 0;
|
||||
m_valueMin = m_positiveOnly ? 0 : -2200000;
|
||||
m_valueMax = 2200000;
|
||||
m_numDigits = 7;
|
||||
m_numDecimalPoints = m_numDigits / 3;
|
||||
m_cursor = -1;
|
||||
|
||||
m_hightlightedDigit = -1;
|
||||
m_text = formatText(m_value);
|
||||
m_cursorState = false;
|
||||
|
||||
connect(&m_animationTimer, SIGNAL(timeout()), this, SLOT(animate()));
|
||||
connect(&m_blinkTimer, SIGNAL(timeout()), this, SLOT(blink()));
|
||||
}
|
||||
|
||||
void ValueDialZ::setFont(const QFont& font)
|
||||
{
|
||||
QWidget::setFont(font);
|
||||
|
||||
QFontMetrics fm(font);
|
||||
m_digitWidth = fm.width('0');
|
||||
m_digitHeight = fm.ascent();
|
||||
if(m_digitWidth < m_digitHeight)
|
||||
m_digitWidth = m_digitHeight;
|
||||
setFixedWidth((m_numDigits + m_numDecimalPoints + (m_positiveOnly ? 0 : 1)) * m_digitWidth + 2);
|
||||
setFixedHeight(m_digitHeight * 2 + 2);
|
||||
}
|
||||
|
||||
void ValueDialZ::setBold(bool bold)
|
||||
{
|
||||
QFont f = font();
|
||||
f.setBold(bold);
|
||||
setFont(f);
|
||||
}
|
||||
|
||||
void ValueDialZ::setColorMapper(ColorMapper colorMapper)
|
||||
{
|
||||
m_colorMapper = colorMapper;
|
||||
|
||||
ColorMapper::colormap::const_iterator cmit = m_colorMapper.getDialBackgroundColorMap().begin();
|
||||
ColorMapper::colormap::const_iterator cmitEnd = m_colorMapper.getDialBackgroundColorMap().end();
|
||||
|
||||
for (; cmit != cmitEnd; ++ cmit) {
|
||||
m_background.setColorAt(cmit->first, cmit->second);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ValueDialZ::setValue(qint64 value)
|
||||
{
|
||||
m_valueNew = value;
|
||||
|
||||
if(m_valueNew < m_valueMin) {
|
||||
m_valueNew = m_valueMin;
|
||||
}
|
||||
else if(m_valueNew > m_valueMax) {
|
||||
m_valueNew = m_valueMax;
|
||||
}
|
||||
|
||||
if(m_valueNew < m_value) {
|
||||
m_animationState = 1;
|
||||
} else if(m_valueNew > m_value) {
|
||||
m_animationState = -1;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
m_animationTimer.start(20);
|
||||
m_textNew = formatText(m_valueNew);
|
||||
}
|
||||
|
||||
void ValueDialZ::setValueRange(bool positiveOnly, uint numDigits, qint64 min, qint64 max)
|
||||
{
|
||||
m_positiveOnly = positiveOnly;
|
||||
m_numDigits = numDigits;
|
||||
m_numDecimalPoints = m_numDigits < 3 ? 0 : (m_numDigits%3) == 0 ? (m_numDigits/3)-1 : m_numDigits/3;
|
||||
|
||||
setFixedWidth((m_numDigits + m_numDecimalPoints + (m_positiveOnly ? 0 : 1)) * m_digitWidth + 2);
|
||||
|
||||
m_valueMin = positiveOnly ? (min < 0 ? 0 : min) : min;
|
||||
m_valueMax = positiveOnly ? (max < 0 ? 0 : max) : max;
|
||||
|
||||
if(m_value < m_valueMin)
|
||||
{
|
||||
setValue(m_valueMin);
|
||||
}
|
||||
else if(m_value > m_valueMax)
|
||||
{
|
||||
setValue(m_valueMax);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_text = formatText(0);
|
||||
m_textNew = m_text;
|
||||
m_value = 0;
|
||||
m_valueNew = m_value;
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
quint64 ValueDialZ::findExponent(int digit)
|
||||
{
|
||||
quint64 e = 1;
|
||||
int d = (m_numDigits + m_numDecimalPoints + (m_positiveOnly ? 0 : 1)) - digit;
|
||||
d = d - (d / 4) - 1;
|
||||
for(int i = 0; i < d; i++)
|
||||
e *= 10;
|
||||
return e;
|
||||
}
|
||||
|
||||
QChar ValueDialZ::digitNeigh(QChar c, bool dir)
|
||||
{
|
||||
if (c == QChar('+')) {
|
||||
return QChar('-');
|
||||
} else if (c == QChar('-')) {
|
||||
return QChar('+');
|
||||
}
|
||||
|
||||
if(dir)
|
||||
{
|
||||
if(c == QChar('0')) {
|
||||
return QChar('9');
|
||||
} else {
|
||||
return QChar::fromLatin1(c.toLatin1() - 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(c == QChar('9')) {
|
||||
return QChar('0');
|
||||
} else {
|
||||
return QChar::fromLatin1(c.toLatin1() + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
QString ValueDialZ::formatText(qint64 value)
|
||||
{
|
||||
QString str = QString("%1%2").arg(m_positiveOnly ? "" : value < 0 ? "-" : "+").arg(abs(value), m_numDigits, 10, QChar('0'));
|
||||
|
||||
for(int i = 0; i < m_numDecimalPoints; i++)
|
||||
{
|
||||
int ipoint = m_numDigits + (m_positiveOnly ? 0 : 1) - 3 - 3 * i;
|
||||
|
||||
if (ipoint != 0) { // do not insert leading point
|
||||
str.insert(ipoint, ".");
|
||||
}
|
||||
}
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
void ValueDialZ::paintEvent(QPaintEvent*)
|
||||
{
|
||||
QPainter painter(this);
|
||||
|
||||
painter.setPen(Qt::black);
|
||||
painter.setBrush(m_background);
|
||||
|
||||
painter.drawRect(0, 0, width() - 1, height() - 1);
|
||||
|
||||
painter.setPen(m_colorMapper.getBoundaryColor());
|
||||
painter.setBrush(Qt::NoBrush);
|
||||
|
||||
for (int i = 1; i < m_numDigits + m_numDecimalPoints; i++)
|
||||
{
|
||||
painter.setPen(m_colorMapper.getBoundaryColor());
|
||||
painter.drawLine(1 + i * m_digitWidth, 1, 1 + i * m_digitWidth, height() - 1);
|
||||
painter.setPen(m_colorMapper.getBoundaryAlphaColor());
|
||||
painter.drawLine(0 + i * m_digitWidth, 1, 0 + i * m_digitWidth, height() - 1);
|
||||
painter.drawLine(2 + i * m_digitWidth, 1, 2 + i * m_digitWidth, height() - 1);
|
||||
}
|
||||
|
||||
painter.setPen(m_colorMapper.getBoundaryAlphaColor());
|
||||
painter.drawLine(1, 1, 1, height() - 1);
|
||||
painter.drawLine(width() - 2, 1, width() - 2, height() - 1);
|
||||
|
||||
// dial borders
|
||||
painter.setPen(m_colorMapper.getDarkBorderColor());
|
||||
painter.drawLine(0, 0, width() - 2, 0);
|
||||
painter.drawLine(0, height() - 1, 0, 0);
|
||||
painter.setPen(m_colorMapper.getLightBorderColor());
|
||||
painter.drawLine(1, height() - 1, width() - 1, height() - 1);
|
||||
painter.drawLine(width() - 1, height() - 1, width() - 1, 0);
|
||||
|
||||
if (m_hightlightedDigit >= 0)
|
||||
{
|
||||
painter.setPen(Qt::NoPen);
|
||||
painter.setBrush(m_colorMapper.getHighlightColor());
|
||||
painter.drawRect(2 + m_hightlightedDigit * m_digitWidth, 1, m_digitWidth - 1, height() - 1);
|
||||
}
|
||||
|
||||
if (m_animationState == 0)
|
||||
{
|
||||
for (int i = 0; i < m_text.length(); i++)
|
||||
{
|
||||
painter.setClipRect(1 + i * m_digitWidth, 1, m_digitWidth, m_digitHeight * 2);
|
||||
painter.setPen(m_colorMapper.getSecondaryForegroundColor());
|
||||
painter.drawText(QRect(1 + i * m_digitWidth, m_digitHeight * 0.6, m_digitWidth, m_digitHeight), Qt::AlignCenter, m_text.mid(i, 1));
|
||||
|
||||
if(m_text[i] != QChar('.'))
|
||||
{
|
||||
painter.setPen(m_colorMapper.getForegroundColor());
|
||||
painter.drawText(QRect(1 + i * m_digitWidth, m_digitHeight * -0.7, m_digitWidth, m_digitHeight), Qt::AlignCenter, digitNeigh(m_text[i], true));
|
||||
painter.drawText(QRect(1 + i * m_digitWidth, m_digitHeight * 1.9, m_digitWidth, m_digitHeight), Qt::AlignCenter, digitNeigh(m_text[i], false));
|
||||
}
|
||||
}
|
||||
|
||||
painter.setClipping(false);
|
||||
|
||||
if ((m_cursor >= 0) && (m_cursorState))
|
||||
{
|
||||
painter.setPen(Qt::NoPen);
|
||||
painter.setBrush(m_colorMapper.getSecondaryForegroundColor());
|
||||
painter.drawRect(4 + m_cursor * m_digitWidth, 1 + m_digitHeight * 1.5, m_digitWidth - 5, m_digitHeight / 6);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(m_animationState != 0)
|
||||
{
|
||||
for(int i = 0; i < m_text.length(); i++)
|
||||
{
|
||||
if(m_text[i] == m_textNew[i])
|
||||
{
|
||||
painter.setClipRect(1 + i * m_digitWidth, 1, m_digitWidth, m_digitHeight * 2);
|
||||
painter.setPen(m_colorMapper.getSecondaryForegroundColor());
|
||||
painter.drawText(QRect(1 + i * m_digitWidth, m_digitHeight * 0.6, m_digitWidth, m_digitHeight), Qt::AlignCenter, m_text.mid(i, 1));
|
||||
|
||||
if(m_text[i] != QChar('.'))
|
||||
{
|
||||
painter.setPen(m_colorMapper.getForegroundColor());
|
||||
painter.drawText(QRect(1 + i * m_digitWidth, m_digitHeight * -0.7, m_digitWidth, m_digitHeight), Qt::AlignCenter, digitNeigh(m_text[i], true));
|
||||
painter.drawText(QRect(1 + i * m_digitWidth, m_digitHeight * 1.9, m_digitWidth, m_digitHeight), Qt::AlignCenter, digitNeigh(m_text[i], false));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int h = m_digitHeight * 0.6 + m_digitHeight * m_animationState / 2.0;
|
||||
painter.setClipRect(1 + i * m_digitWidth, 1, m_digitWidth, m_digitHeight * 2);
|
||||
painter.setPen(m_colorMapper.getSecondaryForegroundColor());
|
||||
painter.drawText(QRect(1 + i * m_digitWidth, h, m_digitWidth, m_digitHeight), Qt::AlignCenter, m_text.mid(i, 1));
|
||||
|
||||
if(m_text[i] != QChar('.'))
|
||||
{
|
||||
painter.setPen(m_colorMapper.getForegroundColor());
|
||||
painter.drawText(QRect(1 + i * m_digitWidth, h + m_digitHeight * -0.7, m_digitWidth, m_digitHeight), Qt::AlignCenter, digitNeigh(m_text[i], true));
|
||||
painter.drawText(QRect(1 + i * m_digitWidth, h + m_digitHeight * 1.9, m_digitWidth, m_digitHeight), Qt::AlignCenter, digitNeigh(m_text[i], false));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ValueDialZ::mousePressEvent(QMouseEvent* event)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = (event->x() - 1) / m_digitWidth;
|
||||
|
||||
if (m_positiveOnly)
|
||||
|
||||
if ((m_text[i] == QChar('.')) || (m_text[i] == QChar('+')) || (m_text[i] == QChar('-')))
|
||||
{
|
||||
i++;
|
||||
|
||||
if (i > m_numDigits + m_numDecimalPoints + (m_positiveOnly ? 0 : 1))
|
||||
{
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Qt::MouseButton mouseButton = event->button();
|
||||
|
||||
if (mouseButton == Qt::RightButton) // ceil value at current digit
|
||||
{
|
||||
if(m_cursor >= 0)
|
||||
{
|
||||
m_cursor = -1;
|
||||
m_blinkTimer.stop();
|
||||
update();
|
||||
}
|
||||
|
||||
qint64 e = findExponent(i);
|
||||
|
||||
m_valueNew = (m_value / e) * e;
|
||||
setValue(m_valueNew);
|
||||
emit changed(m_valueNew);
|
||||
//qDebug("ValueDial::mousePressEvent: Qt::RightButton: i: %d e: %ll new: %ll", i, e, valueNew);
|
||||
}
|
||||
else if (mouseButton == Qt::LeftButton) // set cursor at current digit
|
||||
{
|
||||
m_cursor = i;
|
||||
m_cursorState = true;
|
||||
m_blinkTimer.start(400);
|
||||
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
void ValueDialZ::mouseMoveEvent(QMouseEvent* event)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = (event->x() - 1) / m_digitWidth;
|
||||
|
||||
if(m_text[i] == QChar('.'))
|
||||
{
|
||||
i = -1;
|
||||
}
|
||||
else if ((m_text[i] == QChar('+')) || (m_text[i] != QChar('-')))
|
||||
{
|
||||
i = -1;
|
||||
}
|
||||
|
||||
if(i != m_hightlightedDigit)
|
||||
{
|
||||
m_hightlightedDigit = i;
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
void ValueDialZ::wheelEvent(QWheelEvent* event)
|
||||
{
|
||||
int i;
|
||||
|
||||
i = (event->x() - 1) / m_digitWidth;
|
||||
|
||||
if ((m_text[i] != QChar('.')) &&
|
||||
(m_text[i] != QChar('+')) &&
|
||||
(m_text[i] != QChar('-')))
|
||||
{
|
||||
m_hightlightedDigit = i;
|
||||
}
|
||||
else
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (m_cursor >= 0)
|
||||
{
|
||||
m_cursor = -1;
|
||||
m_blinkTimer.stop();
|
||||
update();
|
||||
}
|
||||
|
||||
qint64 e = findExponent(m_hightlightedDigit);
|
||||
|
||||
if(m_animationState == 0)
|
||||
{
|
||||
if(event->delta() < 0)
|
||||
{
|
||||
if(event->modifiers() & Qt::ShiftModifier) {
|
||||
e *= 5;
|
||||
}
|
||||
|
||||
m_valueNew = (m_value - e < m_valueMin) ? m_valueMin : m_value - e;
|
||||
}
|
||||
else
|
||||
{
|
||||
if(event->modifiers() & Qt::ShiftModifier) {
|
||||
e *= 5;
|
||||
}
|
||||
|
||||
m_valueNew = (m_value + e > m_valueMax) ? m_valueMax : m_value + e;
|
||||
}
|
||||
|
||||
setValue(m_valueNew);
|
||||
emit changed(m_valueNew);
|
||||
}
|
||||
}
|
||||
|
||||
void ValueDialZ::leaveEvent(QEvent*)
|
||||
{
|
||||
if(m_hightlightedDigit != -1) {
|
||||
m_hightlightedDigit = -1;
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
void ValueDialZ::keyPressEvent(QKeyEvent* value)
|
||||
{
|
||||
if(m_cursor >= 0)
|
||||
{
|
||||
if((value->key() == Qt::Key_Return) || (value->key() == Qt::Key_Enter) || (value->key() == Qt::Key_Escape))
|
||||
{
|
||||
m_cursor = -1;
|
||||
m_cursorState = false;
|
||||
m_blinkTimer.stop();
|
||||
update();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if((m_cursor < 0) && (m_hightlightedDigit >= 0))
|
||||
{
|
||||
m_cursor = m_hightlightedDigit;
|
||||
|
||||
if (m_text[m_cursor] == QChar('.')) {
|
||||
m_cursor++;
|
||||
}
|
||||
|
||||
if(m_cursor >= m_numDigits + m_numDecimalPoints + (m_positiveOnly ? 0 : 1)) {
|
||||
return;
|
||||
}
|
||||
|
||||
m_cursorState = true;
|
||||
m_blinkTimer.start(400);
|
||||
update();
|
||||
}
|
||||
|
||||
if(m_cursor < 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((value->key() == Qt::Key_Left) || (value->key() == Qt::Key_Backspace))
|
||||
{
|
||||
if(m_cursor > 0)
|
||||
{
|
||||
m_cursor--;
|
||||
|
||||
if (m_text[m_cursor] == QChar('.')) {
|
||||
m_cursor--;
|
||||
}
|
||||
|
||||
if (m_cursor < (m_positiveOnly ? 0 : 1)) {
|
||||
m_cursor++;
|
||||
}
|
||||
|
||||
m_cursorState = true;
|
||||
update();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if(value->key() == Qt::Key_Right)
|
||||
{
|
||||
if(m_cursor < m_numDecimalPoints + m_numDigits)
|
||||
{
|
||||
m_cursor++;
|
||||
|
||||
if (m_text[m_cursor] == QChar('.')) {
|
||||
m_cursor++;
|
||||
}
|
||||
|
||||
if(m_cursor >= m_numDecimalPoints + m_numDigits + (m_positiveOnly ? 0 : 1)) {
|
||||
m_cursor--;
|
||||
}
|
||||
|
||||
m_cursorState = true;
|
||||
update();
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if(value->key() == Qt::Key_Up)
|
||||
{
|
||||
qint64 e = findExponent(m_cursor);
|
||||
|
||||
if(value->modifiers() & Qt::ShiftModifier) {
|
||||
e *= 5;
|
||||
}
|
||||
|
||||
if(m_animationState != 0) {
|
||||
m_value = m_valueNew;
|
||||
}
|
||||
|
||||
m_valueNew = m_value + e > m_valueMax ? m_valueMax : m_value + e;
|
||||
|
||||
setValue(m_valueNew);
|
||||
emit changed(m_valueNew);
|
||||
}
|
||||
else if(value->key() == Qt::Key_Down)
|
||||
{
|
||||
qint64 e = findExponent(m_cursor);
|
||||
|
||||
if(value->modifiers() & Qt::ShiftModifier) {
|
||||
e *= 5;
|
||||
}
|
||||
|
||||
if(m_animationState != 0) {
|
||||
m_value = m_valueNew;
|
||||
}
|
||||
|
||||
m_valueNew = m_value - e < m_valueMin ? m_valueMin : m_value - e;
|
||||
|
||||
setValue(m_valueNew);
|
||||
emit changed(m_valueNew);
|
||||
}
|
||||
|
||||
if(value->text().length() != 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
QChar c = value->text()[0];
|
||||
|
||||
if(c >= QChar('0') && (c <= QChar('9')))
|
||||
{
|
||||
int d = c.toLatin1() - '0';
|
||||
quint64 e = findExponent(m_cursor);
|
||||
quint64 v = (m_value / e) % 10;
|
||||
if(m_animationState != 0)
|
||||
m_value = m_valueNew;
|
||||
v = m_value - v * e;
|
||||
v += d * e;
|
||||
setValue(v);
|
||||
emit changed(m_valueNew);
|
||||
m_cursor++;
|
||||
|
||||
if ((m_text[m_cursor] == QChar('.')) || (m_text[m_cursor] == QChar('+')) || (m_text[m_cursor] == QChar('-'))) {
|
||||
m_cursor++;
|
||||
}
|
||||
|
||||
if(m_cursor >= m_numDigits + m_numDecimalPoints + (m_positiveOnly ? 0 : 1))
|
||||
{
|
||||
m_cursor = -1;
|
||||
m_blinkTimer.stop();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_cursorState = true;
|
||||
}
|
||||
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
void ValueDialZ::focusInEvent(QFocusEvent*)
|
||||
{
|
||||
if(m_cursor == -1) {
|
||||
m_cursor = 0;
|
||||
m_cursorState = true;
|
||||
m_blinkTimer.start(400);
|
||||
update();
|
||||
}
|
||||
}
|
||||
|
||||
void ValueDialZ::focusOutEvent(QFocusEvent*)
|
||||
{
|
||||
m_cursor = -1;
|
||||
m_blinkTimer.stop();
|
||||
update();
|
||||
}
|
||||
|
||||
void ValueDialZ::animate()
|
||||
{
|
||||
update();
|
||||
|
||||
if(m_animationState > 0)
|
||||
m_animationState++;
|
||||
else if(m_animationState < 0)
|
||||
m_animationState--;
|
||||
else {
|
||||
m_animationTimer.stop();
|
||||
m_animationState = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
if(abs(m_animationState) >= 4) {
|
||||
m_animationState = 0;
|
||||
m_animationTimer.stop();
|
||||
m_value = m_valueNew;
|
||||
m_text = m_textNew;
|
||||
}
|
||||
}
|
||||
|
||||
void ValueDialZ::blink()
|
||||
{
|
||||
if(m_cursor >= 0) {
|
||||
m_cursorState = !m_cursorState;
|
||||
update();
|
||||
}
|
||||
}
|
83
sdrbase/gui/valuedialz.h
Normal file
83
sdrbase/gui/valuedialz.h
Normal file
@ -0,0 +1,83 @@
|
||||
///////////////////////////////////////////////////////////////////////////////////
|
||||
// Copyright (C) 2017 F4EXB //
|
||||
// written by Edouard Griffiths //
|
||||
// //
|
||||
// Same as ValueDial but handles optionally positive and negative numbers with //
|
||||
// sign display. //
|
||||
// //
|
||||
// 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 as version 3 of the License, or //
|
||||
// //
|
||||
// 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 V3 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 <QWidget>
|
||||
#include <QTimer>
|
||||
#include "gui/colormapper.h"
|
||||
#include "util/export.h"
|
||||
|
||||
class SDRANGEL_API ValueDialZ : public QWidget {
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
ValueDialZ(bool positiveOnly = true, QWidget* parent = NULL, ColorMapper colorMapper = ColorMapper(ColorMapper::Normal));
|
||||
|
||||
void setValue(qint64 value);
|
||||
void setValueRange(bool positiveOnly, uint numDigits, qint64 min, qint64 max);
|
||||
void setFont(const QFont& font);
|
||||
void setBold(bool bold);
|
||||
void setColorMapper(ColorMapper colorMapper);
|
||||
qint64 getValue() const { return m_value; }
|
||||
qint64 getValueNew() const { return m_valueNew; }
|
||||
|
||||
signals:
|
||||
void changed(qint64 value);
|
||||
|
||||
private:
|
||||
QLinearGradient m_background;
|
||||
int m_numDigits;
|
||||
int m_numDecimalPoints;
|
||||
int m_digitWidth;
|
||||
int m_digitHeight;
|
||||
int m_hightlightedDigit;
|
||||
int m_cursor;
|
||||
bool m_cursorState;
|
||||
qint64 m_value;
|
||||
qint64 m_valueMax;
|
||||
qint64 m_valueMin;
|
||||
bool m_positiveOnly;
|
||||
QString m_text;
|
||||
|
||||
qint64 m_valueNew;
|
||||
QString m_textNew;
|
||||
int m_animationState;
|
||||
QTimer m_animationTimer;
|
||||
QTimer m_blinkTimer;
|
||||
|
||||
ColorMapper m_colorMapper;
|
||||
|
||||
quint64 findExponent(int digit);
|
||||
QChar digitNeigh(QChar c, bool dir);
|
||||
QString formatText(qint64 value);
|
||||
|
||||
void paintEvent(QPaintEvent*);
|
||||
|
||||
void mousePressEvent(QMouseEvent*);
|
||||
void mouseMoveEvent(QMouseEvent*);
|
||||
void wheelEvent(QWheelEvent*);
|
||||
void leaveEvent(QEvent*);
|
||||
void keyPressEvent(QKeyEvent*);
|
||||
void focusInEvent(QFocusEvent*);
|
||||
void focusOutEvent(QFocusEvent*);
|
||||
|
||||
private slots:
|
||||
void animate();
|
||||
void blink();
|
||||
};
|
@ -116,6 +116,7 @@ SOURCES += mainwindow.cpp\
|
||||
gui/scale.cpp\
|
||||
gui/scaleengine.cpp\
|
||||
gui/valuedial.cpp\
|
||||
gui/valuedialz.cpp\
|
||||
dsp/devicesamplesource.cpp\
|
||||
dsp/devicesamplesink.cpp\
|
||||
plugin/pluginapi.cpp\
|
||||
@ -222,6 +223,7 @@ HEADERS += mainwindow.h\
|
||||
gui/scale.h\
|
||||
gui/scaleengine.h\
|
||||
gui/valuedial.h\
|
||||
gui/valuedialz.h\
|
||||
dsp/devicesamplesource.h\
|
||||
dsp/devicesamplesink.h\
|
||||
plugin/pluginapi.h\
|
||||
|
Loading…
Reference in New Issue
Block a user