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 @@
+
+
+
+
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;