mirror of
				https://github.com/f4exb/sdrangel.git
				synced 2025-11-03 21:20:31 -05:00 
			
		
		
		
	
		
			
				
	
	
		
			675 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			675 lines
		
	
	
		
			18 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
///////////////////////////////////////////////////////////////////////////////////
 | 
						|
// Copyright (C) 2012 maintech GmbH, Otto-Hahn-Str. 15, 97204 Hoechberg, Germany //
 | 
						|
// written by Christian Daniel                                                   //
 | 
						|
// Copyright (C) 2015-2020, 2023 Edouard Griffiths, F4EXB <f4exb06@gmail.com>    //
 | 
						|
// Copyright (C) 2018 fire <fire@80211.at>                                       //
 | 
						|
// Copyright (C) 2019 Davide Gerhard <rainbow@irh.it>                            //
 | 
						|
// Copyright (C) 2020 Vort <vvort@yandex.ru>                                     //
 | 
						|
// Copyright (C) 2022-2023 Jon Beniston, M7RCE <jon@beniston.com>                //
 | 
						|
// Copyright (C) 2022 Jiří Pinkava <jiri.pinkava@rossum.ai>                      //
 | 
						|
//                                                                               //
 | 
						|
// 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                  //
 | 
						|
// (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 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 <QKeyEvent>
 | 
						|
#include <QLocale>
 | 
						|
#include <QMouseEvent>
 | 
						|
#include <QPainter>
 | 
						|
#include <QWheelEvent>
 | 
						|
#include <QApplication>
 | 
						|
#include <QAccessibleValueChangeEvent>
 | 
						|
#include <cstdlib>
 | 
						|
 | 
						|
#include "gui/valuedial.h"
 | 
						|
 | 
						|
ValueDial::ValueDial(QWidget *parent, ColorMapper colorMapper) :
 | 
						|
    QWidget(parent),
 | 
						|
    m_animationState(0),
 | 
						|
    m_colorMapper(colorMapper)
 | 
						|
{
 | 
						|
    setAutoFillBackground(false);
 | 
						|
    setAttribute(Qt::WA_OpaquePaintEvent, true);
 | 
						|
    setAttribute(Qt::WA_NoSystemBackground, true);
 | 
						|
	setAttribute(Qt::WA_InputMethodEnabled, true);
 | 
						|
    setMouseTracking(true);
 | 
						|
    setFocusPolicy(Qt::StrongFocus);
 | 
						|
 | 
						|
	setInputMethodHints(Qt::ImhDigitsOnly);
 | 
						|
 | 
						|
    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_valueNew = 0;
 | 
						|
    m_valueMin = 0;
 | 
						|
    m_valueMax = 2200000;
 | 
						|
    m_numDigits = 7;
 | 
						|
    m_numDecimalPoints = m_numDigits / 3;
 | 
						|
    m_cursor = -1;
 | 
						|
    m_digitWidth = 0;
 | 
						|
    m_digitHeight = 0;
 | 
						|
 | 
						|
    m_hightlightedDigit = -1;
 | 
						|
    m_text = formatText(m_value);
 | 
						|
    m_cursorState = false;
 | 
						|
 | 
						|
    const QLocale &cLocale = QLocale::c();
 | 
						|
    m_groupSeparator = cLocale.groupSeparator();
 | 
						|
 | 
						|
    connect(&m_animationTimer, SIGNAL(timeout()), this, SLOT(animate()));
 | 
						|
    connect(&m_blinkTimer, SIGNAL(timeout()), this, SLOT(blink()));
 | 
						|
}
 | 
						|
 | 
						|
void ValueDial::setFont(const QFont &font)
 | 
						|
{
 | 
						|
    QWidget::setFont(font);
 | 
						|
 | 
						|
    QFontMetrics fm(font);
 | 
						|
    m_digitWidth = fm.horizontalAdvance('0');
 | 
						|
    m_digitHeight = fm.ascent();
 | 
						|
    if (m_digitWidth < m_digitHeight) {
 | 
						|
        m_digitWidth = m_digitHeight;
 | 
						|
    }
 | 
						|
    setFixedWidth((m_numDigits + m_numDecimalPoints) * m_digitWidth + 2);
 | 
						|
    setFixedHeight(m_digitHeight * 2 + 2);
 | 
						|
}
 | 
						|
 | 
						|
void ValueDial::setBold(bool bold)
 | 
						|
{
 | 
						|
    QFont f = font();
 | 
						|
    f.setBold(bold);
 | 
						|
    setFont(f);
 | 
						|
}
 | 
						|
 | 
						|
void ValueDial::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 ValueDial::setValue(quint64 value)
 | 
						|
{
 | 
						|
    m_valueNew = value;
 | 
						|
    m_textNew = formatText(m_valueNew);
 | 
						|
 | 
						|
    if (m_valueNew < m_valueMin) {
 | 
						|
        m_valueNew = m_valueMin;
 | 
						|
    } else if (m_valueNew > m_valueMax) {
 | 
						|
        m_valueNew = m_valueMax;
 | 
						|
    }
 | 
						|
 | 
						|
    QAccessibleValueChangeEvent event(this, value);
 | 
						|
    QAccessible::updateAccessibility(&event);
 | 
						|
 | 
						|
    if (m_valueNew < m_value)
 | 
						|
    {
 | 
						|
        m_animationState = 1;
 | 
						|
    }
 | 
						|
    else if (m_valueNew > m_value)
 | 
						|
    {
 | 
						|
        m_animationState = -1;
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
        m_text = m_textNew;
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    m_animationTimer.start(20);
 | 
						|
}
 | 
						|
 | 
						|
void ValueDial::setValueRange(uint numDigits, quint64 min, quint64 max)
 | 
						|
{
 | 
						|
    m_numDigits = numDigits;
 | 
						|
    m_numDecimalPoints = m_numDigits < 3 ? 0 : (m_numDigits % 3) == 0 ? (m_numDigits / 3) - 1 : m_numDigits / 3;
 | 
						|
    m_valueMin = min;
 | 
						|
    m_valueMax = max;
 | 
						|
 | 
						|
    if (m_animationTimer.isActive())
 | 
						|
    {
 | 
						|
        m_textNew = formatText(m_valueNew);
 | 
						|
 | 
						|
        if (m_valueNew < min) {
 | 
						|
            setValue(min);
 | 
						|
        } else if (m_valueNew > max) {
 | 
						|
            setValue(max);
 | 
						|
        }
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
        m_text = formatText(m_value);
 | 
						|
 | 
						|
        if (m_value < min) {
 | 
						|
            setValue(min);
 | 
						|
        } else if (m_value > max) {
 | 
						|
            setValue(max);
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    setFixedWidth((m_numDigits + m_numDecimalPoints) * m_digitWidth + 2);
 | 
						|
}
 | 
						|
 | 
						|
quint64 ValueDial::findExponent(int digit)
 | 
						|
{
 | 
						|
    quint64 e = 1;
 | 
						|
    int d = (m_numDigits + m_numDecimalPoints) - digit;
 | 
						|
    d = d - (d / 4) - 1;
 | 
						|
 | 
						|
    for (int i = 0; i < d; i++) {
 | 
						|
        e *= 10;
 | 
						|
    }
 | 
						|
 | 
						|
    return e;
 | 
						|
}
 | 
						|
 | 
						|
QChar ValueDial::digitNeigh(QChar c, bool dir)
 | 
						|
{
 | 
						|
    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 ValueDial::formatText(quint64 value)
 | 
						|
{
 | 
						|
    QString str = QString("%1").arg(value, m_numDigits, 10, QChar('0'));
 | 
						|
 | 
						|
    for (int i = 0; i < m_numDecimalPoints; i++)
 | 
						|
    {
 | 
						|
        int ipoint = m_numDigits - 3 - 3 * i;
 | 
						|
 | 
						|
        if (ipoint != 0)
 | 
						|
        { // do not insert leading point
 | 
						|
            const QLocale &cLocale = QLocale::c();
 | 
						|
            str.insert(ipoint, cLocale.groupSeparator());
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
    return str;
 | 
						|
}
 | 
						|
 | 
						|
void ValueDial::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);
 | 
						|
    }
 | 
						|
 | 
						|
    QColor secondaryForegroundColor = m_colorMapper.getSecondaryForegroundColor();
 | 
						|
    if (!isEnabled()) {
 | 
						|
        secondaryForegroundColor = secondaryForegroundColor.darker();
 | 
						|
    }
 | 
						|
 | 
						|
    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(secondaryForegroundColor);
 | 
						|
            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] != m_groupSeparator)
 | 
						|
            {
 | 
						|
                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(secondaryForegroundColor);
 | 
						|
            painter.drawRect(4 + m_cursor * m_digitWidth, 1 + m_digitHeight * 1.5, m_digitWidth - 5, m_digitHeight / 6);
 | 
						|
        }
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
        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(secondaryForegroundColor);
 | 
						|
                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] != m_groupSeparator)
 | 
						|
                {
 | 
						|
                    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(secondaryForegroundColor);
 | 
						|
                painter.drawText(QRect(1 + i * m_digitWidth, h, m_digitWidth, m_digitHeight), Qt::AlignCenter, m_text.mid(i, 1));
 | 
						|
 | 
						|
                if (m_text[i] != m_groupSeparator)
 | 
						|
                {
 | 
						|
                    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 ValueDial::mousePressEvent(QMouseEvent *event)
 | 
						|
{
 | 
						|
    int i;
 | 
						|
 | 
						|
    i = (event->x() - 1) / m_digitWidth;
 | 
						|
 | 
						|
    if (m_text[i] == m_groupSeparator)
 | 
						|
    {
 | 
						|
        i++;
 | 
						|
 | 
						|
        if (i > m_numDigits + m_numDecimalPoints) {
 | 
						|
            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();
 | 
						|
        }
 | 
						|
 | 
						|
        quint64 e = findExponent(i);
 | 
						|
        m_valueNew = (m_value / e) * e;
 | 
						|
        setValue(m_valueNew);
 | 
						|
        emit changed(m_valueNew);
 | 
						|
        //qDebug("ValueDial::mousePressEvent: Qt::RightButton: i: %d e: %llu new: %llu", i, e, valueNew);
 | 
						|
    }
 | 
						|
    else if (mouseButton == Qt::LeftButton) // set cursor at current digit
 | 
						|
    {
 | 
						|
		if (qApp->autoSipEnabled())
 | 
						|
		{
 | 
						|
			QGuiApplication::inputMethod()->show();
 | 
						|
		}
 | 
						|
 | 
						|
        m_cursor = i;
 | 
						|
        m_cursorState = true;
 | 
						|
        m_blinkTimer.start(400);
 | 
						|
 | 
						|
        update();
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
void ValueDial::mouseMoveEvent(QMouseEvent *event)
 | 
						|
{
 | 
						|
    int i;
 | 
						|
    i = (event->x() - 1) / m_digitWidth;
 | 
						|
 | 
						|
    if ((i >= m_text.size()) || (m_text[i] == m_groupSeparator)) {
 | 
						|
        i = -1;
 | 
						|
    }
 | 
						|
 | 
						|
    if (i != m_hightlightedDigit)
 | 
						|
    {
 | 
						|
        m_hightlightedDigit = i;
 | 
						|
        update();
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
void ValueDial::wheelEvent(QWheelEvent *event)
 | 
						|
{
 | 
						|
    int i;
 | 
						|
    i = (event->position().x() - 1) / m_digitWidth;
 | 
						|
 | 
						|
    if (m_text[i] != m_groupSeparator) {
 | 
						|
        m_hightlightedDigit = i;
 | 
						|
    } else {
 | 
						|
        return;
 | 
						|
    }
 | 
						|
 | 
						|
    if (m_cursor >= 0)
 | 
						|
    {
 | 
						|
        m_cursor = -1;
 | 
						|
        m_blinkTimer.stop();
 | 
						|
        update();
 | 
						|
    }
 | 
						|
 | 
						|
    quint64 e = findExponent(m_hightlightedDigit);
 | 
						|
 | 
						|
    if (m_animationState == 0)
 | 
						|
    {
 | 
						|
        if (event->angleDelta().y() < 0)
 | 
						|
        {
 | 
						|
            if (event->modifiers() & Qt::ShiftModifier) {
 | 
						|
                e *= 5;
 | 
						|
            } else if (event->modifiers() & Qt::ControlModifier) {
 | 
						|
                e *= 2;
 | 
						|
            }
 | 
						|
 | 
						|
            if (m_value < e) {
 | 
						|
                m_valueNew = m_valueMin;
 | 
						|
            } else {
 | 
						|
                m_valueNew = m_value - e;
 | 
						|
            }
 | 
						|
        }
 | 
						|
        else
 | 
						|
        {
 | 
						|
            if (event->modifiers() & Qt::ShiftModifier) {
 | 
						|
                e *= 5;
 | 
						|
            } else if (event->modifiers() & Qt::ControlModifier) {
 | 
						|
                e *= 2;
 | 
						|
            }
 | 
						|
 | 
						|
            if (m_valueMax - m_value < e) {
 | 
						|
                m_valueNew = m_valueMax;
 | 
						|
            } else {
 | 
						|
                m_valueNew = m_value + e;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        setValue(m_valueNew);
 | 
						|
        emit changed(m_valueNew);
 | 
						|
        event->accept();
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
void ValueDial::leaveEvent(QEvent *)
 | 
						|
{
 | 
						|
    if (m_hightlightedDigit != -1)
 | 
						|
    {
 | 
						|
        m_hightlightedDigit = -1;
 | 
						|
        update();
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
void ValueDial::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] == m_groupSeparator) {
 | 
						|
            m_cursor++;
 | 
						|
        }
 | 
						|
 | 
						|
        if (m_cursor >= m_numDigits + m_numDecimalPoints) {
 | 
						|
            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] == m_groupSeparator) {
 | 
						|
                m_cursor--;
 | 
						|
            }
 | 
						|
 | 
						|
            if (m_cursor < 0) {
 | 
						|
                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] == m_groupSeparator) {
 | 
						|
                m_cursor++;
 | 
						|
            }
 | 
						|
 | 
						|
            if (m_cursor >= m_numDecimalPoints + m_numDigits) {
 | 
						|
                m_cursor--;
 | 
						|
            }
 | 
						|
 | 
						|
            m_cursorState = true;
 | 
						|
            update();
 | 
						|
            return;
 | 
						|
        }
 | 
						|
    }
 | 
						|
    else if (value->key() == Qt::Key_Up)
 | 
						|
    {
 | 
						|
        quint64 e = findExponent(m_cursor);
 | 
						|
 | 
						|
        if (value->modifiers() & Qt::ShiftModifier) {
 | 
						|
            e *= 5;
 | 
						|
        } else if (value->modifiers() & Qt::ControlModifier) {
 | 
						|
            e *= 2;
 | 
						|
        }
 | 
						|
 | 
						|
        if (m_animationState != 0) {
 | 
						|
            m_value = m_valueNew;
 | 
						|
        }
 | 
						|
 | 
						|
        if (m_valueMax - m_value < e) {
 | 
						|
            m_valueNew = m_valueMax;
 | 
						|
        } else {
 | 
						|
            m_valueNew = m_value + e;
 | 
						|
        }
 | 
						|
 | 
						|
        setValue(m_valueNew);
 | 
						|
        emit changed(m_valueNew);
 | 
						|
    }
 | 
						|
    else if (value->key() == Qt::Key_Down)
 | 
						|
    {
 | 
						|
        quint64 e = findExponent(m_cursor);
 | 
						|
 | 
						|
        if (value->modifiers() & Qt::ShiftModifier) {
 | 
						|
            e *= 5;
 | 
						|
        } else if (value->modifiers() & Qt::ControlModifier) {
 | 
						|
            e *= 2;
 | 
						|
        }
 | 
						|
 | 
						|
        if (m_animationState != 0) {
 | 
						|
            m_value = m_valueNew;
 | 
						|
        }
 | 
						|
 | 
						|
        if (m_value < e) {
 | 
						|
            m_valueNew = m_valueMin;
 | 
						|
        } else {
 | 
						|
            m_valueNew = 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')))
 | 
						|
    {
 | 
						|
        if (m_animationState != 0) {
 | 
						|
            m_value = m_valueNew;
 | 
						|
        }
 | 
						|
 | 
						|
        int d = c.toLatin1() - '0';
 | 
						|
        quint64 e = findExponent(m_cursor);
 | 
						|
        quint64 v = (m_value / e) % 10;
 | 
						|
 | 
						|
        v = m_value - v * e;
 | 
						|
        v += d * e;
 | 
						|
        setValue(v);
 | 
						|
        emit changed(m_valueNew);
 | 
						|
        m_cursor++;
 | 
						|
 | 
						|
        if (m_text[m_cursor] == m_groupSeparator) {
 | 
						|
            m_cursor++;
 | 
						|
        }
 | 
						|
 | 
						|
        if (m_cursor >= m_numDigits + m_numDecimalPoints)
 | 
						|
        {
 | 
						|
            m_cursor = -1;
 | 
						|
            m_blinkTimer.stop();
 | 
						|
        }
 | 
						|
        else
 | 
						|
        {
 | 
						|
            m_cursorState = true;
 | 
						|
        }
 | 
						|
 | 
						|
        update();
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
void ValueDial::focusInEvent(QFocusEvent *)
 | 
						|
{
 | 
						|
    if (m_cursor == -1)
 | 
						|
    {
 | 
						|
        m_cursor = 0;
 | 
						|
        m_cursorState = true;
 | 
						|
        m_blinkTimer.start(400);
 | 
						|
        update();
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
void ValueDial::focusOutEvent(QFocusEvent *)
 | 
						|
{
 | 
						|
    m_cursor = -1;
 | 
						|
    m_blinkTimer.stop();
 | 
						|
    update();
 | 
						|
}
 | 
						|
 | 
						|
void ValueDial::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 ValueDial::blink()
 | 
						|
{
 | 
						|
    if (m_cursor >= 0)
 | 
						|
    {
 | 
						|
        m_cursorState = !m_cursorState;
 | 
						|
        update();
 | 
						|
    }
 | 
						|
}
 |