From 85a3afcb997e76b34dab6cd189c5f51dfe4a18ce Mon Sep 17 00:00:00 2001 From: DanielKauss Date: Tue, 17 Sep 2024 08:05:01 +0200 Subject: [PATCH] SlicerT UI update (#7453) * Update SlicerT UI * Style review Co-authored-by: Rossmaxx <74815851+Rossmaxx@users.noreply.github.com> * Style fixes --------- Co-authored-by: Rossmaxx <74815851+Rossmaxx@users.noreply.github.com> --- include/InstrumentTrackWindow.h | 5 + include/PluginView.h | 19 +-- plugins/SlicerT/SlicerT.cpp | 3 +- plugins/SlicerT/SlicerT.h | 2 + plugins/SlicerT/SlicerTView.cpp | 140 +++++++++++++++---- plugins/SlicerT/SlicerTView.h | 37 +++-- plugins/SlicerT/SlicerTWaveform.cpp | 140 +++++++++++++------ plugins/SlicerT/SlicerTWaveform.h | 8 +- plugins/SlicerT/artwork.png | Bin 13791 -> 0 bytes plugins/SlicerT/folder_icon.png | Bin 0 -> 707 bytes plugins/SlicerT/full_logo.png | Bin 0 -> 2535 bytes plugins/SlicerT/sync_active.png | Bin 0 -> 1611 bytes plugins/SlicerT/sync_inactive.png | Bin 0 -> 1625 bytes plugins/SlicerT/toolbox.png | Bin 0 -> 18089 bytes src/gui/EffectRackView.cpp | 4 +- src/gui/EffectView.cpp | 3 +- src/gui/instrument/EnvelopeAndLfoView.cpp | 2 + src/gui/instrument/EnvelopeGraph.cpp | 4 +- src/gui/instrument/InstrumentTrackWindow.cpp | 51 +++++-- src/gui/instrument/InstrumentView.cpp | 4 +- 20 files changed, 314 insertions(+), 108 deletions(-) delete mode 100644 plugins/SlicerT/artwork.png create mode 100644 plugins/SlicerT/folder_icon.png create mode 100644 plugins/SlicerT/full_logo.png create mode 100644 plugins/SlicerT/sync_active.png create mode 100644 plugins/SlicerT/sync_inactive.png create mode 100644 plugins/SlicerT/toolbox.png diff --git a/include/InstrumentTrackWindow.h b/include/InstrumentTrackWindow.h index 48a352cbd30..f44430d0e39 100644 --- a/include/InstrumentTrackWindow.h +++ b/include/InstrumentTrackWindow.h @@ -29,6 +29,7 @@ #include "ModelView.h" #include "SerializingObject.h" +#include "PluginView.h" class QLabel; class QLineEdit; @@ -67,6 +68,9 @@ class InstrumentTrackWindow : public QWidget, public ModelView, InstrumentTrackWindow( InstrumentTrackView * _tv ); ~InstrumentTrackWindow() override; + void resizeEvent(QResizeEvent* event) override; + + // parent for all internal tab-widgets TabWidget * tabWidgetParent() { @@ -152,6 +156,7 @@ protected slots: InstrumentSoundShapingView * m_ssView; InstrumentFunctionNoteStackingView* m_noteStackingView; InstrumentFunctionArpeggioView* m_arpeggioView; + QWidget* m_instrumentFunctionsView; // container of note stacking and arpeggio InstrumentMidiIOView * m_midiView; EffectRackView * m_effectView; InstrumentTuningView *m_tuningView; diff --git a/include/PluginView.h b/include/PluginView.h index 3c78cb00af2..a85b0b9e185 100644 --- a/include/PluginView.h +++ b/include/PluginView.h @@ -27,23 +27,26 @@ #include -#include "Plugin.h" #include "ModelView.h" +#include "Plugin.h" -namespace lmms::gui -{ +namespace lmms::gui { -class LMMS_EXPORT PluginView : public QWidget, public ModelView +class LMMS_EXPORT PluginView : public QWidget, public ModelView { public: - PluginView( Plugin * _plugin, QWidget * _parent ) : - QWidget( _parent ), - ModelView( _plugin, this ) + PluginView(Plugin* _plugin, QWidget* _parent) + : QWidget(_parent) + , ModelView(_plugin, this) { } -} ; + void setResizable(bool resizable) { m_isResizable = resizable; } + bool isResizable() { return m_isResizable; } +private: + bool m_isResizable = false; +}; } // namespace lmms::gui diff --git a/plugins/SlicerT/SlicerT.cpp b/plugins/SlicerT/SlicerT.cpp index dcfbf6bc551..3b060258401 100644 --- a/plugins/SlicerT/SlicerT.cpp +++ b/plugins/SlicerT/SlicerT.cpp @@ -152,6 +152,7 @@ void SlicerT::playNote(NotePlayHandle* handle, SampleFrame* workingBuffer) void SlicerT::deleteNotePluginData(NotePlayHandle* handle) { delete static_cast(handle->m_pluginData); + emit isPlaying(-1, 0, 0); } // uses the spectral flux to determine the change in magnitude @@ -246,7 +247,7 @@ void SlicerT::findSlices() if (noteSnap == 0) { sliceLock = 1; } for (float& sliceValue : m_slicePoints) { - sliceValue += sliceLock / 2; + sliceValue += sliceLock / 2.f; sliceValue -= static_cast(sliceValue) % sliceLock; } diff --git a/plugins/SlicerT/SlicerT.h b/plugins/SlicerT/SlicerT.h index 06b55687b4e..53b8bfb2a04 100644 --- a/plugins/SlicerT/SlicerT.h +++ b/plugins/SlicerT/SlicerT.h @@ -84,6 +84,8 @@ public slots: void findSlices(); void findBPM(); + QString getSampleName() { return m_originalSample.sampleFile(); } + QString nodeName() const override; gui::PluginView* instantiateView(QWidget* parent) override; diff --git a/plugins/SlicerT/SlicerTView.cpp b/plugins/SlicerT/SlicerTView.cpp index bbdb53ccbc2..4be774f6d2a 100644 --- a/plugins/SlicerT/SlicerTView.cpp +++ b/plugins/SlicerT/SlicerTView.cpp @@ -25,15 +25,16 @@ #include "SlicerTView.h" #include -#include +#include +#include #include "Clipboard.h" #include "DataFile.h" -#include "Engine.h" #include "InstrumentTrack.h" +#include "InstrumentView.h" +#include "PixmapButton.h" #include "SampleLoader.h" #include "SlicerT.h" -#include "Song.h" #include "StringPairDrag.h" #include "Track.h" #include "embed.h" @@ -43,57 +44,63 @@ namespace lmms { namespace gui { SlicerTView::SlicerTView(SlicerT* instrument, QWidget* parent) - : InstrumentViewFixedSize(instrument, 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); - // render background - QPalette pal; - pal.setBrush(backgroundRole(), PLUGIN_NAME::getIconPixmap("artwork")); - setPalette(pal); + setMaximumSize(QSize(10000, 10000)); + setMinimumSize(QSize(516, 400)); + setResizable(true); m_wf = new SlicerTWaveform(248, 128, instrument, this); - m_wf->move(2, 6); + 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 LedCheckBox("Sync", this, tr("SyncToggle"), LedCheckBox::LedColor::Green); - m_syncToggle->move(135, 187); + 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->move(130, 201); m_bpmBox->setToolTip(tr("Original sample BPM")); m_bpmBox->setModel(&m_slicerTParent->m_originalBPM); m_noteThresholdKnob = createStyledKnob(); - m_noteThresholdKnob->move(10, 197); m_noteThresholdKnob->setToolTip(tr("Threshold used for slicing")); m_noteThresholdKnob->setModel(&m_slicerTParent->m_noteThreshold); m_fadeOutKnob = createStyledKnob(); - m_fadeOutKnob->move(64, 197); m_fadeOutKnob->setToolTip(tr("Fade Out per note in milliseconds")); m_fadeOutKnob->setModel(&m_slicerTParent->m_fadeOutFrames); m_midiExportButton = new QPushButton(this); - m_midiExportButton->move(199, 150); 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->move(18, 150); m_resetButton->setIcon(PLUGIN_NAME::getIconPixmap("reset_slices")); - m_resetButton->setToolTip(tr("Reset Slices")); + m_resetButton->setToolTip(tr("Reset slices")); connect(m_resetButton, &PixmapButton::clicked, m_slicerTParent, &SlicerT::updateSlices); + + update(); } Knob* SlicerTView::createStyledKnob() @@ -178,16 +185,101 @@ void SlicerTView::dropEvent(QDropEvent* de) void SlicerTView::paintEvent(QPaintEvent* pe) { QPainter brush(this); - brush.setPen(QColor(255, 255, 255)); brush.setFont(QFont(brush.font().family(), 7, -1, false)); - brush.drawText(8, s_topTextY, s_textBoxWidth, s_textBoxHeight, Qt::AlignCenter, tr("Reset")); - brush.drawText(188, s_topTextY, s_textBoxWidth, s_textBoxHeight, Qt::AlignCenter, tr("Midi")); + 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; - brush.drawText(8, s_bottomTextY, s_textBoxWidth, s_textBoxHeight, Qt::AlignCenter, tr("Threshold")); - brush.drawText(63, s_bottomTextY, s_textBoxWidth, s_textBoxHeight, Qt::AlignCenter, tr("Fade Out")); - brush.drawText(127, s_bottomTextY, s_textBoxWidth, s_textBoxHeight, Qt::AlignCenter, tr("BPM")); - brush.drawText(188, s_bottomTextY, s_textBoxWidth, s_textBoxHeight, Qt::AlignCenter, tr("Snap")); + m_wf->resize(width(), waveFormHeight); } } // namespace gui diff --git a/plugins/SlicerT/SlicerTView.h b/plugins/SlicerT/SlicerTView.h index ea2b979fc42..232c2745425 100644 --- a/plugins/SlicerT/SlicerTView.h +++ b/plugins/SlicerT/SlicerTView.h @@ -26,9 +26,9 @@ #define LMMS_GUI_SLICERT_VIEW_H #include +#include #include "ComboBox.h" -#include "Instrument.h" #include "InstrumentView.h" #include "Knob.h" #include "LcdSpinBox.h" @@ -42,7 +42,7 @@ class SlicerT; namespace gui { -class SlicerTView : public InstrumentViewFixedSize +class SlicerTView : public InstrumentView { Q_OBJECT @@ -55,14 +55,27 @@ public slots: static constexpr int s_textBoxHeight = 20; static constexpr int s_textBoxWidth = 50; - static constexpr int s_topTextY = 170; - static constexpr int s_bottomTextY = 220; + 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: - virtual void dragEnterEvent(QDragEnterEvent* dee); - virtual void dropEvent(QDropEvent* de); + void dragEnterEvent(QDragEnterEvent* dee) override; + void dropEvent(QDropEvent* de) override; - virtual void paintEvent(QPaintEvent* pe); + void paintEvent(QPaintEvent* pe) override; + void resizeEvent(QResizeEvent* event) override; private: SlicerT* m_slicerTParent; @@ -71,7 +84,8 @@ public slots: Knob* m_fadeOutKnob; LcdSpinBox* m_bpmBox; ComboBox* m_snapSetting; - LedCheckBox* m_syncToggle; + PixmapButton* m_syncToggle; + PixmapButton* m_folderButton; QPushButton* m_resetButton; QPushButton* m_midiExportButton; @@ -79,6 +93,13 @@ public slots: SlicerTWaveform* m_wf; Knob* createStyledKnob(); + + QPixmap m_fullLogo; + QPixmap m_background; + + + int m_y1; + int m_y2; }; } // namespace gui } // namespace lmms diff --git a/plugins/SlicerT/SlicerTWaveform.cpp b/plugins/SlicerT/SlicerTWaveform.cpp index 808b81c399b..17fab42e220 100644 --- a/plugins/SlicerT/SlicerTWaveform.cpp +++ b/plugins/SlicerT/SlicerTWaveform.cpp @@ -25,6 +25,7 @@ #include "SlicerTWaveform.h" #include +#include #include "SampleWaveform.h" #include "SlicerT.h" @@ -35,43 +36,52 @@ namespace lmms { namespace gui { +// waveform colors static QColor s_emptyColor = QColor(0, 0, 0, 0); -static QColor s_waveformColor = QColor(123, 49, 212); -static QColor s_waveformBgColor = QColor(255, 255, 255, 0); -static QColor s_waveformMaskColor = QColor(151, 65, 255); // update this if s_waveformColor changes -static QColor s_waveformInnerColor = QColor(183, 124, 255); - -static QColor s_playColor = QColor(255, 255, 255, 200); -static QColor s_playHighlightColor = QColor(255, 255, 255, 70); - -static QColor s_sliceColor = QColor(218, 193, 255); -static QColor s_sliceShadowColor = QColor(136, 120, 158); -static QColor s_sliceHighlightColor = QColor(255, 255, 255); - -static QColor s_seekerColor = QColor(178, 115, 255); -static QColor s_seekerHighlightColor = QColor(178, 115, 255, 100); -static QColor s_seekerShadowColor = QColor(0, 0, 0, 120); +static QColor s_waveformColor = QColor(123, 49, 212); // color of outer waveform +static QColor s_waveformSeekerBgColor = QColor(0, 0, 0, 255); +static QColor s_waveformEditorBgColor = QColor(15, 15, 15, 255); +static QColor s_waveformMaskColor = QColor(151, 65, 255); // update this if s_waveformColor changes +static QColor s_waveformInnerColor = QColor(183, 124, 255); // color of inner waveform + +// now playing colors +static QColor s_playColor = QColor(255, 255, 255, 200); // now playing line +static QColor s_playHighlightColor = QColor(255, 255, 255, 70); // now playing note marker + +// slice markers +static QColor s_sliceColor = QColor(218, 193, 255); // color of slice marker +static QColor s_sliceShadowColor = QColor(136, 120, 158); // color of dark side of slice marker +static QColor s_sliceHighlightColor = QColor(255, 255, 255); // color of highlighted slice marker + +// seeker rect colors +static QColor s_seekerColor = QColor(178, 115, 255); // outline of seeker +static QColor s_seekerHighlightColor = QColor(178, 115, 255, 100); // inside of seeker +static QColor s_seekerShadowColor = QColor(0, 0, 0, 120); // color used for darkening outside seeker + +// decor colors +static QColor s_editorBounding = QColor(53, 22, 90); // color of the editor bounding box +static QColor s_gradientEnd = QColor(29, 16, 47); // end color of the seeker gradient SlicerTWaveform::SlicerTWaveform(int totalWidth, int totalHeight, SlicerT* instrument, QWidget* parent) : QWidget(parent) , m_width(totalWidth) , m_height(totalHeight) + , m_seekerHeight(40) , m_seekerWidth(totalWidth - s_seekerHorMargin * 2) - , m_editorHeight(totalHeight - s_seekerHeight - s_middleMargin) + , m_editorHeight(totalHeight - m_seekerHeight - s_middleMargin - s_seekerVerMargin) , m_editorWidth(totalWidth) , m_sliceArrow(PLUGIN_NAME::getIconPixmap("slice_indicator_arrow")) - , m_seeker(QPixmap(m_seekerWidth, s_seekerHeight)) - , m_seekerWaveform(QPixmap(m_seekerWidth, s_seekerHeight)) - , m_editorWaveform(QPixmap(m_editorWidth, m_editorHeight)) + , m_seeker(QPixmap(m_seekerWidth, m_seekerHeight)) + , m_seekerWaveform(QPixmap(m_seekerWidth, m_seekerHeight)) + , m_editorWaveform(QPixmap(m_editorWidth, m_editorHeight - s_arrowHeight)) , m_sliceEditor(QPixmap(totalWidth, m_editorHeight)) , m_emptySampleIcon(embed::getIconPixmap("sample_track")) , m_slicerTParent(instrument) { - setFixedSize(m_width, m_height); setMouseTracking(true); - m_seekerWaveform.fill(s_waveformBgColor); - m_editorWaveform.fill(s_waveformBgColor); + m_seekerWaveform.fill(s_waveformSeekerBgColor); + m_editorWaveform.fill(s_waveformEditorBgColor); connect(instrument, &SlicerT::isPlaying, this, &SlicerTWaveform::isPlaying); connect(instrument, &SlicerT::dataChanged, this, &SlicerTWaveform::updateUI); @@ -82,15 +92,31 @@ SlicerTWaveform::SlicerTWaveform(int totalWidth, int totalHeight, SlicerT* instr updateUI(); } +void SlicerTWaveform::resizeEvent(QResizeEvent* event) +{ + m_width = width(); + m_height = height(); + m_seekerWidth = m_width - s_seekerHorMargin * 2; + /* m_seekerHeight = m_height * 0.33f; */ + m_editorWidth = m_width; + m_editorHeight = m_height - m_seekerHeight - s_middleMargin - s_seekerVerMargin; + + m_seeker = QPixmap(m_seekerWidth, m_seekerHeight); + m_seekerWaveform = QPixmap(m_seekerWidth, m_seekerHeight); + m_editorWaveform = QPixmap(m_editorWidth, m_editorHeight - s_arrowHeight); + m_sliceEditor = QPixmap(m_width, m_editorHeight); + updateUI(); +} void SlicerTWaveform::drawSeekerWaveform() { - m_seekerWaveform.fill(s_waveformBgColor); + m_seekerWaveform.fill(s_emptyColor); if (m_slicerTParent->m_originalSample.sampleSize() <= 1) { return; } QPainter brush(&m_seekerWaveform); brush.setPen(s_waveformColor); const auto& sample = m_slicerTParent->m_originalSample; - const auto waveform = SampleWaveform::Parameters{sample.data(), sample.sampleSize(), sample.amplification(), sample.reversed()}; + const auto waveform + = SampleWaveform::Parameters{sample.data(), sample.sampleSize(), sample.amplification(), sample.reversed()}; const auto rect = QRect(0, 0, m_seekerWaveform.width(), m_seekerWaveform.height()); SampleWaveform::visualize(waveform, brush, rect); @@ -102,15 +128,16 @@ void SlicerTWaveform::drawSeekerWaveform() void SlicerTWaveform::drawSeeker() { - m_seeker.fill(s_emptyColor); + m_seeker.fill(s_waveformSeekerBgColor); if (m_slicerTParent->m_originalSample.sampleSize() <= 1) { return; } QPainter brush(&m_seeker); + brush.drawPixmap(0, 0, m_seekerWaveform); brush.setPen(s_sliceColor); for (float sliceValue : m_slicerTParent->m_slicePoints) { float xPos = sliceValue * m_seekerWidth; - brush.drawLine(xPos, 0, xPos, s_seekerHeight); + brush.drawLine(xPos, 0, xPos, m_seekerHeight); } float seekerStartPosX = m_seekerStart * m_seekerWidth; @@ -122,16 +149,16 @@ void SlicerTWaveform::drawSeeker() float noteEndPosX = (m_noteEnd - m_noteStart) * m_seekerWidth; brush.setPen(s_playColor); - brush.drawLine(noteCurrentPosX, 0, noteCurrentPosX, s_seekerHeight); - brush.fillRect(noteStartPosX, 0, noteEndPosX, s_seekerHeight, s_playHighlightColor); + brush.drawLine(noteCurrentPosX, 0, noteCurrentPosX, m_seekerHeight); + brush.fillRect(noteStartPosX, 0, noteEndPosX, m_seekerHeight, s_playHighlightColor); - brush.fillRect(seekerStartPosX, 0, seekerMiddleWidth - 1, s_seekerHeight, s_seekerHighlightColor); + brush.fillRect(seekerStartPosX, 0, seekerMiddleWidth - 1, m_seekerHeight, s_seekerHighlightColor); - brush.fillRect(0, 0, seekerStartPosX, s_seekerHeight, s_seekerShadowColor); - brush.fillRect(seekerEndPosX - 1, 0, m_seekerWidth, s_seekerHeight, s_seekerShadowColor); + brush.fillRect(0, 0, seekerStartPosX, m_seekerHeight, s_seekerShadowColor); + brush.fillRect(seekerEndPosX - 1, 0, m_seekerWidth, m_seekerHeight, s_seekerShadowColor); brush.setPen(QPen(s_seekerColor, 1)); - brush.drawRect(seekerStartPosX, 0, seekerMiddleWidth - 1, s_seekerHeight - 1); // -1 needed + brush.drawRoundedRect(seekerStartPosX, 0, seekerMiddleWidth - 1, m_seekerHeight - 1, 2, 2); } void SlicerTWaveform::drawEditorWaveform() @@ -147,7 +174,8 @@ void SlicerTWaveform::drawEditorWaveform() float zoomOffset = (m_editorHeight - m_zoomLevel * m_editorHeight) / 2; const auto& sample = m_slicerTParent->m_originalSample; - const auto waveform = SampleWaveform::Parameters{sample.data() + startFrame, endFrame - startFrame, sample.amplification(), sample.reversed()}; + const auto waveform = SampleWaveform::Parameters{ + sample.data() + startFrame, endFrame - startFrame, sample.amplification(), sample.reversed()}; const auto rect = QRect(0, zoomOffset, m_editorWidth, m_zoomLevel * m_editorHeight); SampleWaveform::visualize(waveform, brush, rect); @@ -159,7 +187,7 @@ void SlicerTWaveform::drawEditorWaveform() void SlicerTWaveform::drawEditor() { - m_sliceEditor.fill(s_waveformBgColor); + m_sliceEditor.fill(s_waveformEditorBgColor); QPainter brush(&m_sliceEditor); // No sample loaded @@ -185,13 +213,16 @@ void SlicerTWaveform::drawEditor() float noteLength = (m_noteEnd - m_noteStart) / (m_seekerEnd - m_seekerStart) * m_editorWidth; brush.setPen(s_playHighlightColor); - brush.drawLine(0, m_editorHeight / 2, m_editorWidth, m_editorHeight / 2); + int middleY = m_editorHeight / 2 + s_arrowHeight; + brush.drawLine(0, middleY, m_editorWidth, middleY); + + brush.drawPixmap(0, s_arrowHeight, m_editorWaveform); - brush.drawPixmap(0, 0, m_editorWaveform); + brush.fillRect(0, 0, m_editorWidth, s_arrowHeight, s_waveformSeekerBgColor); brush.setPen(s_playColor); - brush.drawLine(noteCurrentPos, 0, noteCurrentPos, m_editorHeight); - brush.fillRect(noteStartPos, 0, noteLength, m_editorHeight, s_playHighlightColor); + brush.drawLine(noteCurrentPos, s_arrowHeight, noteCurrentPos, m_editorHeight); + brush.fillRect(noteStartPos, s_arrowHeight, noteLength, m_editorHeight, s_playHighlightColor); brush.setPen(QPen(s_sliceColor, 2)); @@ -215,6 +246,11 @@ void SlicerTWaveform::drawEditor() brush.drawPixmap(xPos - m_sliceArrow.width() / 2.0f, 0, m_sliceArrow); } } + + // decor + brush.setPen(s_editorBounding); + brush.drawLine(0, s_arrowHeight, m_editorWidth, s_arrowHeight); + brush.drawLine(0, m_editorHeight - 1, m_editorWidth, m_editorHeight - 1); } void SlicerTWaveform::isPlaying(float current, float start, float end) @@ -248,7 +284,7 @@ void SlicerTWaveform::updateClosest(QMouseEvent* me) m_closestObject = UIObjects::Nothing; m_closestSlice = -1; - if (me->y() < s_seekerHeight) + if (me->y() < m_seekerHeight) { if (std::abs(normalizedClickSeeker - m_seekerStart) < s_distanceForClick) { @@ -394,7 +430,7 @@ void SlicerTWaveform::mouseMoveEvent(QMouseEvent* me) void SlicerTWaveform::mouseDoubleClickEvent(QMouseEvent* me) { - if (me->button() != Qt::MouseButton::LeftButton) { return; } + if (me->button() != Qt::MouseButton::LeftButton || me->y() < m_seekerHeight) { return; } float normalizedClickEditor = static_cast(me->x()) / m_editorWidth; float startFrame = m_seekerStart; @@ -416,9 +452,27 @@ void SlicerTWaveform::wheelEvent(QWheelEvent* we) void SlicerTWaveform::paintEvent(QPaintEvent* pe) { QPainter p(this); - p.drawPixmap(s_seekerHorMargin, 0, m_seekerWaveform); - p.drawPixmap(s_seekerHorMargin, 0, m_seeker); - p.drawPixmap(0, s_seekerHeight + s_middleMargin, m_sliceEditor); + + // top gradient + QLinearGradient bgGrad(QPointF(0, 0), QPointF(width(), height() - m_editorHeight)); + bgGrad.setColorAt(0, s_waveformEditorBgColor); + bgGrad.setColorAt(1, s_gradientEnd); + + p.setBrush(bgGrad); + p.setPen(s_emptyColor); + p.drawRect(QRect(0, 0, width(), height())); + p.setBrush(QBrush()); + + // seeker + QPainterPath path; + path.addRoundedRect( + QRect(s_seekerHorMargin - 2, s_seekerVerMargin - 2, m_seekerWidth + 4, m_seekerHeight + 4), 4, 4); + p.fillPath(path, s_seekerShadowColor); + p.drawPixmap(s_seekerHorMargin, s_seekerVerMargin, m_seeker); + + // editor + p.setPen(QColor(s_waveformColor)); + p.drawPixmap(0, m_seekerHeight + s_middleMargin + s_seekerVerMargin, m_sliceEditor); } } // namespace gui } // namespace lmms diff --git a/plugins/SlicerT/SlicerTWaveform.h b/plugins/SlicerT/SlicerTWaveform.h index 6478e7f8684..d22e83f5eaa 100644 --- a/plugins/SlicerT/SlicerTWaveform.h +++ b/plugins/SlicerT/SlicerTWaveform.h @@ -32,9 +32,6 @@ #include #include -#include "Instrument.h" -#include "SampleBuffer.h" - namespace lmms { class SlicerT; @@ -54,8 +51,9 @@ public slots: // predefined sizes static constexpr int s_seekerHorMargin = 5; - static constexpr int s_seekerHeight = 38; // used to calcualte all vertical sizes + static constexpr int s_seekerVerMargin = 6; static constexpr int s_middleMargin = 6; + static constexpr int s_arrowHeight = 5; // interaction behavior values static constexpr float s_distanceForClick = 0.02f; @@ -80,11 +78,13 @@ public slots: void wheelEvent(QWheelEvent* we) override; void paintEvent(QPaintEvent* pe) override; + void resizeEvent(QResizeEvent* event) override; private: int m_width; int m_height; + int m_seekerHeight; // used to calcualte all vertical sizes int m_seekerWidth; int m_editorHeight; int m_editorWidth; diff --git a/plugins/SlicerT/artwork.png b/plugins/SlicerT/artwork.png deleted file mode 100644 index e166273c705362e4e07b907a853492b138c566d8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13791 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 literal 0 HcmV?d00001 diff --git a/plugins/SlicerT/sync_active.png b/plugins/SlicerT/sync_active.png new file mode 100644 index 0000000000000000000000000000000000000000..9db13c7944e1bee4eb457cd444edc94c5c81a560 GIT binary patch literal 1611 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 literal 0 HcmV?d00001 diff --git a/src/gui/EffectRackView.cpp b/src/gui/EffectRackView.cpp index eb8c6c43ea4..d815ea31107 100644 --- a/src/gui/EffectRackView.cpp +++ b/src/gui/EffectRackView.cpp @@ -216,14 +216,16 @@ void EffectRackView::update() } else { + (*it)->resize(width() - 35, EffectView::DEFAULT_HEIGHT); ( *it )->move( EffectViewMargin, m_lastY ); + (*it)->update(); m_lastY += ( *it )->height(); ++nView; ++it; } } - w->setFixedSize( EffectView::DEFAULT_WIDTH + 2*EffectViewMargin, m_lastY); + w->resize(width() - 35 + 2 * EffectViewMargin, m_lastY); QWidget::update(); } diff --git a/src/gui/EffectView.cpp b/src/gui/EffectView.cpp index 6f2b984c32a..32472afc6a7 100644 --- a/src/gui/EffectView.cpp +++ b/src/gui/EffectView.cpp @@ -52,8 +52,7 @@ EffectView::EffectView( Effect * _model, QWidget * _parent ) : m_controlView(nullptr), m_dragging(false) { - setFixedSize(EffectView::DEFAULT_WIDTH, EffectView::DEFAULT_HEIGHT); - setFocusPolicy(Qt::StrongFocus); + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); // TODO: Actual effect resizing // Disable effects that are of type "DummyEffect" bool isEnabled = !dynamic_cast( effect() ); diff --git a/src/gui/instrument/EnvelopeAndLfoView.cpp b/src/gui/instrument/EnvelopeAndLfoView.cpp index 1b639e6c326..0f1f47e638f 100644 --- a/src/gui/instrument/EnvelopeAndLfoView.cpp +++ b/src/gui/instrument/EnvelopeAndLfoView.cpp @@ -85,9 +85,11 @@ EnvelopeAndLfoView::EnvelopeAndLfoView(QWidget * parent) : envelopeLayout->addLayout(graphAndAmountLayout); m_envelopeGraph = new EnvelopeGraph(this); + m_envelopeGraph->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); graphAndAmountLayout->addWidget(m_envelopeGraph); m_amountKnob = buildKnob(tr("AMT"), tr("Modulation amount:")); + m_amountKnob->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); graphAndAmountLayout->addWidget(m_amountKnob, 0, Qt::AlignCenter); QHBoxLayout* envKnobsLayout = new QHBoxLayout(); diff --git a/src/gui/instrument/EnvelopeGraph.cpp b/src/gui/instrument/EnvelopeGraph.cpp index 4cf5da74bfa..3102c02a93e 100644 --- a/src/gui/instrument/EnvelopeGraph.cpp +++ b/src/gui/instrument/EnvelopeGraph.cpp @@ -211,8 +211,8 @@ void EnvelopeGraph::paintEvent(QPaintEvent*) const QColor lineColor{ColorHelper::interpolateInRgb(noAmountColor, fullAmountColor, absAmount)}; // Determine the line width so that it scales with the widget - // Use the minimum value of the current width and height to compute it. - const qreal lineWidth = std::min(width(), height()) / 20.; + // Use the diagonal of the box to compute it + const qreal lineWidth = sqrt(width()*width() + height()*height()) / 80.; const QPen linePen{lineColor, lineWidth}; p.setPen(linePen); diff --git a/src/gui/instrument/InstrumentTrackWindow.cpp b/src/gui/instrument/InstrumentTrackWindow.cpp index 1d1d2d73cc2..1fb8596625e 100644 --- a/src/gui/instrument/InstrumentTrackWindow.cpp +++ b/src/gui/instrument/InstrumentTrackWindow.cpp @@ -105,7 +105,7 @@ InstrumentTrackWindow::InstrumentTrackWindow( InstrumentTrackView * _itv ) : connect( m_nameLineEdit, SIGNAL( textChanged( const QString& ) ), this, SLOT( textChanged( const QString& ) ) ); - m_nameLineEdit->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Preferred)); + m_nameLineEdit->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed)); nameAndChangeTrackLayout->addWidget(m_nameLineEdit, 1); @@ -118,7 +118,7 @@ InstrumentTrackWindow::InstrumentTrackWindow( InstrumentTrackView * _itv ) : // m_leftRightNav->setShortcuts(); nameAndChangeTrackLayout->addWidget(m_leftRightNav); - + nameAndChangeTrackWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); generalSettingsLayout->addWidget( nameAndChangeTrackWidget ); auto basicControlsLayout = new QGridLayout; @@ -238,8 +238,8 @@ InstrumentTrackWindow::InstrumentTrackWindow( InstrumentTrackView * _itv ) : m_ssView = new InstrumentSoundShapingView( m_tabWidget ); // FUNC tab - auto instrumentFunctions = new QWidget(m_tabWidget); - auto instrumentFunctionsLayout = new QVBoxLayout(instrumentFunctions); + m_instrumentFunctionsView = new QWidget(m_tabWidget); + auto instrumentFunctionsLayout = new QVBoxLayout(m_instrumentFunctionsView); instrumentFunctionsLayout->setContentsMargins(5, 5, 5, 5); m_noteStackingView = new InstrumentFunctionNoteStackingView( &m_track->m_noteStacking ); m_arpeggioView = new InstrumentFunctionArpeggioView( &m_track->m_arpeggio ); @@ -259,21 +259,21 @@ InstrumentTrackWindow::InstrumentTrackWindow( InstrumentTrackView * _itv ) : m_tabWidget->addTab(m_ssView, tr("Envelope, filter & LFO"), "env_lfo_tab", 1); - m_tabWidget->addTab(instrumentFunctions, tr("Chord stacking & arpeggio"), "func_tab", 2); + m_tabWidget->addTab(m_instrumentFunctionsView, tr("Chord stacking & arpeggio"), "func_tab", 2); m_tabWidget->addTab(m_effectView, tr("Effects"), "fx_tab", 3); m_tabWidget->addTab(m_midiView, tr("MIDI"), "midi_tab", 4); m_tabWidget->addTab(m_tuningView, tr("Tuning and transposition"), "tuning_tab", 5); - adjustTabSize(m_ssView); - adjustTabSize(instrumentFunctions); - // EffectRackView has sizeHint to be QSize(EffectRackView::DEFAULT_WIDTH, INSTRUMENT_HEIGHT - 4 - 1) - adjustTabSize(m_midiView); - adjustTabSize(m_tuningView); // setup piano-widget m_pianoView = new PianoView( this ); m_pianoView->setMinimumHeight( PIANO_HEIGHT ); m_pianoView->setMaximumHeight( PIANO_HEIGHT ); + // setup sizes and policies + generalSettingsWidget->setMaximumHeight(90); + generalSettingsWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed); + m_tabWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); + vlayout->addWidget( generalSettingsWidget ); // Use QWidgetItem explicitly to make the size hint change on instrument changes // QLayout::addWidget() uses QWidgetItemV2 with size hint caching @@ -281,13 +281,20 @@ InstrumentTrackWindow::InstrumentTrackWindow( InstrumentTrackView * _itv ) : vlayout->addWidget( m_pianoView ); setModel( _itv->model() ); + updateInstrumentView(); + QMdiSubWindow* subWin = getGUI()->mainWindow()->addWindowedWidget( this ); Qt::WindowFlags flags = subWin->windowFlags(); - flags |= Qt::MSWindowsFixedSizeDialogHint; + if (!m_instrumentView->isResizable()) { + flags |= Qt::MSWindowsFixedSizeDialogHint; + // any better way than this? + } else { + subWin->setMaximumSize(m_instrumentView->maximumHeight() + 12, m_instrumentView->maximumWidth() + 208); + subWin->setMinimumSize( m_instrumentView->minimumWidth() + 12, m_instrumentView->minimumHeight() + 208); + } flags &= ~Qt::WindowMaximizeButtonHint; subWin->setWindowFlags( flags ); - updateInstrumentView(); // Hide the Size and Maximize options from the system menu // since the dialog size is fixed. @@ -296,10 +303,18 @@ InstrumentTrackWindow::InstrumentTrackWindow( InstrumentTrackView * _itv ) : systemMenu->actions().at( 4 )->setVisible( false ); // Maximize subWin->setWindowIcon( embed::getIconPixmap( "instrument_track" ) ); - subWin->setMinimumSize( subWin->size() ); subWin->hide(); } +void InstrumentTrackWindow::resizeEvent(QResizeEvent * event) { + /* m_instrumentView->resize(QSize(size().width()-1, maxHeight)); */ + adjustTabSize(m_instrumentView); + adjustTabSize(m_instrumentFunctionsView); + adjustTabSize(m_ssView); + adjustTabSize(m_effectView); + adjustTabSize(m_midiView); + adjustTabSize(m_tuningView); +} @@ -668,6 +683,13 @@ void InstrumentTrackWindow::viewInstrumentInDirection(int d) } Q_ASSERT(bringToFront); bringToFront->getInstrumentTrackWindow()->setFocus(); + Qt::WindowFlags flags = windowFlags(); + if (!m_instrumentView->isResizable()) { + flags |= Qt::MSWindowsFixedSizeDialogHint; + } else { + flags &= ~Qt::MSWindowsFixedSizeDialogHint; + } + setWindowFlags( flags ); } void InstrumentTrackWindow::viewNextInstrument() @@ -684,7 +706,8 @@ void InstrumentTrackWindow::adjustTabSize(QWidget *w) // "-1" : // in "TabWidget::addTab", under "Position tab's window", the widget is // moved up by 1 pixel - w->setMinimumSize(INSTRUMENT_WIDTH - 4, INSTRUMENT_HEIGHT - 4 - 1); + w->resize(width() - 4, height() - 180); + w->update(); } diff --git a/src/gui/instrument/InstrumentView.cpp b/src/gui/instrument/InstrumentView.cpp index fe2c04cfbcb..9b681b7964e 100644 --- a/src/gui/instrument/InstrumentView.cpp +++ b/src/gui/instrument/InstrumentView.cpp @@ -35,6 +35,7 @@ namespace lmms::gui InstrumentView::InstrumentView( Instrument * _Instrument, QWidget * _parent ) : PluginView( _Instrument, _parent ) { + setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); setModel( _Instrument ); setAttribute( Qt::WA_DeleteOnClose, true ); } @@ -44,6 +45,7 @@ InstrumentView::InstrumentView( Instrument * _Instrument, QWidget * _parent ) : InstrumentView::~InstrumentView() { + setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); if( instrumentTrackWindow() ) { instrumentTrackWindow()->m_instrumentView = nullptr; @@ -76,4 +78,4 @@ InstrumentTrackWindow * InstrumentView::instrumentTrackWindow() -} // namespace lmms::gui \ No newline at end of file +} // namespace lmms::gui