# HG changeset patch # User Chris Cannam # Date 1481725721 0 # Node ID 8665e0ffa0d8fac26fa49b7b31dd8032d9d3ea56 # Parent 6a6a63506e3f86b2b880232374c209430843417c# Parent f32828ea63d9d7fa18ccdd44822960735b2adc9b Merge from branch 3.0-integration diff -r f32828ea63d9 -r 8665e0ffa0d8 files.pri --- a/files.pri Wed Dec 14 11:56:47 2016 +0000 +++ b/files.pri Wed Dec 14 14:28:41 2016 +0000 @@ -80,6 +80,7 @@ widgets/TipDialog.h \ widgets/TransformFinder.h \ widgets/UnitConverter.h \ + widgets/WidgetScale.h \ widgets/WindowShapePreview.h \ widgets/WindowTypeSelector.h diff -r f32828ea63d9 -r 8665e0ffa0d8 widgets/LEDButton.cpp --- a/widgets/LEDButton.cpp Wed Dec 14 11:56:47 2016 +0000 +++ b/widgets/LEDButton.cpp Wed Dec 14 14:28:41 2016 +0000 @@ -23,6 +23,7 @@ #include "LEDButton.h" +#include "WidgetScale.h" #include #include @@ -279,12 +280,12 @@ QSize LEDButton::sizeHint() const { - return QSize(17, 17); + return WidgetScale::scaleQSize(QSize(17, 17)); } QSize LEDButton::minimumSizeHint() const { - return QSize(17, 17); + return WidgetScale::scaleQSize(QSize(17, 17)); } diff -r f32828ea63d9 -r 8665e0ffa0d8 widgets/LEDButton.h --- a/widgets/LEDButton.h Wed Dec 14 11:56:47 2016 +0000 +++ b/widgets/LEDButton.h Wed Dec 14 14:28:41 2016 +0000 @@ -25,8 +25,8 @@ sunken variant. This version also implements a simple button API. */ -#ifndef _LED_BUTTON_H_ -#define _LED_BUTTON_H_ +#ifndef SV_LED_BUTTON_H +#define SV_LED_BUTTON_H #include #include "base/Debug.h" diff -r f32828ea63d9 -r 8665e0ffa0d8 widgets/LevelPanToolButton.cpp --- a/widgets/LevelPanToolButton.cpp Wed Dec 14 11:56:47 2016 +0000 +++ b/widgets/LevelPanToolButton.cpp Wed Dec 14 14:28:41 2016 +0000 @@ -170,4 +170,18 @@ m_lpw->renderTo(this, QRectF(margin, margin, m_pixels, m_pixels), false); } +void +LevelPanToolButton::enterEvent(QEvent *e) +{ + QToolButton::enterEvent(e); + emit mouseEntered(); +} +void +LevelPanToolButton::leaveEvent(QEvent *e) +{ + QToolButton::enterEvent(e); + emit mouseLeft(); +} + + diff -r f32828ea63d9 -r 8665e0ffa0d8 widgets/LevelPanToolButton.h --- a/widgets/LevelPanToolButton.h Wed Dec 14 11:56:47 2016 +0000 +++ b/widgets/LevelPanToolButton.h Wed Dec 14 14:28:41 2016 +0000 @@ -56,12 +56,17 @@ void levelChanged(float); void panChanged(float); + void mouseEntered(); + void mouseLeft(); + private slots: void selfLevelChanged(float); void selfClicked(); protected: - void paintEvent(QPaintEvent *); + virtual void paintEvent(QPaintEvent *); + virtual void enterEvent(QEvent *); + virtual void leaveEvent(QEvent *); LevelPanWidget *m_lpw; int m_pixels; diff -r f32828ea63d9 -r 8665e0ffa0d8 widgets/LevelPanWidget.cpp --- a/widgets/LevelPanWidget.cpp Wed Dec 14 11:56:47 2016 +0000 +++ b/widgets/LevelPanWidget.cpp Wed Dec 14 14:28:41 2016 +0000 @@ -21,6 +21,8 @@ #include "layer/ColourMapper.h" #include "base/AudioLevel.h" +#include "WidgetScale.h" + #include #include #include @@ -35,6 +37,8 @@ QWidget(parent), m_level(maxLevel), m_pan(0), + m_monitorLeft(-1), + m_monitorRight(-1), m_editable(true), m_includeMute(true) { @@ -47,22 +51,7 @@ QSize LevelPanWidget::sizeHint() const { - static double ratio = 0.0; - if (ratio == 0.0) { - double baseEm; -#ifdef Q_OS_MAC - baseEm = 17.0; -#else - baseEm = 15.0; -#endif - double em = QFontMetrics(QFont()).height(); - ratio = em / baseEm; - } - - int pixels = 40; - int scaled = int(pixels * ratio + 0.5); - if (pixels != 0 && scaled == 0) scaled = 1; - return QSize(scaled, scaled); + return WidgetScale::scaleQSize(QSize(40, 40)); } static int @@ -91,18 +80,36 @@ else return -20.; } +int +LevelPanWidget::audioLevelToLevel(float audioLevel, bool withMute) +{ + int level; + if (withMute) { + level = AudioLevel::multiplier_to_fader + (audioLevel, maxLevel, AudioLevel::ShortFader); + } else { + level = db_to_level(AudioLevel::multiplier_to_dB(audioLevel)); + } + if (level < 0) level = 0; + if (level > maxLevel) level = maxLevel; + return level; +} + +float +LevelPanWidget::levelToAudioLevel(int level, bool withMute) +{ + if (withMute) { + return float(AudioLevel::fader_to_multiplier + (level, maxLevel, AudioLevel::ShortFader)); + } else { + return float(AudioLevel::dB_to_multiplier(level_to_db(level))); + } +} + void LevelPanWidget::setLevel(float flevel) { - int level; - if (m_includeMute) { - level = AudioLevel::multiplier_to_fader - (flevel, maxLevel, AudioLevel::ShortFader); - } else { - level = db_to_level(AudioLevel::multiplier_to_dB(flevel)); - } - if (level < 0) level = 0; - if (level > maxLevel) level = maxLevel; + int level = audioLevelToLevel(flevel, m_includeMute); if (level != m_level) { m_level = level; float convertsTo = getLevel(); @@ -116,20 +123,45 @@ float LevelPanWidget::getLevel() const { - if (m_includeMute) { - return float(AudioLevel::fader_to_multiplier - (m_level, maxLevel, AudioLevel::ShortFader)); - } else { - return float(AudioLevel::dB_to_multiplier(level_to_db(m_level))); + return levelToAudioLevel(m_level, m_includeMute); +} + +int +LevelPanWidget::audioPanToPan(float audioPan) +{ + int pan = int(round(audioPan * maxPan)); + if (pan < -maxPan) pan = -maxPan; + if (pan > maxPan) pan = maxPan; + return pan; +} + +float +LevelPanWidget::panToAudioPan(int pan) +{ + return float(pan) / float(maxPan); +} + +void +LevelPanWidget::setPan(float fpan) +{ + int pan = audioPanToPan(fpan); + if (pan != m_pan) { + m_pan = pan; + update(); } } +float +LevelPanWidget::getPan() const +{ + return panToAudioPan(m_pan); +} + void -LevelPanWidget::setPan(float pan) +LevelPanWidget::setMonitoringLevels(float left, float right) { - m_pan = int(round(pan * maxPan)); - if (m_pan < -maxPan) m_pan = -maxPan; - if (m_pan > maxPan) m_pan = maxPan; + m_monitorLeft = left; + m_monitorRight = right; update(); } @@ -160,12 +192,6 @@ update(); } -float -LevelPanWidget::getPan() const -{ - return float(m_pan) / float(maxPan); -} - void LevelPanWidget::emitLevelChanged() { @@ -338,11 +364,33 @@ pen.setWidthF(cellLightSize(rect).width() + thin); pen.setCapStyle(Qt::RoundCap); paint.setPen(pen); + paint.setBrush(Qt::NoBrush); for (int pan = -maxPan; pan <= maxPan; ++pan) { paint.drawLine(cellCentre(rect, 0, pan), cellCentre(rect, maxLevel, pan)); } + if (m_monitorLeft > 0.f || m_monitorRight > 0.f) { + paint.setPen(Qt::NoPen); + for (int pan = -maxPan; pan <= maxPan; ++pan) { + float audioPan = panToAudioPan(pan); + float audioLevel; + if (audioPan < 0.f) { + audioLevel = m_monitorLeft + m_monitorRight * (1.f + audioPan); + } else { + audioLevel = m_monitorRight + m_monitorLeft * (1.f - audioPan); + } + int levelHere = audioLevelToLevel(audioLevel, false); + for (int level = 0; level <= levelHere; ++level) { + paint.setBrush(level_to_colour(level)); + QRectF clr = cellLightRect(rect, level, pan); + paint.drawEllipse(clr); + } + } + paint.setPen(pen); + paint.setBrush(Qt::NoBrush); + } + if (isEnabled()) { pen.setColor(Qt::black); } else { @@ -384,5 +432,17 @@ renderTo(this, rect(), m_editable); } +void +LevelPanWidget::enterEvent(QEvent *e) +{ + QWidget::enterEvent(e); + emit mouseEntered(); +} +void +LevelPanWidget::leaveEvent(QEvent *e) +{ + QWidget::enterEvent(e); + emit mouseLeft(); +} diff -r f32828ea63d9 -r 8665e0ffa0d8 widgets/LevelPanWidget.h --- a/widgets/LevelPanWidget.h Wed Dec 14 11:56:47 2016 +0000 +++ b/widgets/LevelPanWidget.h Wed Dec 14 14:28:41 2016 +0000 @@ -53,6 +53,9 @@ /// Set pan in the range [-1,1] -- will be rounded void setPan(float); + /// Set left and right peak monitoring levels in the range [0,1] + void setMonitoringLevels(float, float); + /// Specify whether the widget is editable or read-only (default editable) void setEditable(bool); @@ -60,24 +63,37 @@ void setIncludeMute(bool); signals: - void levelChanged(float); - void panChanged(float); + void levelChanged(float); // range [0,1] + void panChanged(float); // range [-1,1] + void mouseEntered(); + void mouseLeft(); + protected: virtual void mousePressEvent(QMouseEvent *ev); virtual void mouseMoveEvent(QMouseEvent *ev); virtual void mouseReleaseEvent(QMouseEvent *ev); virtual void wheelEvent(QWheelEvent *ev); virtual void paintEvent(QPaintEvent *ev); + virtual void enterEvent(QEvent *); + virtual void leaveEvent(QEvent *); void emitLevelChanged(); void emitPanChanged(); int m_level; int m_pan; + float m_monitorLeft; + float m_monitorRight; bool m_editable; bool m_includeMute; + static int audioLevelToLevel(float audioLevel, bool withMute); + static float levelToAudioLevel(int level, bool withMute); + + static int audioPanToPan(float audioPan); + static float panToAudioPan(int pan); + QSizeF cellSize(QRectF) const; QPointF cellCentre(QRectF, int level, int pan) const; QSizeF cellLightSize(QRectF) const; diff -r f32828ea63d9 -r 8665e0ffa0d8 widgets/ModelDataTableDialog.cpp --- a/widgets/ModelDataTableDialog.cpp Wed Dec 14 11:56:47 2016 +0000 +++ b/widgets/ModelDataTableDialog.cpp Wed Dec 14 14:28:41 2016 +0000 @@ -61,7 +61,7 @@ toolbar = addToolBar(tr("Edit Toolbar")); - action = new QAction(il.load("datainsert"), tr("Insert New Item"), this); + action = new QAction(il.load("draw"), tr("Insert New Item"), this); action->setShortcut(tr("Insert")); action->setStatusTip(tr("Insert a new item")); connect(action, SIGNAL(triggered()), this, SLOT(insertRow())); diff -r f32828ea63d9 -r 8665e0ffa0d8 widgets/NotifyingPushButton.h --- a/widgets/NotifyingPushButton.h Wed Dec 14 11:56:47 2016 +0000 +++ b/widgets/NotifyingPushButton.h Wed Dec 14 14:28:41 2016 +0000 @@ -26,8 +26,8 @@ class NotifyingPushButton : public QPushButton { Q_OBJECT + public: - NotifyingPushButton(QWidget *parent = 0) : QPushButton(parent) { } diff -r f32828ea63d9 -r 8665e0ffa0d8 widgets/PropertyBox.cpp --- a/widgets/PropertyBox.cpp Wed Dec 14 11:56:47 2016 +0000 +++ b/widgets/PropertyBox.cpp Wed Dec 14 14:28:41 2016 +0000 @@ -27,6 +27,9 @@ #include "AudioDial.h" #include "LEDButton.h" #include "IconLoader.h" +#include "LevelPanWidget.h" +#include "LevelPanToolButton.h" +#include "WidgetScale.h" #include "NotifyingCheckBox.h" #include "NotifyingComboBox.h" @@ -174,14 +177,44 @@ if (params) { - QLabel *playLabel = new QLabel(tr("Play")); - layout->addWidget(playLabel); - layout->setAlignment(playLabel, Qt::AlignVCenter); + layout->insertStretch(-1, 10); - m_playButton = new LEDButton(Qt::darkGreen); - m_playButton->setState(!params->isPlayMuted()); + if (params->getPlayClipId() != "") { + NotifyingPushButton *playParamButton = new NotifyingPushButton; + playParamButton->setObjectName("playParamButton"); + playParamButton->setIcon(IconLoader().load("faders")); + playParamButton->setFixedWidth(WidgetScale::scalePixelSize(24)); + playParamButton->setFixedHeight(WidgetScale::scalePixelSize(24)); + layout->addWidget(playParamButton); + connect(playParamButton, SIGNAL(clicked()), + this, SLOT(editPlayParameters())); + connect(playParamButton, SIGNAL(mouseEntered()), + this, SLOT(mouseEnteredWidget())); + connect(playParamButton, SIGNAL(mouseLeft()), + this, SLOT(mouseLeftWidget())); + } + + LevelPanToolButton *levelPan = new LevelPanToolButton; + layout->addWidget(levelPan); + connect(levelPan, SIGNAL(levelChanged(float)), + this, SLOT(playGainControlChanged(float))); + connect(levelPan, SIGNAL(panChanged(float)), + this, SLOT(playPanControlChanged(float))); + connect(params, SIGNAL(playGainChanged(float)), + levelPan, SLOT(setLevel(float))); + connect(params, SIGNAL(playPanChanged(float)), + levelPan, SLOT(setPan(float))); + connect(levelPan, SIGNAL(mouseEntered()), + this, SLOT(mouseEnteredWidget())); + connect(levelPan, SIGNAL(mouseLeft()), + this, SLOT(mouseLeftWidget())); + + m_playButton = new NotifyingPushButton; + m_playButton->setCheckable(true); + m_playButton->setIcon(IconLoader().load("speaker")); + m_playButton->setChecked(!params->isPlayMuted()); layout->addWidget(m_playButton); - connect(m_playButton, SIGNAL(stateChanged(bool)), + connect(m_playButton, SIGNAL(toggled(bool)), this, SLOT(playAudibleButtonChanged(bool))); connect(m_playButton, SIGNAL(mouseEntered()), this, SLOT(mouseEnteredWidget())); @@ -191,71 +224,6 @@ this, SLOT(playAudibleChanged(bool))); layout->setAlignment(m_playButton, Qt::AlignVCenter); - layout->insertStretch(-1, 10); - - if (params->getPlayClipId() != "") { - QPushButton *playParamButton = - new QPushButton(QIcon(":icons/faders.png"), ""); - playParamButton->setFixedWidth(24); - playParamButton->setFixedHeight(24); - layout->addWidget(playParamButton); - connect(playParamButton, SIGNAL(clicked()), - this, SLOT(editPlayParameters())); - } - - AudioDial *gainDial = new AudioDial; - layout->addWidget(gainDial); - gainDial->setMeterColor(Qt::darkRed); - gainDial->setMinimum(-50); - gainDial->setMaximum(50); - gainDial->setPageStep(1); - gainDial->setFixedWidth(24); - gainDial->setFixedHeight(24); - gainDial->setNotchesVisible(false); - gainDial->setObjectName(tr("Playback Gain")); - gainDial->setRangeMapper(new LinearRangeMapper - (-50, 50, -25, 25, tr("dB"))); - gainDial->setDefaultValue(0); - gainDial->setShowToolTip(true); - connect(gainDial, SIGNAL(valueChanged(int)), - this, SLOT(playGainDialChanged(int))); - connect(params, SIGNAL(playGainChanged(float)), - this, SLOT(playGainChanged(float))); - connect(this, SIGNAL(changePlayGainDial(int)), - gainDial, SLOT(setValue(int))); - connect(gainDial, SIGNAL(mouseEntered()), - this, SLOT(mouseEnteredWidget())); - connect(gainDial, SIGNAL(mouseLeft()), - this, SLOT(mouseLeftWidget())); - playGainChanged(params->getPlayGain()); - layout->setAlignment(gainDial, Qt::AlignVCenter); - - AudioDial *panDial = new AudioDial; - layout->addWidget(panDial); - panDial->setMeterColor(Qt::darkGreen); - panDial->setMinimum(-50); - panDial->setMaximum(50); - panDial->setPageStep(1); - panDial->setFixedWidth(24); - panDial->setFixedHeight(24); - panDial->setNotchesVisible(false); - panDial->setToolTip(tr("Playback Pan / Balance")); - panDial->setDefaultValue(0); - panDial->setObjectName(tr("Playback Pan / Balance")); - panDial->setShowToolTip(true); - connect(panDial, SIGNAL(valueChanged(int)), - this, SLOT(playPanDialChanged(int))); - connect(params, SIGNAL(playPanChanged(float)), - this, SLOT(playPanChanged(float))); - connect(this, SIGNAL(changePlayPanDial(int)), - panDial, SLOT(setValue(int))); - connect(panDial, SIGNAL(mouseEntered()), - this, SLOT(mouseEnteredWidget())); - connect(panDial, SIGNAL(mouseLeft()), - this, SLOT(mouseLeftWidget())); - playPanChanged(params->getPlayPan()); - layout->setAlignment(panDial, Qt::AlignVCenter); - } else { layout->insertStretch(-1, 10); @@ -330,7 +298,7 @@ QIcon icon(IconLoader().load(iconName)); button->setIcon(icon); button->setObjectName(name); - button->setFixedSize(QSize(18, 18)); + button->setFixedSize(WidgetScale::scaleQSize(QSize(18, 18))); } else { button = new NotifyingCheckBox(); button->setObjectName(name); @@ -397,13 +365,13 @@ this, SLOT(mouseLeftWidget())); if (inGroup) { - dial->setFixedWidth(24); - dial->setFixedHeight(24); + dial->setFixedWidth(WidgetScale::scalePixelSize(24)); + dial->setFixedHeight(WidgetScale::scalePixelSize(24)); m_groupLayouts[groupName]->addWidget (dial, 0, m_groupLayouts[groupName]->columnCount()); } else { - dial->setFixedWidth(32); - dial->setFixedHeight(32); + dial->setFixedWidth(WidgetScale::scalePixelSize(32)); + dial->setFixedHeight(WidgetScale::scalePixelSize(32)); m_layout->addWidget(dial, row, 1); QLabel *label = new QLabel(m_mainWidget); connect(dial, SIGNAL(valueChanged(int)), @@ -691,7 +659,7 @@ void PropertyBox::playAudibleChanged(bool audible) { - m_playButton->setState(audible); + m_playButton->setChecked(audible); } void @@ -707,26 +675,15 @@ CommandHistory::getInstance()->addCommand(command, true, true); } } - -void -PropertyBox::playGainChanged(float gain) -{ - int dialValue = int(lrint(log10(gain) * 20.0)); - if (dialValue < -50) dialValue = -50; - if (dialValue > 50) dialValue = 50; - emit changePlayGainDial(dialValue); -} void -PropertyBox::playGainDialChanged(int dialValue) +PropertyBox::playGainControlChanged(float gain) { QObject *obj = sender(); PlayParameters *params = m_container->getPlayParameters(); if (!params) return; - float gain = float(pow(10, float(dialValue) / 20.0)); - if (params->getPlayGain() != gain) { PlayParameterRepository::EditCommand *command = new PlayParameterRepository::EditCommand(params); @@ -736,28 +693,15 @@ updateContextHelp(obj); } - -void -PropertyBox::playPanChanged(float pan) -{ - int dialValue = int(lrint(pan * 50.0)); - if (dialValue < -50) dialValue = -50; - if (dialValue > 50) dialValue = 50; - emit changePlayPanDial(dialValue); -} void -PropertyBox::playPanDialChanged(int dialValue) +PropertyBox::playPanControlChanged(float pan) { QObject *obj = sender(); PlayParameters *params = m_container->getPlayParameters(); if (!params) return; - float pan = float(dialValue) / 50.f; - if (pan < -1.f) pan = -1.f; - if (pan > 1.f) pan = 1.f; - if (params->getPlayPan() != pan) { PlayParameterRepository::EditCommand *command = new PlayParameterRepository::EditCommand(params); @@ -849,10 +793,27 @@ QString cname = m_container->getPropertyContainerName(); if (cname == "") return; + LevelPanToolButton *lp = qobject_cast(w); + if (lp) { + emit contextHelpChanged(tr("Adjust playback level and pan of %1").arg(cname)); + return; + } + QString wname = w->objectName(); + if (wname == "playParamButton") { + PlayParameters *params = m_container->getPlayParameters(); + if (params) { + emit contextHelpChanged + (tr("Change sound used for playback (currently \"%1\")") + .arg(params->getPlayClipId())); + return; + } + } + QString extraText; - AudioDial *dial = dynamic_cast(w); + + AudioDial *dial = qobject_cast(w); if (dial) { double mv = dial->mappedValue(); QString unit = ""; diff -r f32828ea63d9 -r 8665e0ffa0d8 widgets/PropertyBox.h --- a/widgets/PropertyBox.h Wed Dec 14 11:56:47 2016 +0000 +++ b/widgets/PropertyBox.h Wed Dec 14 14:28:41 2016 +0000 @@ -27,6 +27,7 @@ class QVBoxLayout; class QLabel; class LEDButton; +class NotifyingPushButton; class PropertyBox : public QFrame { @@ -39,8 +40,6 @@ PropertyContainer *getContainer() { return m_container; } signals: - void changePlayGainDial(int); - void changePlayPanDial(int); void showLayer(bool); void contextHelpChanged(const QString &); @@ -56,10 +55,8 @@ void playAudibleChanged(bool); void playAudibleButtonChanged(bool); - void playGainChanged(float); - void playGainDialChanged(int); - void playPanChanged(float); - void playPanDialChanged(int); + void playGainControlChanged(float); + void playPanControlChanged(float); void populateViewPlayFrame(); @@ -84,7 +81,7 @@ QFrame *m_viewPlayFrame; QVBoxLayout *m_mainBox; LEDButton *m_showButton; - LEDButton *m_playButton; + NotifyingPushButton *m_playButton; std::map m_groupLayouts; std::map m_propertyControllers; }; diff -r f32828ea63d9 -r 8665e0ffa0d8 widgets/PropertyStack.cpp --- a/widgets/PropertyStack.cpp Wed Dec 14 11:56:47 2016 +0000 +++ b/widgets/PropertyStack.cpp Wed Dec 14 14:28:41 2016 +0000 @@ -25,6 +25,8 @@ #include "widgets/CommandHistory.h" #include "layer/ShowLayerCommand.h" +#include "WidgetScale.h" + #include #include @@ -45,11 +47,9 @@ setTabBar(bar); -#if (QT_VERSION >= 0x0402) setElideMode(Qt::ElideNone); tabBar()->setUsesScrollButtons(true); - tabBar()->setIconSize(QSize(16, 16)); -#endif + tabBar()->setIconSize(WidgetScale::scaleQSize(QSize(16, 16))); repopulate(); diff -r f32828ea63d9 -r 8665e0ffa0d8 widgets/WidgetScale.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/widgets/WidgetScale.h Wed Dec 14 14:28:41 2016 +0000 @@ -0,0 +1,54 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Sonic Visualiser + An audio file viewer and annotation editor. + Centre for Digital Music, Queen Mary, University of London. + + 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 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + +#ifndef SV_WIDGET_SCALE_H +#define SV_WIDGET_SCALE_H + +#include +#include + +class WidgetScale +{ +public: + /** + * Take a "design pixel" size and scale it for the actual + * display. This is relevant to hi-dpi systems that do not do + * pixel doubling (i.e. Windows and Linux rather than OS/X). + */ + static int scalePixelSize(int pixels) { + + static double ratio = 0.0; + if (ratio == 0.0) { + double baseEm; +#ifdef Q_OS_MAC + baseEm = 17.0; +#else + baseEm = 15.0; +#endif + double em = QFontMetrics(QFont()).height(); + ratio = em / baseEm; + } + + int scaled = int(pixels * ratio + 0.5); + if (pixels != 0 && scaled == 0) scaled = 1; + return scaled; + } + + static QSize scaleQSize(QSize size) { + return QSize(scalePixelSize(size.width()), + scalePixelSize(size.height())); + } +}; + +#endif