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>
This commit is contained in:
DanielKauss
2024-09-17 08:05:01 +02:00
committed by GitHub
parent 588aab3389
commit 7d35d4225e
20 changed files with 311 additions and 105 deletions

View File

@@ -29,6 +29,7 @@
#include "ModelView.h"
#include "SerializingObject.h"
#include "PluginView.h"
class QLabel;
class QLineEdit;
@@ -67,6 +68,9 @@ public:
InstrumentTrackWindow( InstrumentTrackView * _tv );
~InstrumentTrackWindow() override;
void resizeEvent(QResizeEvent* event) override;
// parent for all internal tab-widgets
TabWidget * tabWidgetParent()
{
@@ -152,6 +156,7 @@ private:
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;

View File

@@ -27,23 +27,26 @@
#include <QWidget>
#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

View File

@@ -152,6 +152,7 @@ void SlicerT::playNote(NotePlayHandle* handle, SampleFrame* workingBuffer)
void SlicerT::deleteNotePluginData(NotePlayHandle* handle)
{
delete static_cast<PlaybackState*>(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<int>(sliceValue) % sliceLock;
}

View File

@@ -84,6 +84,8 @@ public:
void findSlices();
void findBPM();
QString getSampleName() { return m_originalSample.sampleFile(); }
QString nodeName() const override;
gui::PluginView* instantiateView(QWidget* parent) override;

View File

@@ -25,15 +25,16 @@
#include "SlicerTView.h"
#include <QDropEvent>
#include <QFileInfo>
#include <qpixmap.h>
#include <qpushbutton.h>
#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;
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"));
// --- 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

View File

@@ -26,9 +26,9 @@
#define LMMS_GUI_SLICERT_VIEW_H
#include <QPushButton>
#include <qpixmap.h>
#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:
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 @@ private:
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 @@ private:
SlicerTWaveform* m_wf;
Knob* createStyledKnob();
QPixmap m_fullLogo;
QPixmap m_background;
int m_y1;
int m_y2;
};
} // namespace gui
} // namespace lmms

View File

@@ -25,6 +25,7 @@
#include "SlicerTWaveform.h"
#include <QBitmap>
#include <qpainterpath.h>
#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_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
static QColor s_playColor = QColor(255, 255, 255, 200);
static QColor s_playHighlightColor = QColor(255, 255, 255, 70);
// 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
static QColor s_sliceColor = QColor(218, 193, 255);
static QColor s_sliceShadowColor = QColor(136, 120, 158);
static QColor s_sliceHighlightColor = QColor(255, 255, 255);
// 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
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);
// 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, 0, m_editorWaveform);
brush.drawPixmap(0, s_arrowHeight, 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<float>(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

View File

@@ -32,9 +32,6 @@
#include <QMouseEvent>
#include <QPainter>
#include "Instrument.h"
#include "SampleBuffer.h"
namespace lmms {
class SlicerT;
@@ -54,8 +51,9 @@ public:
// 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 @@ protected:
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;

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 707 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
plugins/SlicerT/toolbox.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@@ -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();
}

View File

@@ -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<DummyEffect *>( effect() );

View File

@@ -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();

View File

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

View File

@@ -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();
}

View File

@@ -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
} // namespace lmms::gui