From 9218ea976147bef1bd9c2905f7e7476a2946c7fb Mon Sep 17 00:00:00 2001 From: Be Date: Tue, 28 Sep 2021 17:04:28 -0500 Subject: add QML button to show DlgPreferences --- CMakeLists.txt | 4 + res/qml/main.qml | 11 +++ src/preferences/dialog/dlgpreferences.cpp | 25 +++--- src/preferences/dialog/dlgprefinterface.cpp | 120 ++++++++++++++++------------ src/qml/qmlapplication.cpp | 35 +++++++- src/qml/qmlapplication.h | 6 +- src/qml/qmldlgpreferencesproxy.cpp | 17 ++++ src/qml/qmldlgpreferencesproxy.h | 23 ++++++ 8 files changed, 177 insertions(+), 64 deletions(-) create mode 100644 src/qml/qmldlgpreferencesproxy.cpp create mode 100644 src/qml/qmldlgpreferencesproxy.h diff --git a/CMakeLists.txt b/CMakeLists.txt index f194a63262..346b953765 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -809,6 +809,7 @@ add_library(mixxx-lib STATIC EXCLUDE_FROM_ALL src/qml/qmlapplication.cpp src/qml/qmlcontrolproxy.cpp src/qml/qmlconfigproxy.cpp + src/qml/qmldlgpreferencesproxy.cpp src/qml/qmleffectmanifestparametersmodel.cpp src/qml/qmleffectsmanagerproxy.cpp src/qml/qmleffectslotproxy.cpp @@ -1235,6 +1236,9 @@ endif() # The mixxx executable add_executable(mixxx WIN32 src/main.cpp) +# ugly hack to get #include "preferences/dialog/ui_dlgpreferencesdlg.h" to work in +# src/qmldlgpreferencesproxy.h, which is #included from src/qmlapplication.h. +target_include_directories(mixxx PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/mixxx-lib_autogen/include") set_target_properties(mixxx-lib PROPERTIES CXX_CLANG_TIDY "${CLANG_TIDY}") target_link_libraries(mixxx PRIVATE mixxx-lib mixxx-gitinfostore) diff --git a/res/qml/main.qml b/res/qml/main.qml index 10d5743a47..17f86be408 100644 --- a/res/qml/main.qml +++ b/res/qml/main.qml @@ -1,4 +1,5 @@ import "." as Skin +import Mixxx 0.1 as Mixxx import QtQuick 2.12 import QtQuick.Controls 2.12 import QtQuick.Layouts 1.11 @@ -64,6 +65,16 @@ ApplicationWindow { checkable: true } + Skin.Button { + id: showPreferencesButton + + text: "Prefs" + activeColor: Theme.white + onClicked: { + Mixxx.PreferencesDialog.show(); + } + } + } } diff --git a/src/preferences/dialog/dlgpreferences.cpp b/src/preferences/dialog/dlgpreferences.cpp index d1b2fdcd35..da1761dd32 100644 --- a/src/preferences/dialog/dlgpreferences.cpp +++ b/src/preferences/dialog/dlgpreferences.cpp @@ -152,17 +152,20 @@ DlgPreferences::DlgPreferences( tr("Interface"), "ic_preferences_interface.svg"); - DlgPrefWaveform* pWaveformPage = new DlgPrefWaveform(this, m_pConfig, pLibrary); - addPageWidget(PreferencesPage( - pWaveformPage, - new QTreeWidgetItem(contentsTreeWidget, QTreeWidgetItem::Type)), - tr("Waveforms"), - "ic_preferences_waveforms.svg"); - connect(pWaveformPage, - &DlgPrefWaveform::reloadUserInterface, - this, - &DlgPreferences::reloadUserInterface, - Qt::DirectConnection); + // ugly proxy for determining whether this is being instantiated for QML or legacy QWidgets GUI + if (pSkinLoader) { + DlgPrefWaveform* pWaveformPage = new DlgPrefWaveform(this, m_pConfig, pLibrary); + addPageWidget(PreferencesPage( + pWaveformPage, + new QTreeWidgetItem(contentsTreeWidget, QTreeWidgetItem::Type)), + tr("Waveforms"), + "ic_preferences_waveforms.svg"); + connect(pWaveformPage, + &DlgPrefWaveform::reloadUserInterface, + this, + &DlgPreferences::reloadUserInterface, + Qt::DirectConnection); + } addPageWidget(PreferencesPage( new DlgPrefColors(this, m_pConfig, pLibrary), diff --git a/src/preferences/dialog/dlgprefinterface.cpp b/src/preferences/dialog/dlgprefinterface.cpp index 9562073339..305ad71484 100644 --- a/src/preferences/dialog/dlgprefinterface.cpp +++ b/src/preferences/dialog/dlgprefinterface.cpp @@ -46,7 +46,7 @@ DlgPrefInterface::DlgPrefInterface( m_pConfig(pConfig), m_pScreensaverManager(pScreensaverManager), m_pSkinLoader(pSkinLoader), - m_pSkin(pSkinLoader->getConfiguredSkin()), + m_pSkin(pSkinLoader ? pSkinLoader->getConfiguredSkin() : nullptr), m_dScaleFactor(1.0), m_minScaleFactor(1.0), m_dDevicePixelRatio(1.0), @@ -67,11 +67,6 @@ DlgPrefInterface::DlgPrefInterface( double unscaledDevicePixelRatio = m_dDevicePixelRatio / initialScaleFactor; m_minScaleFactor = 1 / unscaledDevicePixelRatio; - VERIFY_OR_DEBUG_ASSERT(m_pSkin != nullptr) { - qWarning() << "Skipping creation of DlgPrefInterface because there is no skin available."; - return; - } - // Locale setting // Iterate through the available locales and add them to the combobox // Borrowed following snippet from http://qt-project.org/wiki/How_to_create_a_multi_language_application @@ -126,50 +121,59 @@ DlgPrefInterface::DlgPrefInterface( // ...and then insert entry for default system locale at the top ComboBoxLocale->insertItem(0, QStringLiteral("System"), ""); - // Skin configurations - QString sizeWarningString = - " " + - tr("The minimum size of the selected skin is bigger than your " - "screen resolution."); - warningLabel->setText(sizeWarningString); - - ComboBoxSkinconf->clear(); - // align left edge of preview image and skin description with comboboxes - skinPreviewLabel->setStyleSheet("QLabel { margin-left: 4px; }"); - skinPreviewLabel->setText(""); - skinDescriptionText->setStyleSheet("QLabel { margin-left: 2px; }"); - skinDescriptionText->setText(""); - skinDescriptionText->hide(); - - const QList skins = m_pSkinLoader->getSkins(); - int index = 0; - for (const SkinPointer& pSkin : skins) { - ComboBoxSkinconf->insertItem(index, pSkin->name()); - m_skins.insert(pSkin->name(), pSkin); - index++; - } + if (pSkinLoader) { + // Skin configurations + QString sizeWarningString = + " " + + tr("The minimum size of the selected skin is bigger than your " + "screen resolution."); + warningLabel->setText(sizeWarningString); + + ComboBoxSkinconf->clear(); + // align left edge of preview image and skin description with comboboxes + skinPreviewLabel->setStyleSheet("QLabel { margin-left: 4px; }"); + skinPreviewLabel->setText(""); + skinDescriptionText->setStyleSheet("QLabel { margin-left: 2px; }"); + skinDescriptionText->setText(""); + skinDescriptionText->hide(); - ComboBoxSkinconf->setCurrentIndex(index); - // schemes must be updated here to populate the drop-down box and set m_colorScheme - slotUpdateSchemes(); - slotSetSkinPreview(); - const auto* const pScreen = getScreen(); - if (m_pSkin->fitsScreenSize(*pScreen)) { - warningLabel->hide(); + const QList skins = m_pSkinLoader->getSkins(); + int index = 0; + for (const SkinPointer& pSkin : skins) { + ComboBoxSkinconf->insertItem(index, pSkin->name()); + m_skins.insert(pSkin->name(), pSkin); + index++; + } + + ComboBoxSkinconf->setCurrentIndex(index); + // schemes must be updated here to populate the drop-down box and set m_colorScheme + slotUpdateSchemes(); + slotSetSkinPreview(); + const auto* const pScreen = getScreen(); + if (m_pSkin->fitsScreenSize(*pScreen)) { + warningLabel->hide(); + } else { + warningLabel->show(); + } + slotSetSkinDescription(); + + connect(ComboBoxSkinconf, + QOverload::of(&QComboBox::currentIndexChanged), + this, + &DlgPrefInterface::slotSetSkin); + connect(ComboBoxSchemeconf, + QOverload::of(&QComboBox::currentIndexChanged), + this, + &DlgPrefInterface::slotSetScheme); } else { - warningLabel->show(); + lableSkin_2->hide(); + labelColorScheme->hide(); + ComboBoxSkinconf->hide(); + ComboBoxSchemeconf->hide(); + skinDescriptionText->hide(); + skinPreviewLabel->hide(); } - slotSetSkinDescription(); - - connect(ComboBoxSkinconf, - QOverload::of(&QComboBox::currentIndexChanged), - this, - &DlgPrefInterface::slotSetSkin); - connect(ComboBoxSchemeconf, - QOverload::of(&QComboBox::currentIndexChanged), - this, - &DlgPrefInterface::slotSetScheme); // Start in fullscreen mode checkBoxStartFullScreen->setChecked( @@ -215,6 +219,10 @@ QScreen* DlgPrefInterface::getScreen() const { } void DlgPrefInterface::slotUpdateSchemes() { + if (!m_pSkinLoader) { + return; + } + // Re-populates the scheme combobox and attempts to pick the color scheme from config file. // Since this involves opening a file we won't do this as part of regular slotUpdate const QList schlist = m_pSkin->colorschemes(); @@ -339,6 +347,10 @@ void DlgPrefInterface::slotSetScheme(int) { } void DlgPrefInterface::slotSetSkinDescription() { + if (!m_pSkinLoader) { + return; + } + const QString description = m_pSkin->description(); if (!description.isEmpty()) { skinDescriptionText->show(); @@ -349,6 +361,10 @@ void DlgPrefInterface::slotSetSkinDescription() { } void DlgPrefInterface::slotSetSkinPreview() { + if (!m_pSkinLoader) { + return; + } + QPixmap preview = m_pSkin->preview(m_colorScheme); preview.setDevicePixelRatio(m_dDevicePixelRatio); skinPreviewLabel->setPixmap(preview.scaled( @@ -358,6 +374,10 @@ void DlgPrefInterface::slotSetSkinPreview() { } void DlgPrefInterface::slotSetSkin(int) { + if (!m_pSkinLoader) { + return; + } + QString newSkinName = ComboBoxSkinconf->currentText(); if (newSkinName == m_pSkin->name()) { return; @@ -381,8 +401,10 @@ void DlgPrefInterface::slotSetSkin(int) { } void DlgPrefInterface::slotApply() { - m_pConfig->set(ConfigKey(kConfigGroup, kResizableSkinKey), m_pSkin->name()); - m_pConfig->set(ConfigKey(kConfigGroup, kSchemeKey), m_colorScheme); + if (m_pSkinLoader) { + m_pConfig->set(ConfigKey(kConfigGroup, kResizableSkinKey), m_pSkin->name()); + m_pConfig->set(ConfigKey(kConfigGroup, kSchemeKey), m_colorScheme); + } QString locale = ComboBoxLocale->itemData( ComboBoxLocale->currentIndex()).toString(); diff --git a/src/qml/qmlapplication.cpp b/src/qml/qmlapplication.cpp index dc3d03e488..9cdf2f34ab 100644 --- a/src/qml/qmlapplication.cpp +++ b/src/qml/qmlapplication.cpp @@ -4,6 +4,7 @@ #include "qml/asyncimageprovider.h" #include "qml/qmlconfigproxy.h" #include "qml/qmlcontrolproxy.h" +#include "qml/qmldlgpreferencesproxy.h" #include "qml/qmleffectmanifestparametersmodel.h" #include "qml/qmleffectslotproxy.h" #include "qml/qmleffectsmanagerproxy.h" @@ -46,8 +47,23 @@ QmlApplication::QmlApplication( exit(result); } - qmlRegisterType("Mixxx", 0, 1, "ControlProxy"); - qmlRegisterType("Mixxx", 0, 1, "WaveformOverview"); + // FIXME: DlgPreferences has some initialization logic that must be executed + // before the GUI is shown, at least for the effects system. + m_pDlgPreferences = std::make_shared( + m_pCoreServices->getScreensaverManager(), + nullptr, + m_pCoreServices->getSoundManager(), + m_pCoreServices->getPlayerManager(), + m_pCoreServices->getControllerManager(), + m_pCoreServices->getVinylControlManager(), + m_pCoreServices->getLV2Backend(), + m_pCoreServices->getEffectsManager(), + m_pCoreServices->getSettingsManager(), + m_pCoreServices->getLibrary()); + // Without this, QApplication will quit when the last QWidget QWindow is + // closed because it does not take into account the window created by + // the QQmlApplicationEngine. + m_pDlgPreferences->setAttribute(Qt::WA_QuitOnClose, false); // Any uncreateable non-singleton types registered here require arguments // that we don't want to expose to QML directly. Instead, they can be @@ -66,6 +82,21 @@ QmlApplication::QmlApplication( // convert them to shared_ptrs when the QQmlApplicationEngine instantiates // the QML proxy objects. + qmlRegisterSingletonType("Mixxx", + 0, + 1, + "PreferencesDialog", + lambda_to_singleton_type_factory_ptr( + [pDlgPreferences = std::weak_ptr( + m_pDlgPreferences)](QQmlEngine* pEngine, + QJSEngine* pScriptEngine) -> QObject* { + Q_UNUSED(pScriptEngine); + return new QmlDlgPreferencesProxy(pDlgPreferences.lock(), pEngine); + })); + + qmlRegisterType("Mixxx", 0, 1, "ControlProxy"); + qmlRegisterType("Mixxx", 0, 1, "WaveformOverview"); + qmlRegisterSingletonType("Mixxx", 0, 1, diff --git a/src/qml/qmlapplication.h b/src/qml/qmlapplication.h index 866645100d..d3f3d1b113 100644 --- a/src/qml/qmlapplication.h +++ b/src/qml/qmlapplication.h @@ -1,11 +1,12 @@ #pragma once -#include - #include #include #include +#include "coreservices.h" +#include "preferences/dialog/dlgpreferences.h" + namespace mixxx { namespace qml { @@ -27,6 +28,7 @@ class QmlApplication : public QObject { std::unique_ptr m_pAppEngine; QFileSystemWatcher m_fileWatcher; + std::shared_ptr m_pDlgPreferences; }; } // namespace qml diff --git a/src/qml/qmldlgpreferencesproxy.cpp b/src/qml/qmldlgpreferencesproxy.cpp new file mode 100644 index 0000000000..113789a58b --- /dev/null +++ b/src/qml/qmldlgpreferencesproxy.cpp @@ -0,0 +1,17 @@ +#include "qmldlgpreferencesproxy.h" + +namespace mixxx { +namespace qml { + +QmlDlgPreferencesProxy::QmlDlgPreferencesProxy( + std::shared_ptr pDlgPreferences, QObject* parent) + : QObject(parent), + m_pDlgPreferences(pDlgPreferences) { +} + +void QmlDlgPreferencesProxy::show() { + m_pDlgPreferences->show(); +} + +} // namespace qml +} // namespace mixxx diff --git a/src/qml/qmldlgpreferencesproxy.h b/src/qml/qmldlgpreferencesproxy.h new file mode 100644 index 0000000000..c9b032e7fc --- /dev/null +++ b/src/qml/qmldlgpreferencesproxy.h @@ -0,0 +1,23 @@ +#pragma once +#include + +#include "preferences/dialog/dlgpreferences.h" + +namespace mixxx { +namespace qml { + +class QmlDlgPreferencesProxy : public QObject { + Q_OBJECT + public: + explicit QmlDlgPreferencesProxy( + std::shared_ptr pDlgPreferences, + QObject* parent = nullptr); + + Q_INVOKABLE void show(); + + private: + std::shared_ptr m_pDlgPreferences; +}; + +} // namespace qml +} // namespace mixxx -- cgit v1.2.3