diff --git a/plugins/SlicerT/CMakeLists.txt b/plugins/SlicerT/CMakeLists.txt index fa7ce3c11a1..a139c9883fd 100644 --- a/plugins/SlicerT/CMakeLists.txt +++ b/plugins/SlicerT/CMakeLists.txt @@ -6,6 +6,8 @@ link_libraries(${FFTW3F_LIBRARIES}) build_plugin(slicert SlicerT.cpp SlicerT.h + SlicerTKnob.cpp + SlicerTKnob.h SlicerTView.cpp SlicerTView.h SlicerTWaveform.cpp diff --git a/plugins/SlicerT/SlicerTKnob.cpp b/plugins/SlicerT/SlicerTKnob.cpp new file mode 100644 index 00000000000..c8ef57b749a --- /dev/null +++ b/plugins/SlicerT/SlicerTKnob.cpp @@ -0,0 +1,64 @@ +/* + * SlicerTKnob.cpp + * + * Copyright (c) 2023 Daniel Kauss Serna + * + * This file is part of LMMS - https://lmms.io + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program (see COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + +#include "SlicerTKnob.h" + +#include +#include + +namespace lmms::gui { +SlicerTKnob::SlicerTKnob(QWidget* parent) + : Knob(KnobType::Styled, parent) +{ + setFixedSize(50, 20); + setCenterPointX(24.0); + setCenterPointY(15.0); +} + +void SlicerTKnob::paintEvent(QPaintEvent* event) +{ + auto brush = QPainter{this}; + brush.translate(width() / 2.0f, height() / 2.0f); + + // int kor = 15; // knob outer radius + // int kir = 9; // knob inner radius + + // // draw knob backgrounds + // brush.setRenderHint(QPainter::Antialiasing); + + // // draw outer radius 2 times to make smooth + // brush.setPen(QPen(QColor(159, 124, 223, 100), 4)); + // brush.drawArc(QRect(kor, 0, kor * 2, kor * 2), -45 * 16, 270 * 16); + + // brush.setPen(QPen(QColor(159, 124, 223, 255), 2)); + // brush.drawArc(QRect(kor, 0, kor * 2, kor * 2), -45 * 16, 270 * 16); + + // // inner knob circle + // brush.setBrush(QColor(106, 90, 138)); + // brush.setPen(QColor(0, 0, 0, 0)); + // brush.drawEllipse(QPoint(0, 15), kir, kir); + + Knob::paintEvent(event); +} +} // namespace lmms::gui diff --git a/plugins/SlicerT/SlicerTKnob.h b/plugins/SlicerT/SlicerTKnob.h new file mode 100644 index 00000000000..034386fecb4 --- /dev/null +++ b/plugins/SlicerT/SlicerTKnob.h @@ -0,0 +1,40 @@ +/* + * SlicerTKnob.h + * + * Copyright (c) 2024 saker + * + * This file is part of LMMS - https://lmms.io + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public + * License along with this program (see COPYING); if not, write to the + * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, + * Boston, MA 02110-1301 USA. + * + */ + +#ifndef LMMS_SLICERT_KNOB_H +#define LMMS_SLICERT_KNOB_H + +#include +#include "Knob.h" + +namespace lmms::gui { +class SlicerTKnob : public Knob +{ +public: + SlicerTKnob(QWidget* parent); + void paintEvent(QPaintEvent* event) override; +}; +} // namespace lmms::gui + +#endif // LMMS_SLICERT_KNOB_H diff --git a/plugins/SlicerT/SlicerTView.cpp b/plugins/SlicerT/SlicerTView.cpp index 15292fd6de6..f04360e62b2 100644 --- a/plugins/SlicerT/SlicerTView.cpp +++ b/plugins/SlicerT/SlicerTView.cpp @@ -27,14 +27,16 @@ #include #include #include +#include +#include #include "Clipboard.h" #include "DataFile.h" #include "InstrumentTrack.h" #include "InstrumentView.h" -#include "PixmapButton.h" #include "SampleLoader.h" #include "SlicerT.h" +#include "SlicerTKnob.h" #include "StringPairDrag.h" #include "Track.h" #include "embed.h" @@ -46,72 +48,88 @@ namespace gui { SlicerTView::SlicerTView(SlicerT* instrument, QWidget* parent) : InstrumentView(instrument, parent) , m_slicerTParent(instrument) - , m_fullLogo(PLUGIN_NAME::getIconPixmap("full_logo")) - , m_background(PLUGIN_NAME::getIconPixmap("toolbox")) { - // window settings setAcceptDrops(true); setAutoFillBackground(true); - setMaximumSize(QSize(10000, 10000)); - setMinimumSize(QSize(516, 400)); - - m_wf = new SlicerTWaveform(248, 128, instrument, this); - m_wf->move(0, s_topBarHeight); - - m_snapSetting = new ComboBox(this, tr("Slice snap")); - m_snapSetting->setGeometry(185, 200, 55, ComboBox::DEFAULT_HEIGHT); - m_snapSetting->setToolTip(tr("Set slice snapping for detection")); - m_snapSetting->setModel(&m_slicerTParent->m_sliceSnap); - - m_syncToggle = new PixmapButton(this, tr("Sync sample")); - m_syncToggle->setActiveGraphic(PLUGIN_NAME::getIconPixmap("sync_active")); - m_syncToggle->setInactiveGraphic(PLUGIN_NAME::getIconPixmap("sync_inactive")); - m_syncToggle->setCheckable(true); - m_syncToggle->setToolTip(tr("Enable BPM sync")); - m_syncToggle->setModel(&m_slicerTParent->m_enableSync); - - m_bpmBox = new LcdSpinBox(3, "19purple", this); - m_bpmBox->setToolTip(tr("Original sample BPM")); - m_bpmBox->setModel(&m_slicerTParent->m_originalBPM); - - m_noteThresholdKnob = createStyledKnob(); - m_noteThresholdKnob->setToolTip(tr("Threshold used for slicing")); - m_noteThresholdKnob->setModel(&m_slicerTParent->m_noteThreshold); - - m_fadeOutKnob = createStyledKnob(); - m_fadeOutKnob->setToolTip(tr("Fade Out per note in milliseconds")); - m_fadeOutKnob->setModel(&m_slicerTParent->m_fadeOutFrames); - - m_midiExportButton = new QPushButton(this); - m_midiExportButton->setIcon(PLUGIN_NAME::getIconPixmap("copy_midi")); - m_midiExportButton->setToolTip(tr("Copy midi pattern to clipboard")); - connect(m_midiExportButton, &PixmapButton::clicked, this, &SlicerTView::exportMidi); - - m_folderButton = new PixmapButton(this); - m_folderButton->setActiveGraphic(PLUGIN_NAME::getIconPixmap("folder_icon")); - m_folderButton->setInactiveGraphic(PLUGIN_NAME::getIconPixmap("folder_icon")); - m_folderButton->setToolTip(tr("Open sample selector")); - connect(m_folderButton, &PixmapButton::clicked, this, &SlicerTView::openFiles); - - m_resetButton = new QPushButton(this); - m_resetButton->setIcon(PLUGIN_NAME::getIconPixmap("reset_slices")); - m_resetButton->setToolTip(tr("Reset slices")); - connect(m_resetButton, &PixmapButton::clicked, m_slicerTParent, &SlicerT::updateSlices); - - update(); -} - -Knob* SlicerTView::createStyledKnob() -{ - Knob* newKnob = new Knob(KnobType::Styled, this); - newKnob->setFixedSize(50, 40); - newKnob->setCenterPointX(24.0); - newKnob->setCenterPointY(15.0); - return newKnob; + auto waveform = new SlicerTWaveform(248, 128, instrument, this); + + auto logoLabel = new QLabel(this); + logoLabel->setPixmap(PLUGIN_NAME::getIconPixmap("full_logo")); + + auto noteThresholdLabel = new QLabel(tr("Threshold"), this); + auto noteThresholdKnob = new SlicerTKnob(this); + noteThresholdKnob->setToolTip(tr("Threshold used for slicing")); + noteThresholdKnob->setModel(&m_slicerTParent->m_noteThreshold); + + auto fadeOutLabel = new QLabel(tr("Fade Out"), this); + auto fadeOutKnob = new SlicerTKnob(this); + fadeOutKnob->setToolTip(tr("Fade Out per note in milliseconds")); + fadeOutKnob->setModel(&m_slicerTParent->m_fadeOutFrames); + + auto snapSetting = new ComboBox(this, tr("Slice snap")); + snapSetting->setToolTip(tr("Set slice snapping for detection")); + snapSetting->setModel(&m_slicerTParent->m_sliceSnap); + + auto syncToggle = new PixmapButton(this, tr("Sync sample")); + syncToggle->setActiveGraphic(PLUGIN_NAME::getIconPixmap("sync_active")); + syncToggle->setInactiveGraphic(PLUGIN_NAME::getIconPixmap("sync_inactive")); + syncToggle->setCheckable(true); + syncToggle->setToolTip(tr("Enable BPM sync")); + syncToggle->setModel(&m_slicerTParent->m_enableSync); + + auto bpmBox = new LcdSpinBox(3, "19purple", this); + bpmBox->setToolTip(tr("Original sample BPM")); + bpmBox->setModel(&m_slicerTParent->m_originalBPM); + + auto midiExportButton = new QPushButton(this); + midiExportButton->setIcon(PLUGIN_NAME::getIconPixmap("copy_midi")); + midiExportButton->setToolTip(tr("Copy midi pattern to clipboard")); + connect(midiExportButton, &PixmapButton::clicked, this, &SlicerTView::exportMidi); + + // m_folderButton = new PixmapButton(this); + // m_folderButton->setActiveGraphic(PLUGIN_NAME::getIconPixmap("folder_icon")); + // m_folderButton->setInactiveGraphic(PLUGIN_NAME::getIconPixmap("folder_icon")); + // m_folderButton->setToolTip(tr("Open sample selector")); + // connect(m_folderButton, &PixmapButton::clicked, this, &SlicerTView::openFiles); + + auto resetButton = new QPushButton(this); + resetButton->setIcon(PLUGIN_NAME::getIconPixmap("reset_slices")); + resetButton->setToolTip(tr("Reset slices")); + connect(resetButton, &PixmapButton::clicked, m_slicerTParent, &SlicerT::updateSlices); + + auto resetButtonLabel = new QLabel(tr("Reset"), this); + auto midiExportButtonLabel = new QLabel(tr("Midi"), this); + auto bpmBoxLabel = new QLabel(tr("BPM"), this); + auto snapSettingLabel = new QLabel(tr("Snap"), this); + + auto topBar = new QGridLayout{}; + topBar->setHorizontalSpacing(0); + topBar->setVerticalSpacing(0); + topBar->addWidget(logoLabel, 0, 0, Qt::AlignTop); + topBar->addWidget(noteThresholdKnob, 0, 1, Qt::AlignRight); + topBar->addWidget(noteThresholdLabel, 1, 1, Qt::AlignTop | Qt::AlignHCenter); + topBar->addWidget(fadeOutKnob, 0, 2, Qt::AlignRight); + topBar->addWidget(fadeOutLabel, 1, 2, Qt::AlignTop | Qt::AlignHCenter); + + auto sideBar = new QGridLayout{}; + sideBar->addWidget(resetButton, 1, 0); + sideBar->addWidget(resetButtonLabel, 2, 0, Qt::AlignTop | Qt::AlignHCenter); + sideBar->addWidget(midiExportButton, 1, 1); + sideBar->addWidget(midiExportButtonLabel, 2, 1, Qt::AlignTop | Qt::AlignHCenter); + sideBar->addWidget(bpmBox, 1, 2); + sideBar->addWidget(bpmBoxLabel, 2, 2, Qt::AlignTop | Qt::AlignHCenter); + sideBar->addWidget(snapSetting, 1, 3); + sideBar->addWidget(snapSettingLabel, 2, 3, Qt::AlignTop | Qt::AlignHCenter); + sideBar->addWidget(syncToggle, 0, 3); + + auto mainLayout = new QVBoxLayout{this}; + mainLayout->setContentsMargins(0, 0, 0, 0); + mainLayout->addLayout(topBar); + mainLayout->addWidget(waveform); + mainLayout->addLayout(sideBar); } -// copied from piano roll void SlicerTView::exportMidi() { using namespace Clipboard; @@ -141,10 +159,8 @@ void SlicerTView::openFiles() m_slicerTParent->updateFile(audioFile); } -// all the drag stuff is copied from AudioFileProcessor void SlicerTView::dragEnterEvent(QDragEnterEvent* dee) { - // For mimeType() and MimeType enum class using namespace Clipboard; if (dee->mimeData()->hasFormat(mimeType(MimeType::StringPair))) @@ -166,7 +182,6 @@ void SlicerTView::dropEvent(QDropEvent* de) QString value = StringPairDrag::decodeValue(de); if (type == "samplefile") { - // set m_wf wave file m_slicerTParent->updateFile(value); return; } @@ -181,105 +196,5 @@ void SlicerTView::dropEvent(QDropEvent* de) de->ignore(); } -void SlicerTView::paintEvent(QPaintEvent* pe) -{ - QPainter brush(this); - brush.setFont(QFont(brush.font().family(), 7, -1, false)); - - int boxTopY = height() - s_bottomBoxHeight; - - // --- backgrounds and limiters - brush.drawPixmap(QRect(0, boxTopY, s_leftBoxWidth, s_bottomBoxHeight), m_background); // left - brush.fillRect( - QRect(s_leftBoxWidth, boxTopY, width() - s_leftBoxWidth, s_bottomBoxHeight), QColor(23, 26, 31)); // right - brush.fillRect(QRect(0, 0, width(), s_topBarHeight), QColor(20, 23, 27)); // top - - // top bar dividers - brush.setPen(QColor(56, 58, 60)); - brush.drawLine(0, s_topBarHeight - 1, width(), s_topBarHeight - 1); - brush.drawLine(0, 0, width(), 0); - - // sample name divider - brush.setPen(QColor(56, 58, 60)); - brush.drawLine(0, boxTopY, width(), boxTopY); - - // boxes divider - brush.setPen(QColor(56, 24, 94)); - brush.drawLine(s_leftBoxWidth, boxTopY, s_leftBoxWidth, height()); - - // --- top bar - brush.drawPixmap( - QRect(10, (s_topBarHeight - m_fullLogo.height()) / 2, m_fullLogo.width(), m_fullLogo.height()), m_fullLogo); - - int y1_text = m_y1 + 27; - - // --- left box - brush.setPen(QColor(255, 255, 255)); - brush.drawText(s_x1 - 25, y1_text, s_textBoxWidth, s_textBoxHeight, Qt::AlignCenter, tr("Threshold")); - brush.drawText(s_x2 - 25, y1_text, s_textBoxWidth, s_textBoxHeight, Qt::AlignCenter, tr("Fade Out")); - brush.drawText(s_x3 - 25, y1_text, s_textBoxWidth, s_textBoxHeight, Qt::AlignCenter, tr("Reset")); - brush.drawText(s_x4 - 8, y1_text, s_textBoxWidth, s_textBoxHeight, Qt::AlignCenter, tr("Midi")); - brush.drawText(s_x5 - 16, y1_text, s_textBoxWidth, s_textBoxHeight, Qt::AlignCenter, tr("BPM")); - brush.drawText(s_x6 - 8, y1_text, s_textBoxWidth, s_textBoxHeight, Qt::AlignCenter, tr("Snap")); - - int kor = 15; // knob outer radius - int kir = 9; // knob inner radius - - // draw knob backgrounds - brush.setRenderHint(QPainter::Antialiasing); - - // draw outer radius 2 times to make smooth - brush.setPen(QPen(QColor(159, 124, 223, 100), 4)); - brush.drawArc(QRect(s_x1 - kor, m_y1, kor * 2, kor * 2), -45 * 16, 270 * 16); - brush.drawArc(QRect(s_x2 - kor, m_y1, kor * 2, kor * 2), -45 * 16, 270 * 16); - - brush.setPen(QPen(QColor(159, 124, 223, 255), 2)); - brush.drawArc(QRect(s_x1 - kor, m_y1, kor * 2, kor * 2), -45 * 16, 270 * 16); - brush.drawArc(QRect(s_x2 - kor, m_y1, kor * 2, kor * 2), -45 * 16, 270 * 16); - - // inner knob circle - brush.setBrush(QColor(106, 90, 138)); - brush.setPen(QColor(0, 0, 0, 0)); - brush.drawEllipse(QPoint(s_x1, m_y1 + 15), kir, kir); - brush.drawEllipse(QPoint(s_x2, m_y1 + 15), kir, kir); - - // current sample bar - brush.fillRect(QRect(0, boxTopY - s_sampleBoxHeight, width(), s_sampleBoxHeight), QColor(5, 5, 5)); - - brush.setPen(QColor(56, 58, 60)); - brush.drawLine(width() - 24, boxTopY - s_sampleBoxHeight, width() - 24, boxTopY); - - brush.setPen(QColor(255, 255, 255, 180)); - brush.setFont(QFont(brush.font().family(), 8, -1, false)); - QString sampleName = m_slicerTParent->getSampleName(); - if (sampleName == "") { sampleName = "No sample loaded"; } - - brush.drawText(5, boxTopY - s_sampleBoxHeight, width(), s_sampleBoxHeight, Qt::AlignLeft, sampleName); -} - -void SlicerTView::resizeEvent(QResizeEvent* re) -{ - m_y1 = height() - s_bottomBoxOffset; - - // left box - m_noteThresholdKnob->move(s_x1 - 25, m_y1); - m_fadeOutKnob->move(s_x2 - 25, m_y1); - - m_resetButton->move(s_x3 - 15, m_y1 + 3); - m_midiExportButton->move(s_x4 + 2, m_y1 + 3); - - m_bpmBox->move(s_x5 - 13, m_y1 + 4); - m_snapSetting->move(s_x6 - 8, m_y1 + 3); - - // right box - m_syncToggle->move((width() - 100), m_y1 + 5); - - m_folderButton->move(width() - 20, height() - s_bottomBoxHeight - s_sampleBoxHeight + 1); - - int waveFormHeight = height() - s_bottomBoxHeight - s_topBarHeight - s_sampleBoxHeight; - - m_wf->resize(width(), waveFormHeight); -} - } // namespace gui } // namespace lmms diff --git a/plugins/SlicerT/SlicerTView.h b/plugins/SlicerT/SlicerTView.h index 62819d78789..026f1fd997f 100644 --- a/plugins/SlicerT/SlicerTView.h +++ b/plugins/SlicerT/SlicerTView.h @@ -53,53 +53,11 @@ public slots: public: SlicerTView(SlicerT* instrument, QWidget* parent); - static constexpr int s_textBoxHeight = 20; - static constexpr int s_textBoxWidth = 50; - - static constexpr int s_topBarHeight = 50; - static constexpr int s_bottomBoxHeight = 97; - static constexpr int s_bottomBoxOffset = 65; - static constexpr int s_sampleBoxHeight = 14; - static constexpr int s_folderButtonWidth = 15; - static constexpr int s_leftBoxWidth = 400; - - - static constexpr int s_x1 = 35; - static constexpr int s_x2 = 85; - static constexpr int s_x3 = 160; - static constexpr int s_x4 = 190; - static constexpr int s_x5 = 275; - static constexpr int s_x6 = 325; -protected: void dragEnterEvent(QDragEnterEvent* dee) override; void dropEvent(QDropEvent* de) override; - void paintEvent(QPaintEvent* pe) override; - void resizeEvent(QResizeEvent* event) override; - private: SlicerT* m_slicerTParent; - - Knob* m_noteThresholdKnob; - Knob* m_fadeOutKnob; - LcdSpinBox* m_bpmBox; - ComboBox* m_snapSetting; - PixmapButton* m_syncToggle; - PixmapButton* m_folderButton; - - QPushButton* m_resetButton; - QPushButton* m_midiExportButton; - - SlicerTWaveform* m_wf; - - Knob* createStyledKnob(); - - QPixmap m_fullLogo; - QPixmap m_background; - - - int m_y1; - int m_y2; }; } // namespace gui } // namespace lmms