Skip to content
Open
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 44 additions & 1 deletion include/PatternEditor.h
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,24 @@

#include "Editor.h"
#include "TrackContainerView.h"
#include "AutomatableModel.h"

class QLabel;
class QScrollBar;

namespace lmms
{

class IntModel;
class PatternStore;

namespace gui
{

class AutomatableSlider;
class ComboBox;
class TimeLineWidget;


class PatternEditor : public TrackContainerView
{
Q_OBJECT
Expand All @@ -65,18 +70,43 @@ public slots:
void cloneClip();
void updateMaxSteps();

signals:
void zoomLevelChanged();
void offsetValueChanged();
void zoomControlsVisibilityChanged( bool show );
Comment thread
Itreza2 marked this conversation as resolved.
Outdated

protected:
double getZoom() const
{
// The zoom level is calculated such as exactly one bar is visible when the zoom slider is at its maximum value,
// and the whole pattern is visible when the zoom slider is at its minimum value.
return 1 + m_zoomingModel->value() * ( m_maxClipLength / TimePos::ticksPerBar() - 1 ) / static_cast<double>(m_zoomingModel->maxValue());
Comment thread
Itreza2 marked this conversation as resolved.
Outdated
}

protected slots:
void dropEvent(QDropEvent * de ) override;
void resizeEvent(QResizeEvent* de) override;
void updatePosition();
void updatePixelsPerBar();
void updateScrollBar();

private:
void wheelEvent( QWheelEvent * we ) override;
Comment thread
Itreza2 marked this conversation as resolved.
Outdated

IntModel* m_zoomingModel;
QScrollBar* m_leftRightScroll;

PatternStore* m_ps;
TimeLineWidget* m_timeLine;
int m_trackHeadWidth;
tick_t m_maxClipLength;
void makeSteps( bool clone );

private slots:
void zoomingChanged();
void horizontalScrollChanged();

friend class PatternEditorWindow;
};


Expand All @@ -89,14 +119,27 @@ Q_OBJECT

QSize sizeHint() const override;

double zoomLevel() const
{
return m_editor->getZoom();
}

double horizontalScrollValue() const;

PatternEditor* m_editor;

public slots:
void play() override;
void stop() override;

void showZoomControls( bool show );
Comment thread
Itreza2 marked this conversation as resolved.
Outdated

private:
AutomatableSlider * m_zoomingSlider;
Comment thread
Itreza2 marked this conversation as resolved.
Outdated
ComboBox* m_patternComboBox;

QAction* m_zoomIconAction;
QAction* m_zoomSliderAction;
};


Expand Down
20 changes: 15 additions & 5 deletions src/gui/clips/ClipView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
#include "KeyboardShortcuts.h"
#include "lmms_math.h"
#include "MidiClipView.h"
#include "PatternEditor.h"
#include "PatternClip.h"
#include "PatternStore.h"
#include "Song.h"
Expand Down Expand Up @@ -119,6 +120,8 @@ ClipView::ClipView( Clip * clip,
connect( m_clip, SIGNAL(lengthChanged()),
this, SLOT(updateLength()));
connect(getGUI()->songEditor()->m_editor, &SongEditor::pixelsPerBarChanged, this, &ClipView::updateLength);
connect(getGUI()->patternEditor()->m_editor, &PatternEditor::zoomLevelChanged, this, &ClipView::updateLength);
connect(getGUI()->patternEditor()->m_editor, &PatternEditor::offsetValueChanged, this, &ClipView::updatePosition);
connect( m_clip, SIGNAL(positionChanged()),
this, SLOT(updatePosition()));
connect( m_clip, SIGNAL(destroyedClip()), this, SLOT(close()));
Expand Down Expand Up @@ -314,7 +317,7 @@ void ClipView::updateLength()
{
if( fixedClips() )
{
setFixedWidth( parentWidget()->width() );
setFixedWidth( parentWidget()->width() * getGUI()->patternEditor()->zoomLevel() );
Comment thread
Itreza2 marked this conversation as resolved.
Outdated
}
else
{
Expand All @@ -337,10 +340,17 @@ void ClipView::updateLength()
*/
void ClipView::updatePosition()
{
m_trackView->getTrackContentWidget()->changePosition();
// moving a Clip can result in change of song-length etc.,
// therefore we update the track-container
m_trackView->trackContainerView()->update();
if ( fixedClips() )
Comment thread
Itreza2 marked this conversation as resolved.
Outdated
{
move( -parentWidget()->width() * getGUI()->patternEditor()->horizontalScrollValue(), 0 );
Comment thread
Itreza2 marked this conversation as resolved.
Outdated
}
else
{
m_trackView->getTrackContentWidget()->changePosition();
// moving a Clip can result in change of song-length etc.,
// therefore we update the track-container
m_trackView->trackContainerView()->update();
}
}

void ClipView::selectColor()
Expand Down
3 changes: 2 additions & 1 deletion src/gui/clips/MidiClipView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -498,7 +498,8 @@ void MidiClipView::wheelEvent(QWheelEvent * we)
const auto pos = we->position().toPoint();
if(m_clip->m_clipType == MidiClip::Type::BeatClip &&
(fixedClips() || pixelsPerBar() >= 96) &&
pos.y() > height() - m_stepBtnOff.height())
pos.y() > height() - m_stepBtnOff.height() &&
!(we->modifiers() & (Qt::ControlModifier | Qt::ShiftModifier)))
{
// get the step number that was wheeled on and
// do calculations in floats to prevent rounding errors...
Expand Down
120 changes: 119 additions & 1 deletion src/gui/editors/PatternEditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,12 @@
#include "PatternEditor.h"

#include <QAction>
#include <QLabel>
#include <QScrollBar>
#include <QSlider>
#include <QVBoxLayout>

#include "AutomatableSlider.h"
#include "ClipView.h"
#include "ComboBox.h"
#include "DataFile.h"
Expand All @@ -48,6 +52,7 @@ namespace lmms::gui

PatternEditor::PatternEditor(PatternStore* ps) :
TrackContainerView(ps),
m_zoomingModel(new IntModel(0, 0, 100, nullptr, tr("Zoom"))),
m_ps(ps),
m_trackHeadWidth(ConfigManager::inst()->value("ui", "compacttrackbuttons").toInt() == 1
? DEFAULT_SETTINGS_WIDGET_WIDTH_COMPACT + TRACK_OP_WIDTH_COMPACT
Expand All @@ -60,12 +65,33 @@ PatternEditor::PatternEditor(PatternStore* ps) :
Engine::getSong()->getTimeline(Song::PlayMode::Pattern),
m_currentPosition, this
);
connect(this, &TrackContainerView::positionChanged, m_timeLine, qOverload<>(&QWidget::update));
connect(m_timeLine->timeline(), &Timeline::positionChanged, this, &PatternEditor::updatePosition);
static_cast<QVBoxLayout*>(layout())->insertWidget(0, m_timeLine);

connect(m_ps, &PatternStore::trackUpdated,
this, &PatternEditor::updateMaxSteps);

// Set up zooming model
m_zoomingModel->setParent(this);
m_zoomingModel->setJournalling(false);
connect(m_zoomingModel, SIGNAL(dataChanged()), this, SLOT(zoomingChanged()));

connect(Engine::getSong(), &Song::stopped, this, [this]()
{
// Show zoom controls again as they are hidden during playback
emit zoomControlsVisibilityChanged( m_maxClipLength / TimePos::ticksPerBar() > 1 );
Comment thread
Itreza2 marked this conversation as resolved.
Outdated
});

// Set up horizontal scroll bar
m_leftRightScroll = new QScrollBar( Qt::Horizontal, this );
Comment thread
Itreza2 marked this conversation as resolved.
Outdated
m_leftRightScroll->setMinimum(0);
m_leftRightScroll->setMaximum(0);
m_leftRightScroll->setSingleStep(1);
m_leftRightScroll->setPageStep( m_maxClipLength );
static_cast<QVBoxLayout *>( layout() )->addWidget( m_leftRightScroll );
connect(m_leftRightScroll, SIGNAL(valueChanged(int)),this, SLOT(horizontalScrollChanged()));
Comment thread
Itreza2 marked this conversation as resolved.
Outdated

setFocusPolicy(Qt::StrongFocus);
setFocus();
}
Expand Down Expand Up @@ -206,7 +232,7 @@ void PatternEditor::updatePixelsPerBar()
setPixelsPerBar(m_maxClipLength != 0
? (width() - m_trackHeadWidth) * TimePos::ticksPerBar() / m_maxClipLength
: (width() - m_trackHeadWidth));
m_timeLine->setPixelsPerBar(pixelsPerBar());
m_timeLine->setPixelsPerBar(pixelsPerBar() * getZoom());
}

void PatternEditor::updateMaxSteps()
Expand All @@ -223,6 +249,41 @@ void PatternEditor::updateMaxSteps()
}
}
updatePixelsPerBar();
updateScrollBar();

// Show zoom controls if the pattern is longer than one bar, hide them otherwise as they would have no effect anyway
emit zoomControlsVisibilityChanged( m_maxClipLength / TimePos::ticksPerBar() > 1 );
Comment thread
Itreza2 marked this conversation as resolved.
Outdated
}


void PatternEditor::updateScrollBar()
{
m_leftRightScroll->setPageStep( m_maxClipLength / getZoom() );
m_leftRightScroll->setMaximum( m_maxClipLength - m_leftRightScroll->pageStep() );
Comment thread
Itreza2 marked this conversation as resolved.
Outdated
}


void PatternEditor::wheelEvent( QWheelEvent * we )
Comment thread
Itreza2 marked this conversation as resolved.
Outdated
{
const auto posX = we->position().toPoint().x();
if ((we->modifiers() & Qt::ControlModifier) && (posX > m_trackHeadWidth))
{
// move zoom slider (pixelsPerBar will change automatically)
int step = we->modifiers() & Qt::ShiftModifier ? 1 : 5;
// when Alt is pressed, wheelEvent returns delta for x coordinate (mimics horizontal mouse wheel)
int direction = (we->angleDelta().y() + we->angleDelta().x()) > 0 ? 1 : -1;
m_zoomingModel->incValue(step * direction);
}
else if (we->modifiers() & Qt::ShiftModifier)
{
m_leftRightScroll->setValue( m_leftRightScroll->value() - we->angleDelta().y() );
Comment thread
Itreza2 marked this conversation as resolved.
Outdated
}
else
{
we->ignore();
return;
}
we->accept();
}


Expand Down Expand Up @@ -271,6 +332,23 @@ void PatternEditor::cloneClip()
}


void PatternEditor::zoomingChanged()
{
updatePixelsPerBar();
updateScrollBar();

emit zoomLevelChanged();
}

void PatternEditor::horizontalScrollChanged()
{
m_currentPosition = TimePos( m_leftRightScroll->value() );
Comment thread
Itreza2 marked this conversation as resolved.
Outdated
updatePosition();

emit offsetValueChanged();
}




PatternEditorWindow::PatternEditorWindow(PatternStore* ps) :
Expand Down Expand Up @@ -327,6 +405,23 @@ PatternEditorWindow::PatternEditorWindow(PatternStore* ps) :
stretch->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
trackAndStepActionsToolBar->addWidget(stretch);

QLabel* zoom_lbl = new QLabel(m_toolBar);
zoom_lbl->setPixmap( embed::getIconPixmap( "zoom" ) );
Comment thread
Itreza2 marked this conversation as resolved.
Outdated

// Set slider zoom
m_zoomingSlider = new AutomatableSlider(m_toolBar, tr("Zoom"));
m_zoomingSlider->setModel(m_editor->m_zoomingModel);
m_zoomingSlider->setOrientation(Qt::Horizontal);
m_zoomingSlider->setPageStep(1);
m_zoomingSlider->setFocusPolicy(Qt::NoFocus);
m_zoomingSlider->setFixedSize(100, 26);
m_zoomingSlider->setToolTip(tr("Zoom"));
m_zoomingSlider->setContextMenuPolicy(Qt::NoContextMenu);
connect(m_editor, &PatternEditor::zoomControlsVisibilityChanged, this, &PatternEditorWindow::showZoomControls);

m_zoomIconAction = trackAndStepActionsToolBar->addWidget(zoom_lbl);
m_zoomSliderAction = trackAndStepActionsToolBar->addWidget(m_zoomingSlider);
showZoomControls( false );

// Step actions
trackAndStepActionsToolBar->addAction(embed::getIconPixmap("step_btn_remove"), tr("Remove steps"),
Expand Down Expand Up @@ -358,15 +453,28 @@ QSize PatternEditorWindow::sizeHint() const
}


double PatternEditorWindow::horizontalScrollValue() const
{
return m_editor->m_leftRightScroll->value() / static_cast<double>(m_editor->m_leftRightScroll->pageStep());
}


void PatternEditorWindow::play()
{
showZoomControls( false );
Comment thread
Itreza2 marked this conversation as resolved.
Outdated

if (Engine::getSong()->playMode() != Song::PlayMode::Pattern)
{
m_zoomingSlider->setValue(0);
Engine::getSong()->playPattern();
}
else
{
Engine::getSong()->togglePause();
if ( Engine::getSong()->isPaused())
{
showZoomControls( true );
}
Comment thread
Itreza2 marked this conversation as resolved.
Outdated
}
}

Expand All @@ -377,4 +485,14 @@ void PatternEditorWindow::stop()
}


void PatternEditorWindow::showZoomControls( bool show )
{
if ( !Engine::getSong()->isPlaying() )
{
m_zoomIconAction->setVisible( show );
m_zoomSliderAction->setVisible( show );
}
}
Comment thread
Itreza2 marked this conversation as resolved.
Outdated


} // namespace lmms::gui
1 change: 0 additions & 1 deletion src/gui/tracks/TrackContentWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,6 @@ void TrackContentWidget::changePosition( const TimePos & newPos )
{
if (clipView->getClip()->startPosition().getBar() == curPattern)
{
clipView->move(0, clipView->y());
clipView->raise();
clipView->show();
}
Expand Down
Loading