diff --git a/CMakeLists.txt b/CMakeLists.txt index 2873b5bcdecc..5d3f9e07f7e2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -617,19 +617,19 @@ add_library(mixxx-lib STATIC EXCLUDE_FROM_ALL src/waveform/widgets/rgbwaveformwidget.cpp src/waveform/widgets/softwarewaveformwidget.cpp src/waveform/widgets/waveformwidgetabstract.cpp - src/widget/colormenu.cpp src/widget/controlwidgetconnection.cpp - src/widget/cuemenu.cpp src/widget/hexspinbox.cpp src/widget/paintable.cpp src/widget/wanalysislibrarytableview.cpp src/widget/wbasewidget.cpp src/widget/wbattery.cpp src/widget/wbeatspinbox.cpp + src/widget/wcolorpicker.cpp src/widget/wcombobox.cpp src/widget/wcoverart.cpp src/widget/wcoverartlabel.cpp src/widget/wcoverartmenu.cpp + src/widget/wcuemenupopup.cpp src/widget/wdisplay.cpp src/widget/weffect.cpp src/widget/weffectbuttonparameter.cpp diff --git a/build/depends.py b/build/depends.py index 7b82e4ed00f0..cb9aa2dd110b 100644 --- a/build/depends.py +++ b/build/depends.py @@ -930,9 +930,7 @@ def sources(self, build): "src/sources/soundsourceproviderregistry.cpp", "src/sources/soundsourceproxy.cpp", - "src/widget/colormenu.cpp", "src/widget/controlwidgetconnection.cpp", - "src/widget/cuemenu.cpp", "src/widget/wbasewidget.cpp", "src/widget/wwidget.cpp", "src/widget/wwidgetgroup.cpp", @@ -983,6 +981,8 @@ def sources(self, build): "src/widget/wcoverart.cpp", "src/widget/wcoverartlabel.cpp", "src/widget/wcoverartmenu.cpp", + "src/widget/wcolorpicker.cpp", + "src/widget/wcuemenupopup.cpp", "src/widget/wsingletoncontainer.cpp", "src/widget/wmainmenubar.cpp", diff --git a/res/images/ic_checkmark.svg b/res/images/ic_checkmark.svg new file mode 100644 index 000000000000..e2ebaa5bed3d --- /dev/null +++ b/res/images/ic_checkmark.svg @@ -0,0 +1,3 @@ + + + diff --git a/res/images/ic_delete.svg b/res/images/ic_delete.svg new file mode 100644 index 000000000000..9f2b5ec79aa8 --- /dev/null +++ b/res/images/ic_delete.svg @@ -0,0 +1,80 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + diff --git a/res/mixxx.qrc b/res/mixxx.qrc index c42863446913..a9719f9e5d3c 100644 --- a/res/mixxx.qrc +++ b/res/mixxx.qrc @@ -30,6 +30,8 @@ images/mixxx_icon.svg images/mixxx-icon-logo-symbolic.svg images/skin_preview_placeholder.png + images/ic_checkmark.svg + images/ic_delete.svg images/preferences/ic_preferences_autodj.svg images/preferences/ic_preferences_bpmdetect.svg images/preferences/ic_preferences_broadcast.svg @@ -55,6 +57,7 @@ shaders/filteredsignal.frag shaders/passthrough.vert shaders/rgbsignal.frag + skins/default.qss translations/mixxx_ar.qm translations/mixxx_ast.qm translations/mixxx_bg.qm diff --git a/res/skins/Deere/style.qss b/res/skins/Deere/style.qss index c89a5eca6b4c..d73f7d60fff7 100644 --- a/res/skins/Deere/style.qss +++ b/res/skins/Deere/style.qss @@ -789,7 +789,7 @@ QAbstractScrollArea::corner { background-color: #222; } -WWidget, QLabel { +WWidget, WLibrary QLabel { font-family: "Open Sans"; font-size: 12px; text-transform: uppercase; diff --git a/res/skins/LateNight/style.qss b/res/skins/LateNight/style.qss index b2101872d4e5..9dfbf5251127 100644 --- a/res/skins/LateNight/style.qss +++ b/res/skins/LateNight/style.qss @@ -5,8 +5,8 @@ } #Mixxx, WWidget, -WLabel, QLabel, -WPushButton, QPushButton, +WLabel, WLibrary QLabel, +WPushButton, WLibrary QPushButton, WEffect, WEffectSelector, WBeatSpinBox, QSpinBox { @@ -26,16 +26,11 @@ WBeatSpinBox, QSpinBox, /* Hotcue labels in the overview */ WOverview, -/* Edit label and pushbuttons in the hotcue label edit dialog */ -WOverview QLabel, -WOverview QPushButton { +/* 'Edit' label in the hotcue label edit dialog */ +WOverview QLabel { font-family: "Open Sans"; text-transform: none; } -WOverview QLabel, -WOverview QPushButton { - font-weight: normal; -} QToolTip { font-family: Ubuntu; @@ -47,7 +42,7 @@ QToolTip { border-radius: 2px; } -WPushButton, QPushButton { +WPushButton, WLibary QPushButton { font-size: 11px/12px; } @@ -477,7 +472,7 @@ WOverview { color: #0bd9d1; } -QLabel, QRadioButton, +WLibary QLabel, WLibary QRadioButton, WSearchLineEdit, #LibraryBPMSpinBox, #LibraryBPMButton::item, @@ -577,8 +572,6 @@ WTime { font-size: 10px/10px; } - - /********************** Decks **********************/ #DeckRow_1_KeyVinylFx { qproperty-layoutAlignment: 'AlignLeft | AlignTop'; diff --git a/res/skins/Shade/style.qss b/res/skins/Shade/style.qss index 158e25eb970b..42cb266361e5 100644 --- a/res/skins/Shade/style.qss +++ b/res/skins/Shade/style.qss @@ -442,10 +442,10 @@ QSplitter::handle:pressed { image: url(skin:/style/style_handle_checked.png); ba QSplitter::handle:horizontal { width: 6px; } QSplitter::handle:vertical { height: 6px;} -QPushButton { font-size: 10pt; +WLibrary QPushButton { font-size: 10pt; font-family: "Open Sans";} /* Extra declaration for QRadionButton otherwise it shows up with wrong colors in Linux with Gnome */ -QLabel, QRadioButton { +WLibrary QLabel, WLibrary QRadioButton { font-size: 10pt; background: transparent; color: #C1C1C1;} diff --git a/res/skins/Tango/style.qss b/res/skins/Tango/style.qss index dbde02e6c394..baf80b4a2c35 100644 --- a/res/skins/Tango/style.qss +++ b/res/skins/Tango/style.qss @@ -94,7 +94,6 @@ WWidgetGroup { image: url(skin:/graphics/splitterVert_handle_pressed.svg); } - /* ################################################################ ####### Colors ################################################## ###############################################################*/ diff --git a/res/skins/default.qss b/res/skins/default.qss new file mode 100644 index 000000000000..667f25e10030 --- /dev/null +++ b/res/skins/default.qss @@ -0,0 +1,11 @@ +WCueMenuPopup #CueDeleteButton { + qproperty-icon: url(:/images/ic_delete.svg); +} + +WColorPicker QPushButton[checked="false"] { + qproperty-icon: none; +} + +WColorPicker QPushButton[checked="true"] { + qproperty-icon: url(:/images/ic_checkmark.svg); +} diff --git a/src/mixxx.cpp b/src/mixxx.cpp index 83c40792071d..73873c3329f7 100644 --- a/src/mixxx.cpp +++ b/src/mixxx.cpp @@ -468,6 +468,17 @@ void MixxxMainWindow::initialize(QApplication* pApp, const CmdlineArgs& args) { QWidget* oldWidget = m_pWidgetParent; + // Load default styles that can be overridden by skins + QFile file(":/skins/default.qss"); + if (file.open(QIODevice::ReadOnly)) { + QByteArray fileBytes = file.readAll(); + QString style = QString::fromLocal8Bit(fileBytes.constData(), + fileBytes.length()); + setStyleSheet(style); + } else { + qWarning() << "Failed to load default skin styles!"; + } + // Load skin to a QWidget that we set as the central widget. Assignment // intentional in next line. if (!(m_pWidgetParent = m_pSkinLoader->loadConfiguredSkin(this, m_pKeyboard, diff --git a/src/widget/colormenu.cpp b/src/widget/colormenu.cpp deleted file mode 100644 index 543b27108429..000000000000 --- a/src/widget/colormenu.cpp +++ /dev/null @@ -1,39 +0,0 @@ -#include "widget/colormenu.h" -#include "util/color/color.h" - -ColorMenu::ColorMenu(QWidget *parent) - : QMenu(parent) { - // If another title would be more appropriate in some context, setTitle - // can be called again after construction. - setTitle(tr("Set color")); - for (const auto& pColor : Color::kPredefinedColorsSet.allColors) { - if (*pColor == *Color::kPredefinedColorsSet.noColor) { - continue; - } - - QAction* pColorAction = new QAction(pColor->m_sDisplayName, this); - QPixmap pixmap(80, 80); - pixmap.fill(pColor->m_defaultRgba); - pColorAction->setIcon(QIcon(pixmap)); - - m_pColorActions.insert(pColor, pColorAction); - addAction(pColorAction); - connect(pColorAction, &QAction::triggered, this, [pColor, this]() { - emit(colorPicked(pColor)); - }); - } -} - -void ColorMenu::useColorSet(PredefinedColorsRepresentation* pColorRepresentation) { - QMapIterator i(m_pColorActions); - while (i.hasNext()) { - i.next(); - QPixmap pixmap(80, 80); - if (pColorRepresentation == nullptr) { - pixmap.fill(i.key()->m_defaultRgba); - } else { - pixmap.fill(pColorRepresentation->representationFor(i.key())); - } - i.value()->setIcon(QIcon(pixmap)); - } -} diff --git a/src/widget/colormenu.h b/src/widget/colormenu.h deleted file mode 100644 index 4c82943cbb8c..000000000000 --- a/src/widget/colormenu.h +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -#include - -#include "util/color/color.h" - -class ColorMenu : public QMenu { - Q_OBJECT - public: - ColorMenu(QWidget *parent = nullptr); - - void useColorSet(PredefinedColorsRepresentation* pColorRepresentation); - - signals: - void colorPicked(PredefinedColorPointer pColor); - - private: - QMap m_pColorActions; -}; diff --git a/src/widget/cuemenu.cpp b/src/widget/cuemenu.cpp deleted file mode 100644 index b9d62a309114..000000000000 --- a/src/widget/cuemenu.cpp +++ /dev/null @@ -1,58 +0,0 @@ -#include - -#include "widget/cuemenu.h" -#include "util/color/color.h" - -CueMenu::CueMenu(QWidget *parent) - : QMenu(parent) { - m_pEditLabel = new QAction(tr("Edit label"), this); - addAction(m_pEditLabel); - connect(m_pEditLabel, &QAction::triggered, this, &CueMenu::slotEditLabel); - - m_pColorMenu = new ColorMenu(this); - connect(m_pColorMenu, &ColorMenu::colorPicked, this, &CueMenu::slotChangeCueColor); - addMenu(m_pColorMenu); - - m_pRemoveCue = new QAction(tr("Remove"), this); - addAction(m_pRemoveCue); - connect(m_pRemoveCue, &QAction::triggered, this, &CueMenu::slotRemoveCue); -} - -CueMenu::~CueMenu() { - delete m_pEditLabel; - delete m_pColorMenu; - delete m_pRemoveCue; -} - -void CueMenu::slotEditLabel() { - VERIFY_OR_DEBUG_ASSERT(m_pCue != nullptr) { - return; - } - bool okay = false; - QString newLabel = QInputDialog::getText(this, tr("Edit cue label"), - tr("New cue label"), QLineEdit::Normal, - m_pCue->getLabel(), &okay); - if (okay) { - m_pCue->setLabel(newLabel); - } -} - -void CueMenu::slotChangeCueColor(PredefinedColorPointer pColor) { - VERIFY_OR_DEBUG_ASSERT(m_pCue != nullptr) { - return; - } - VERIFY_OR_DEBUG_ASSERT(pColor != nullptr) { - return; - } - m_pCue->setColor(pColor); -} - -void CueMenu::slotRemoveCue() { - VERIFY_OR_DEBUG_ASSERT(m_pCue != nullptr) { - return; - } - VERIFY_OR_DEBUG_ASSERT(m_pTrack != nullptr) { - return; - } - m_pTrack->removeCue(m_pCue); -} diff --git a/src/widget/cuemenu.h b/src/widget/cuemenu.h deleted file mode 100644 index 3802292e44aa..000000000000 --- a/src/widget/cuemenu.h +++ /dev/null @@ -1,41 +0,0 @@ -#pragma once - -#include - -#include "track/track.h" -#include "track/cue.h" -#include "widget/colormenu.h" - -class CueMenu : public QMenu { - Q_OBJECT - public: - CueMenu(QWidget *parent = nullptr); - ~CueMenu() override; - - void setCue(CuePointer pCue) { - m_pCue = pCue; - } - - void setTrack(TrackPointer pTrack) { - m_pTrack = pTrack; - } - - void useColorSet(PredefinedColorsRepresentation* pColorRepresentation) { - if (m_pColorMenu != nullptr) { - m_pColorMenu->useColorSet(pColorRepresentation); - } - } - - private slots: - void slotEditLabel(); - void slotRemoveCue(); - void slotChangeCueColor(PredefinedColorPointer pColor); - - private: - CuePointer m_pCue; - TrackPointer m_pTrack; - - QAction* m_pEditLabel; - ColorMenu* m_pColorMenu; - QAction* m_pRemoveCue; -}; diff --git a/src/widget/wcolorpicker.cpp b/src/widget/wcolorpicker.cpp new file mode 100644 index 000000000000..669cb7cad8f8 --- /dev/null +++ b/src/widget/wcolorpicker.cpp @@ -0,0 +1,108 @@ +#include "widget/wcolorpicker.h" + +#include +#include +#include +#include + +#include "util/color/color.h" +#include "util/parented_ptr.h" + +namespace { + const int kNumColumns = 4; +} + +WColorPicker::WColorPicker(QWidget* parent) + : QWidget(parent) { + QGridLayout* pLayout = new QGridLayout(); + pLayout->setMargin(0); + pLayout->setContentsMargins(0, 0, 0, 0); + + // Unfortunately, not all styles supported by Qt support setting a + // background color for QPushButtons (see + // https://bugreports.qt.io/browse/QTBUG-11089). For example, when using + // the gtk2 style all color buttons would be just grey. It's possible to + // work around this by modifing the button border with a QSS stylesheet, so + // that the QStyle will be overwritten, but as a sane default for skins + // without styles for WColorPicker, we're setting the platform-independent + // "Fusion" style here. This will make the buttons look slightly different + // from the rest of the application (when not styled via QSS), but that's + // better than having buttons without any colors (which would make the + // color picker unusable). + m_pStyle = QStyleFactory::create(QString("fusion")); + + int row = 0; + int column = 0; + for (const auto& pColor : Color::kPredefinedColorsSet.allColors) { + if (*pColor == *Color::kPredefinedColorsSet.noColor) { + continue; + } + + parented_ptr pColorButton = make_parented("", this); + if (m_pStyle) { + pColorButton->setStyle(m_pStyle); + } + + // Set the background color of the button. This can't be overridden in skin stylesheets. + pColorButton->setStyleSheet( + QString("QPushButton { background-color: #%1; }").arg(pColor->m_defaultRgba.rgb(), 6, 16, QChar('0')) + ); + + pColorButton->setToolTip(pColor->m_sDisplayName); + pColorButton->setCheckable(true); + m_pColorButtons.insert(pColor, pColorButton); + + pLayout->addWidget(pColorButton, row, column); + column++; + if (column == kNumColumns) { + column = 0; + row++; + } + + connect(pColorButton, &QPushButton::clicked, this, [pColor, this]() { + emit(colorPicked(pColor)); + }); + } + setLayout(pLayout); +} + +void WColorPicker::setSelectedColor(PredefinedColorPointer pColor) { + if (m_pSelectedColor) { + QMap::const_iterator it = m_pColorButtons.find(m_pSelectedColor); + if (it != m_pColorButtons.constEnd()) { + it.value()->setChecked(false); + // This is needed to re-apply skin styles (e.g. to show/hide a checkmark icon) + it.value()->style()->unpolish(it.value()); + it.value()->style()->polish(it.value()); + } + } + + if (pColor) { + QMap::const_iterator it = m_pColorButtons.find(pColor); + if (it != m_pColorButtons.constEnd()) { + it.value()->setChecked(true); + // This is needed to re-apply skin styles (e.g. to show/hide a checkmark icon) + it.value()->style()->unpolish(it.value()); + it.value()->style()->polish(it.value()); + } + } + + m_pSelectedColor = pColor; +} + +void WColorPicker::useColorSet(PredefinedColorsRepresentation* pColorRepresentation) { + QMapIterator i(m_pColorButtons); + while (i.hasNext()) { + i.next(); + PredefinedColorPointer pColor = i.key(); + QPushButton* pColorButton = i.value(); + QColor color = (pColorRepresentation == nullptr) ? pColor->m_defaultRgba : pColorRepresentation->representationFor(pColor); + + // Set the background color of the button. This can't be overridden in skin stylesheets. + pColorButton->setStyleSheet( + QString("QPushButton { background-color: #%1; }").arg(color.rgb(), 6, 16, QChar('0')) + ); + + pColorButton->setToolTip(pColor->m_sDisplayName); + } +} diff --git a/src/widget/wcolorpicker.h b/src/widget/wcolorpicker.h new file mode 100644 index 000000000000..911cbc43a445 --- /dev/null +++ b/src/widget/wcolorpicker.h @@ -0,0 +1,25 @@ +#pragma once + +#include +#include +#include +#include + +#include "util/color/color.h" + +class WColorPicker : public QWidget { + Q_OBJECT + public: + WColorPicker(QWidget* parent = nullptr); + + void setSelectedColor(PredefinedColorPointer pColor = nullptr); + void useColorSet(PredefinedColorsRepresentation* pColorRepresentation); + + signals: + void colorPicked(PredefinedColorPointer pColor); + + private: + QMap m_pColorButtons; + PredefinedColorPointer m_pSelectedColor; + QStyle* m_pStyle; +}; diff --git a/src/widget/wcuemenupopup.cpp b/src/widget/wcuemenupopup.cpp new file mode 100644 index 000000000000..215c6f4fd674 --- /dev/null +++ b/src/widget/wcuemenupopup.cpp @@ -0,0 +1,131 @@ +#include "widget/wcuemenupopup.h" + +#include +#include +#include + +#include "engine/engine.h" +#include "util/color/color.h" + +WCueMenuPopup::WCueMenuPopup(QWidget* parent) + : QWidget(parent) { + QWidget::hide(); + setWindowFlags(Qt::Popup); + setObjectName("WCueMenuPopup"); + + m_pCueNumber = new QLabel(this); + m_pCueNumber->setToolTip(tr("Cue number")); + m_pCueNumber->setObjectName("CueNumberLabel"); + m_pCueNumber->setAlignment(Qt::AlignLeft); + + m_pCuePosition = new QLabel(this); + m_pCuePosition->setToolTip(tr("Cue position")); + m_pCuePosition->setObjectName("CuePositionLabel"); + m_pCuePosition->setAlignment(Qt::AlignRight); + + m_pEditLabel = new QLineEdit(this); + m_pEditLabel->setToolTip(tr("Edit cue label")); + m_pEditLabel->setObjectName("CueLabelEdit"); + connect(m_pEditLabel, &QLineEdit::textEdited, this, &WCueMenuPopup::slotEditLabel); + connect(m_pEditLabel, &QLineEdit::returnPressed, this, &WCueMenuPopup::hide); + + m_pColorPicker = new WColorPicker(this); + m_pColorPicker->setObjectName("CueColorPicker"); + connect(m_pColorPicker, &WColorPicker::colorPicked, this, &WCueMenuPopup::slotChangeCueColor); + + m_pDeleteCue = new QPushButton("", this); + m_pDeleteCue->setToolTip(tr("Delete this cue")); + m_pDeleteCue->setObjectName("CueDeleteButton"); + connect(m_pDeleteCue, &QPushButton::clicked, this, &WCueMenuPopup::slotDeleteCue); + + QHBoxLayout* pLabelLayout = new QHBoxLayout(); + pLabelLayout->addWidget(m_pCueNumber); + pLabelLayout->addStretch(1); + pLabelLayout->addWidget(m_pCuePosition); + + QVBoxLayout* pLeftLayout = new QVBoxLayout(); + pLeftLayout->addLayout(pLabelLayout); + pLeftLayout->addWidget(m_pEditLabel); + pLeftLayout->addWidget(m_pColorPicker); + + QVBoxLayout* pRightLayout = new QVBoxLayout(); + pRightLayout->addWidget(m_pDeleteCue); + pRightLayout->addStretch(1); + + QHBoxLayout* pMainLayout = new QHBoxLayout(); + pMainLayout->addLayout(pLeftLayout); + pMainLayout->addSpacing(5); + pMainLayout->addLayout(pRightLayout); + setLayout(pMainLayout); +} + +void WCueMenuPopup::setTrackAndCue(TrackPointer pTrack, CuePointer pCue) { + if (pTrack && pCue) { + m_pTrack = pTrack; + m_pCue = pCue; + + int hotcueNumber = m_pCue->getHotCue(); + QString hotcueNumberText = ""; + if (hotcueNumber != Cue::kNoHotCue) { + // Programmers count from 0, but DJs count from 1 + hotcueNumberText = QString(tr("Hotcue #%1")).arg(QString::number(hotcueNumber + 1)); + } + m_pCueNumber->setText(hotcueNumberText); + + QString positionText = ""; + double startPosition = m_pCue->getPosition(); + double endPosition = m_pCue->getEndPosition(); + if (startPosition != Cue::kNoPosition) { + double startPositionSeconds = startPosition / m_pTrack->getSampleRate() / mixxx::kEngineChannelCount; + positionText = mixxx::Duration::formatTime(startPositionSeconds, mixxx::Duration::Precision::CENTISECONDS); + if (endPosition != Cue::kNoPosition) { + double endPositionSeconds = endPosition / m_pTrack->getSampleRate() / mixxx::kEngineChannelCount; + positionText = QString("%1 - %2").arg( + positionText, + mixxx::Duration::formatTime(endPositionSeconds, mixxx::Duration::Precision::CENTISECONDS) + ); + } + } + m_pCuePosition->setText(positionText); + + m_pEditLabel->setText(m_pCue->getLabel()); + m_pColorPicker->setSelectedColor(m_pCue->getColor()); + } else { + m_pTrack.reset(); + m_pCue.reset(); + m_pCueNumber->setText(QString("")); + m_pCuePosition->setText(QString("")); + m_pEditLabel->setText(QString("")); + m_pColorPicker->setSelectedColor(); + } +} + +void WCueMenuPopup::slotEditLabel() { + VERIFY_OR_DEBUG_ASSERT(m_pCue != nullptr) { + return; + } + m_pCue->setLabel(m_pEditLabel->text()); +} + +void WCueMenuPopup::slotChangeCueColor(PredefinedColorPointer pColor) { + VERIFY_OR_DEBUG_ASSERT(m_pCue != nullptr) { + return; + } + VERIFY_OR_DEBUG_ASSERT(pColor != nullptr) { + return; + } + m_pCue->setColor(pColor); + m_pColorPicker->setSelectedColor(pColor); + hide(); +} + +void WCueMenuPopup::slotDeleteCue() { + VERIFY_OR_DEBUG_ASSERT(m_pCue != nullptr) { + return; + } + VERIFY_OR_DEBUG_ASSERT(m_pTrack != nullptr) { + return; + } + m_pTrack->removeCue(m_pCue); + hide(); +} diff --git a/src/widget/wcuemenupopup.h b/src/widget/wcuemenupopup.h new file mode 100644 index 000000000000..99d587bdeefa --- /dev/null +++ b/src/widget/wcuemenupopup.h @@ -0,0 +1,68 @@ +#pragma once + +#include +#include +#include + +#include "track/cue.h" +#include "track/track.h" +#include "widget/wcolorpicker.h" + +class WCueMenuPopup : public QWidget { + Q_OBJECT + public: + WCueMenuPopup(QWidget* parent = nullptr); + + ~WCueMenuPopup() { + delete m_pCueNumber; + delete m_pCuePosition; + delete m_pEditLabel; + delete m_pColorPicker; + delete m_pDeleteCue; + } + + void setTrackAndCue(TrackPointer pTrack, CuePointer pCue); + + void useColorSet(PredefinedColorsRepresentation* pColorRepresentation) { + if (m_pColorPicker != nullptr) { + m_pColorPicker->useColorSet(pColorRepresentation); + } + } + + void popup(const QPoint& p, QAction* atAction = nullptr) { + Q_UNUSED(atAction); + qDebug() << "Showing menu at" << p; + move(p); + show(); + } + + void hide() { + emit(aboutToHide()); + QWidget::hide(); + } + + void show() { + m_pEditLabel->setFocus(); + emit(aboutToShow()); + QWidget::show(); + } + + signals: + void aboutToHide(); + void aboutToShow(); + + private slots: + void slotEditLabel(); + void slotDeleteCue(); + void slotChangeCueColor(PredefinedColorPointer pColor); + + private: + CuePointer m_pCue; + TrackPointer m_pTrack; + + QLabel* m_pCueNumber; + QLabel* m_pCuePosition; + QLineEdit* m_pEditLabel; + WColorPicker* m_pColorPicker; + QPushButton* m_pDeleteCue; +}; diff --git a/src/widget/woverview.cpp b/src/widget/woverview.cpp index aa24b3ecf85b..3af7b3de4ef2 100644 --- a/src/widget/woverview.cpp +++ b/src/widget/woverview.cpp @@ -54,7 +54,7 @@ WOverview::WOverview( m_group(group), m_pConfig(pConfig), m_endOfTrack(false), - m_pCueMenu(std::make_unique(this)), + m_pCueMenuPopup(std::make_unique(this)), m_bShowCueTimes(true), m_iPosSeconds(0), m_iPos(0), @@ -87,7 +87,7 @@ WOverview::WOverview( connect(pPlayerManager, &PlayerManager::trackAnalyzerProgress, this, &WOverview::onTrackAnalyzerProgress); - connect(m_pCueMenu.get(), &QMenu::aboutToHide, this, &WOverview::slotCueMenuAboutToHide); + connect(m_pCueMenuPopup.get(), &WCueMenuPopup::aboutToHide, this, &WOverview::slotCueMenuPopupAboutToHide); } void WOverview::setup(const QDomNode& node, const SkinContext& context) { @@ -136,7 +136,7 @@ void WOverview::setup(const QDomNode& node, const SkinContext& context) { ? defaultMark->fillColor() : m_signalColors.getAxesColor(); m_predefinedColorsRepresentation = context.getCueColorRepresentation(node, defaultColor); - m_pCueMenu->useColorSet(&m_predefinedColorsRepresentation); + m_pCueMenuPopup->useColorSet(&m_predefinedColorsRepresentation); for (const auto& pMark: m_marks) { if (pMark->isValid()) { @@ -400,8 +400,8 @@ void WOverview::mouseMoveEvent(QMouseEvent* e) { // before hotcues in m_marksToRender so if there is a hotcue in the same // location, the hotcue gets rendered on top. When right clicking, the // the hotcue rendered on top must be assigned to m_pHoveredMark to show - // the CueMenu. To accomplish this, m_marksToRender is iterated in reverse - // and the loop breaks as soon as m_pHoveredMark is set. + // the CueMenuPopup. To accomplish this, m_marksToRender is iterated in + // reverse and the loop breaks as soon as m_pHoveredMark is set. for (int i = m_marksToRender.size() - 1; i >= 0; --i) { WaveformMarkPointer pMark = m_marksToRender.at(i); int hoveredPosition; @@ -471,16 +471,15 @@ void WOverview::mousePressEvent(QMouseEvent* e) { } } if (pHoveredCue != nullptr) { - m_pCueMenu->setCue(pHoveredCue); - m_pCueMenu->setTrack(m_pCurrentTrack); - m_pCueMenu->popup(e->globalPos()); + m_pCueMenuPopup->setTrackAndCue(m_pCurrentTrack, pHoveredCue); + m_pCueMenuPopup->popup(e->globalPos()); m_bHotcueMenuShowing = true; } } } } -void WOverview::slotCueMenuAboutToHide() { +void WOverview::slotCueMenuPopupAboutToHide() { m_bHotcueMenuShowing = false; m_pHoveredMark.clear(); update(); diff --git a/src/widget/woverview.h b/src/widget/woverview.h index d5bcc4792ac5..96ab55709e90 100644 --- a/src/widget/woverview.h +++ b/src/widget/woverview.h @@ -20,7 +20,7 @@ #include "analyzer/analyzerprogress.h" #include "track/track.h" -#include "widget/cuemenu.h" +#include "widget/wcuemenupopup.h" #include "widget/trackdroptarget.h" #include "widget/wwidget.h" @@ -101,7 +101,7 @@ class WOverview : public WWidget, public TrackDropTarget { void receiveCuesUpdated(); void slotWaveformSummaryUpdated(); - void slotCueMenuAboutToHide(); + void slotCueMenuPopupAboutToHide(); private: // Append the waveform overview pixmap according to available data @@ -143,7 +143,7 @@ class WOverview : public WWidget, public TrackDropTarget { TrackPointer m_pCurrentTrack; ConstWaveformPointer m_pWaveform; - std::unique_ptr m_pCueMenu; + std::unique_ptr m_pCueMenuPopup; bool m_bShowCueTimes; int m_iPosSeconds;