Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/2.4'
Browse files Browse the repository at this point in the history
  • Loading branch information
ferranpujolcamins committed Jun 25, 2023
2 parents a5ae80a + bd3a6f5 commit 5f22560
Show file tree
Hide file tree
Showing 11 changed files with 185 additions and 37 deletions.
7 changes: 6 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1267,6 +1267,10 @@ if(APPLE)
# will automatically insert retain/release calls on Objective-C objects.
target_compile_options(mixxx-lib PUBLIC -fobjc-arc)

target_sources(mixxx-lib PRIVATE
src/util/darkappearance.mm
)

option(MACOS_ITUNES_LIBRARY "Native macOS iTunes/Music.app library integration" ON)
if(MACOS_ITUNES_LIBRARY)
target_sources(mixxx-lib PRIVATE
Expand Down Expand Up @@ -1819,7 +1823,8 @@ add_executable(mixxx-test
src/test/hotcuecontrol_test.cpp
src/test/imageutils_test.cpp
src/test/indexrange_test.cpp
src/test/itunesxmlimportertest.cpp
# TODO: reanable this after https://github.com/mixxxdj/mixxx/pull/11666
# src/test/itunesxmlimportertest.cpp
src/test/keyutilstest.cpp
src/test/lcstest.cpp
src/test/learningutilstest.cpp
Expand Down
46 changes: 41 additions & 5 deletions res/controllers/hid-controller-api.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,54 @@ declare namespace controller {
* @param dataList Data to send as list of bytes
* @param length Unused but mandatory argument for backwards compatibility
* @param reportID 1...255 for HID devices that uses ReportIDs - or 0 for devices, which don't use ReportIDs
* @param resendUnchangedReport If set, the report will also be send, if the data are unchanged since last sending [default = false]
* @param useNonSkippingFIFO If set, the report will send in FIFO mode
*
* `false` (default):
* - Reports with identical data will be sent only once.
* - If reports were superseded by newer data before they could be sent,
* the oudated data will be skipped.
* - This mode works for all USB HID class compatible reports,
* in these each field represents the state of a control (e.g. an LED).
* - This mode works best in overload situations, where more reports
* are to be sent, than can be processed.
*
* `true`:
* - The report will not be skipped under any circumstances,
* except FIFO memory overflow.
* - All reports with useNonSkippingFIFO set `true` will be send before
* any cached report with useNonSkippingFIFO set `false`.
* - All reports with useNonSkippingFIFO set `true` will be send in
* strict First In / First Out (FIFO) order.
* - Limit the use of this mode to the places, where it is really necessary.
*/
function send(dataList: number[], length: number, reportID: number, resendUnchangedReport?: boolean): void;
function send(dataList: number[], length: number, reportID: number, useNonSkippingFIFO?: boolean): void;

/**
* Sends an OutputReport to HID device
*
* @param reportID 1...255 for HID devices that uses ReportIDs - or 0 for devices, which don't use ReportIDs
* @param dataArray Data to send as byte array
* @param resendUnchangedReport If set, the report will also be send, if the data are unchanged since last sending [default = false]
* @param useNonSkippingFIFO If set, the report will send in FIFO mode
*
* `false` (default):
* - Reports with identical data will be sent only once.
* - If reports were superseded by newer data before they could be sent,
* the oudated data will be skipped.
* - This mode works for all USB HID class compatible reports,
* in these each field represents the state of a control (e.g. an LED).
* - This mode works best in overload situations, where more reports
* are to be sent, than can be processed.
*
* `true`:
* - The report will not be skipped under any circumstances,
* except FIFO memory overflow.
* - All reports with useNonSkippingFIFO set `true` will be send before
* any cached report with useNonSkippingFIFO set `false`.
* - All reports with useNonSkippingFIFO set `true` will be send in
* strict First In / First Out (FIFO) order.
* - Limit the use of this mode to the places, where it is really necessary.
*/
function sendOutputReport(reportID: number, dataArray: ArrayBuffer, resendUnchangedReport?: boolean): void;
function sendOutputReport(reportID: number, dataArray: ArrayBuffer, useNonSkippingFIFO?: boolean): void;

/**
* getInputReport receives an InputReport from the HID device on request.
Expand All @@ -56,7 +92,7 @@ declare namespace controller {
*
* @param reportID 1...255 for HID devices that uses ReportIDs - or 0 for devices, which don't use
* @returns The returned array matches the input format of sendFeatureReport,
* allowing it to be read, modified and sent it back to the controller.
* allowing it to be read, modified and sent it back to the controller.
*/
function getFeatureReport(reportID: number): ArrayBuffer;
}
33 changes: 18 additions & 15 deletions src/library/basetracktablemodel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -590,21 +590,9 @@ QVariant BaseTrackTableModel::roleValue(
break;
}
M_FALLTHROUGH_INTENDED;
// Right align BPM, duraation and bitrate so big/small values can easily be
// spotted by length (number of digits)
case Qt::TextAlignmentRole: {
switch (field) {
case ColumnCache::COLUMN_LIBRARYTABLE_BPM:
case ColumnCache::COLUMN_LIBRARYTABLE_DURATION:
case ColumnCache::COLUMN_LIBRARYTABLE_BITRATE: {
// We need to cast to int due to a bug similar to
// https://bugreports.qt.io/browse/QTBUG-67582
return static_cast<int>(Qt::AlignVCenter | Qt::AlignRight);
}
default:
return QVariant(); // default AlignLeft for all other columns
}
}
// NOTE: for export we need to fall through to Qt::DisplayRole,
// so do not add any other role cases here, or the export
// will be empty
case Qt::DisplayRole:
switch (field) {
case ColumnCache::COLUMN_LIBRARYTABLE_DURATION: {
Expand Down Expand Up @@ -873,6 +861,21 @@ QVariant BaseTrackTableModel::roleValue(
return Qt::PartiallyChecked;
}
}
// Right align BPM, duration and bitrate so big/small values can easily be
// spotted by length (number of digits)
case Qt::TextAlignmentRole: {
switch (field) {
case ColumnCache::COLUMN_LIBRARYTABLE_BPM:
case ColumnCache::COLUMN_LIBRARYTABLE_DURATION:
case ColumnCache::COLUMN_LIBRARYTABLE_BITRATE: {
// We need to cast to int due to a bug similar to
// https://bugreports.qt.io/browse/QTBUG-67582
return static_cast<int>(Qt::AlignVCenter | Qt::AlignRight);
}
default:
return QVariant(); // default AlignLeft for all other columns
}
}
default:
DEBUG_ASSERT(!"unexpected role");
break;
Expand Down
56 changes: 56 additions & 0 deletions src/preferences/dialog/dlgpreferences.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,10 @@
#include "util/color/color.h"
#include "util/widgethelper.h"

#ifdef __APPLE__
#include "util/darkappearance.h"
#endif

DlgPreferences::DlgPreferences(
std::shared_ptr<mixxx::ScreensaverManager> pScreensaverManager,
std::shared_ptr<mixxx::skin::SkinLoader> pSkinLoader,
Expand All @@ -61,6 +65,7 @@ DlgPreferences::DlgPreferences(
m_pConfig(pSettingsManager->settings()),
m_pageSizeHint(QSize(0, 0)) {
setupUi(this);
fixSliderStyle();
contentsTreeWidget->setHeaderHidden(true);

// Add '&' to default button labels to always have Alt shortcuts, indpependent
Expand Down Expand Up @@ -564,3 +569,54 @@ QRect DlgPreferences::getDefaultGeometry() {

return optimumRect;
}

void DlgPreferences::fixSliderStyle() {
#ifdef __APPLE__
// Only used on macOS where the default slider style has several issues:
// - the handle is semi-transparent
// - the slider is higher than the space we give it, which causes that:
// - the groove is not correctly centered vertically
// - the handle is cut off at the top
// The style below is based on sliders in the macOS system settings dialogs.
if (darkAppearance()) {
setStyleSheet(R"--(
QSlider::handle:horizontal {
background-color: #8f8c8b;
border-radius: 4px;
width: 8px;
margin: -8px;
}
QSlider::handle:horizontal::pressed {
background-color: #a9a7a7;
}
QSlider::groove:horizontal {
background: #1e1e1e;
height: 4px;
border-radius: 2px;
margin-left: 8px;
margin-right: 8px;
}
)--");
} else {
setStyleSheet(R"--(
QSlider::handle:horizontal {
background-color: #ffffff;
border-radius: 4px;
border: 1px solid #d4d3d3;
width: 7px;
margin: -8px;
}
QSlider::handle:horizontal::pressed {
background-color: #ececec;
}
QSlider::groove:horizontal {
background: #c6c5c5;
height: 4px;
border-radius: 2px;
margin-left: 8px;
margin-right: 8px;
}
)--");
}
#endif // __APPLE__
}
1 change: 1 addition & 0 deletions src/preferences/dialog/dlgpreferences.h
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ class DlgPreferences : public QDialog, public Ui::DlgPreferencesDlg {

private:
DlgPreferencePage* currentPage();
void fixSliderStyle();
QList<PreferencesPage> m_allPages;
void onShow();
void onHide();
Expand Down
2 changes: 1 addition & 1 deletion src/preferences/dialog/dlgprefwaveformdlg.ui
Original file line number Diff line number Diff line change
Expand Up @@ -490,7 +490,7 @@ Select from different types of displays for the waveform, which differ primarily
</property>
</widget>
</item>
<item row="4" column="1">
<item row="4" column="1" colspan="2">
<widget class="QSlider" name="beatGridAlphaSlider">
<property name="maximum">
<number>100</number>
Expand Down
1 change: 1 addition & 0 deletions src/util/darkappearance.h
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
bool darkAppearance();
14 changes: 14 additions & 0 deletions src/util/darkappearance.mm
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#include "util/darkappearance.h"
#import <AppKit/NSApplication.h>

bool darkAppearance() {
if (__builtin_available(macOS 10.14, *)) {
auto appearance =
[NSApp.effectiveAppearance bestMatchFromAppearancesWithNames:@[
NSAppearanceNameAqua,
NSAppearanceNameDarkAqua
]];
return [appearance isEqualToString:NSAppearanceNameDarkAqua];
}
return false;
}
29 changes: 23 additions & 6 deletions src/waveform/waveformwidgetfactory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

#include <QGuiApplication>
#include <QOpenGLFunctions>
#include <QRegularExpression>
#include <QStringList>
#include <QTime>
#include <QWidget>
Expand Down Expand Up @@ -71,6 +72,8 @@ bool shouldRenderWaveform(WaveformWidgetAbstract* pWaveformWidget) {

return glw->shouldRender();
}

const QRegularExpression openGLVersionRegex(QStringLiteral("^(\\d+)\\.(\\d+).*$"));
} // anonymous namespace

///////////////////////////////////////////
Expand Down Expand Up @@ -142,13 +145,27 @@ WaveformWidgetFactory::WaveformWidgetFactory()
reinterpret_cast<const char*>(glFunctions->glGetString(GL_VENDOR))));
QString rendererString = QString(QLatin1String(
reinterpret_cast<const char*>(glFunctions->glGetString(GL_RENDERER))));
qDebug() << versionString << vendorString << rendererString;

// note: the requested version has been set in WGLWidget's OpenGLWindow constructor
const int majorVersion = context->surface()->format().majorVersion();
const int minorVersion = context->surface()->format().minorVersion();
qDebug().noquote() << QStringLiteral(
"OpenGL driver version string \"%1\", vendor \"%2\", "
"renderer \"%3\"")
.arg(versionString, vendorString, rendererString);

GLint majorVersion, minorVersion = GL_INVALID_ENUM;
glFunctions->glGetIntegerv(GL_MAJOR_VERSION, &majorVersion);
glFunctions->glGetIntegerv(GL_MINOR_VERSION, &minorVersion);
if (majorVersion == GL_INVALID_ENUM || minorVersion == GL_INVALID_ENUM) {
// GL_MAJOR/MINOR_VERSION are not supported below OpenGL 3.0, so
// parse GL_VERSION string as a fallback.
// https://www.khronos.org/opengl/wiki/OpenGL_Context#OpenGL_version_number
auto match = openGLVersionRegex.match(versionString);
DEBUG_ASSERT(match.hasMatch());
majorVersion = match.captured(1).toInt();
minorVersion = match.captured(2).toInt();
}

qDebug() << "QOpenGLContext surface format version:" << majorVersion << minorVersion;
qDebug().noquote()
<< QStringLiteral("Supported OpenGL version: %1.%2")
.arg(QString::number(majorVersion), QString::number(minorVersion));

m_openGLShaderAvailable = QOpenGLShaderProgram::hasOpenGLShaderPrograms(context);

Expand Down
31 changes: 23 additions & 8 deletions src/widget/wmainmenubar.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -578,8 +578,9 @@ void WMainMenuBar::initialize() {
auto* pHelpSupport = new QAction(supportTitle, this);
pHelpSupport->setStatusTip(supportText);
pHelpSupport->setWhatsThis(buildWhatsThis(supportTitle, supportText));
connect(pHelpSupport, &QAction::triggered,
this, [this] { slotVisitUrl(MIXXX_SUPPORT_URL); });
connect(pHelpSupport, &QAction::triggered, this, [this] {
slotVisitUrl(QUrl(MIXXX_SUPPORT_URL));
});
pHelpMenu->addAction(pHelpSupport);

// User Manual
Expand All @@ -594,7 +595,7 @@ void WMainMenuBar::initialize() {
pHelpManual->setStatusTip(manualText);
pHelpManual->setWhatsThis(buildWhatsThis(manualTitle, manualText));
connect(pHelpManual, &QAction::triggered, this, [this, manualUrl] {
slotVisitUrl(manualUrl.toString());
slotVisitUrl(manualUrl);
});
pHelpMenu->addAction(pHelpManual);

Expand All @@ -614,18 +615,32 @@ void WMainMenuBar::initialize() {
&QAction::triggered,
this,
[this, keyboardShortcutsUrl] {
slotVisitUrl(keyboardShortcutsUrl.toString());
slotVisitUrl(keyboardShortcutsUrl);
});
pHelpMenu->addAction(pHelpKbdShortcuts);

// User Settings Directory
const QString& settingsDirPath = m_pConfig->getSettingsPath();
QString settingsDirTitle = tr("&Settings directory");
QString settingsDirText = tr("Open the Mixxx user settings directory.");
auto* pHelpSettingsDir = new QAction(settingsDirTitle, this);
pHelpSettingsDir->setMenuRole(QAction::NoRole);
pHelpSettingsDir->setStatusTip(settingsDirText);
pHelpSettingsDir->setWhatsThis(buildWhatsThis(settingsDirTitle, settingsDirText));
connect(pHelpSettingsDir, &QAction::triggered, this, [this, settingsDirPath] {
slotVisitUrl(QUrl::fromLocalFile(settingsDirPath));
});
pHelpMenu->addAction(pHelpSettingsDir);

// Translate This Application
QString translateTitle = tr("&Translate This Application") + externalLinkSuffix;
QString translateText = tr("Help translate this application into your language.");
auto* pHelpTranslation = new QAction(translateTitle, this);
pHelpTranslation->setStatusTip(translateText);
pHelpTranslation->setWhatsThis(buildWhatsThis(translateTitle, translateText));
connect(pHelpTranslation, &QAction::triggered,
this, [this] { slotVisitUrl(MIXXX_TRANSLATION_URL); });
connect(pHelpTranslation, &QAction::triggered, this, [this] {
slotVisitUrl(QUrl(MIXXX_TRANSLATION_URL));
});
pHelpMenu->addAction(pHelpTranslation);

pHelpMenu->addSeparator();
Expand Down Expand Up @@ -711,8 +726,8 @@ void WMainMenuBar::slotDeveloperDebugger(bool toggle) {
ConfigValue(toggle ? 1 : 0));
}

void WMainMenuBar::slotVisitUrl(const QString& url) {
QDesktopServices::openUrl(QUrl(url));
void WMainMenuBar::slotVisitUrl(const QUrl& url) {
QDesktopServices::openUrl(url);
}

void WMainMenuBar::createVisibilityControl(QAction* pAction,
Expand Down
2 changes: 1 addition & 1 deletion src/widget/wmainmenubar.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ class WMainMenuBar : public QMenuBar {
void slotDeveloperStatsExperiment(bool enable);
void slotDeveloperStatsBase(bool enable);
void slotDeveloperDebugger(bool toggle);
void slotVisitUrl(const QString& url);
void slotVisitUrl(const QUrl& url);

private:
void initialize();
Expand Down

0 comments on commit 5f22560

Please sign in to comment.