diff --git a/CMakeLists.txt b/CMakeLists.txt
index b63900dda..22e241c92 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -36,7 +36,7 @@ SET(PROJECT_DESCRIPTION "${PROJECT_NAME_UCASE} - Free music production software"
SET(PROJECT_COPYRIGHT "2008-${PROJECT_YEAR} ${PROJECT_AUTHOR}")
SET(VERSION_MAJOR "1")
SET(VERSION_MINOR "2")
-SET(VERSION_RELEASE "0")
+SET(VERSION_RELEASE "1")
SET(VERSION_STAGE "")
SET(VERSION_BUILD "0")
SET(VERSION "${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_RELEASE}")
@@ -438,9 +438,9 @@ If(WANT_GIG)
ENDIF(WANT_GIG)
# check for pthreads
-IF(LMMS_BUILD_LINUX OR LMMS_BUILD_APPLE OR LMMS_BUILD_OPENBSD)
+IF(LMMS_BUILD_LINUX OR LMMS_BUILD_APPLE OR LMMS_BUILD_OPENBSD OR LMMS_BUILD_FREEBSD)
FIND_PACKAGE(Threads)
-ENDIF(LMMS_BUILD_LINUX OR LMMS_BUILD_APPLE OR LMMS_BUILD_OPENBSD)
+ENDIF(LMMS_BUILD_LINUX OR LMMS_BUILD_APPLE OR LMMS_BUILD_OPENBSD OR LMMS_BUILD_FREEBSD)
# check for sndio (roaraudio won't work yet)
IF(WANT_SNDIO)
diff --git a/cmake/modules/DetectMachine.cmake b/cmake/modules/DetectMachine.cmake
index 08e8745cd..86807b757 100644
--- a/cmake/modules/DetectMachine.cmake
+++ b/cmake/modules/DetectMachine.cmake
@@ -4,6 +4,8 @@ ELSEIF(APPLE)
SET(LMMS_BUILD_APPLE 1)
ELSEIF(${CMAKE_SYSTEM_NAME} MATCHES "OpenBSD")
SET(LMMS_BUILD_OPENBSD 1)
+ELSEIF(${CMAKE_SYSTEM_NAME} MATCHES "FreeBSD")
+ SET(LMMS_BUILD_FREEBSD 1)
ELSEIF(HAIKU)
SET(LMMS_BUILD_HAIKU 1)
ELSE()
diff --git a/data/locale/pl.ts b/data/locale/pl.ts
index 5d9cc51cd..4214718af 100644
--- a/data/locale/pl.ts
+++ b/data/locale/pl.ts
@@ -3108,7 +3108,7 @@ Możesz usunąć i przenieść kanały FX w menu kontekstowym, które jest dost
VELOCITY
- GŁOŚNOŚĆ UDERZENIA
+ PRĘDKOŚĆ
ENABLE MIDI OUTPUT
@@ -10321,4 +10321,4 @@ Kontrolka LED w prawym dolnym rogu edytora kształtu fali pokazuje, czy wybrana
Wzmocnienie wyścia
-
\ No newline at end of file
+
diff --git a/data/locale/ru.ts b/data/locale/ru.ts
index c7ec3a328..f717d598d 100644
--- a/data/locale/ru.ts
+++ b/data/locale/ru.ts
@@ -1664,7 +1664,7 @@ Oe Ai <oeai/at/symbiants/dot/com>
W/D
- НАСЫЩ
+
@@ -1679,7 +1679,7 @@ Oe Ai <oeai/at/symbiants/dot/com>
DECAY
- ЗАТУХАНИЕ
+
diff --git a/data/locale/sv.ts b/data/locale/sv.ts
index eb51c9082..56cf1a0af 100644
--- a/data/locale/sv.ts
+++ b/data/locale/sv.ts
@@ -1658,7 +1658,7 @@ If you're interested in translating LMMS in another language or want to imp
W/D
- B/T
+
@@ -1673,7 +1673,7 @@ If you're interested in translating LMMS in another language or want to imp
DECAY
- FÖRFALL
+
diff --git a/data/locale/uk.ts b/data/locale/uk.ts
index 7271c4946..c088f401c 100644
--- a/data/locale/uk.ts
+++ b/data/locale/uk.ts
@@ -1678,7 +1678,7 @@ If you're interested in translating LMMS in another language or want to imp
DECAY
- ЗГАСАННЯ
+
diff --git a/include/SongEditor.h b/include/SongEditor.h
index 8a02d5691..6f39cc1d9 100644
--- a/include/SongEditor.h
+++ b/include/SongEditor.h
@@ -79,6 +79,9 @@ public:
public slots:
void scrolled( int new_pos );
+ void selectRegionFromPixels(int xStart, int xEnd);
+ void stopSelectRegion();
+ void updateRubberband();
void setEditMode( EditMode mode );
void setEditModeDraw();
@@ -91,6 +94,9 @@ public slots:
protected:
virtual void closeEvent( QCloseEvent * ce );
+ virtual void mousePressEvent(QMouseEvent * me);
+ virtual void mouseMoveEvent(QMouseEvent * me);
+ virtual void mouseReleaseEvent(QMouseEvent * me);
private slots:
void setHighQuality( bool );
@@ -115,6 +121,9 @@ private:
virtual bool allowRubberband() const;
+ int trackIndexFromSelectionPoint(int yPos);
+ int indexOfTrackView(const TrackView* tv);
+
Song * m_song;
@@ -141,11 +150,19 @@ private:
bool m_scrollBack;
bool m_smoothScroll;
- int m_widgetWidthTotal;
EditMode m_mode;
EditMode m_ctrlMode; // mode they were in before they hit ctrl
+ QPoint m_origin;
+ QPoint m_scrollPos;
+ QPoint m_mousePos;
+ int m_rubberBandStartTrackview;
+ MidiTime m_rubberbandStartMidipos;
+ int m_currentZoomingValue;
+ int m_trackHeadWidth;
+ bool m_selectRegion;
+
friend class SongEditorWindow;
} ;
diff --git a/include/Track.h b/include/Track.h
index 6c98de10e..40b32a61a 100644
--- a/include/Track.h
+++ b/include/Track.h
@@ -215,6 +215,12 @@ public:
{
return m_tco;
}
+
+ inline TrackView * getTrackView()
+ {
+ return m_trackView;
+ }
+
// qproperty access func
QColor mutedColor() const;
QColor mutedBackgroundColor() const;
@@ -263,10 +269,6 @@ protected:
float pixelsPerTact();
- inline TrackView * getTrackView()
- {
- return m_trackView;
- }
DataFile createTCODataFiles(const QVector & tcos) const;
diff --git a/include/TrackContainerView.h b/include/TrackContainerView.h
index 67575583b..094cbfff0 100644
--- a/include/TrackContainerView.h
+++ b/include/TrackContainerView.h
@@ -131,24 +131,17 @@ public slots:
virtual void dropEvent( QDropEvent * _de );
virtual void dragEnterEvent( QDragEnterEvent * _dee );
- ///
- /// \brief selectRegionFromPixels
- /// \param x
- /// \param y
- /// Use the rubber band to select TCO from all tracks using x, y pixels
- void selectRegionFromPixels(int xStart, int xEnd);
///
/// \brief stopRubberBand
/// Removes the rubber band from display when finished with.
void stopRubberBand();
+
protected:
static const int DEFAULT_PIXELS_PER_TACT = 16;
- virtual void mousePressEvent( QMouseEvent * _me );
- virtual void mouseMoveEvent( QMouseEvent * _me );
- virtual void mouseReleaseEvent( QMouseEvent * _me );
+
virtual void resizeEvent( QResizeEvent * );
MidiTime m_currentPosition;
@@ -186,7 +179,7 @@ private:
float m_ppt;
RubberBand * m_rubberBand;
- QPoint m_origin;
+
signals:
diff --git a/include/versioninfo.h b/include/versioninfo.h
index b34936d57..a5d3d64c6 100644
--- a/include/versioninfo.h
+++ b/include/versioninfo.h
@@ -32,6 +32,10 @@
#define PLATFORM "OpenBSD"
#endif
+#ifdef LMMS_BUILD_FREEBSD
+#define PLATFORM "FreeBSD"
+#endif
+
#ifdef LMMS_BUILD_WIN32
#define PLATFORM "win32"
#endif
diff --git a/plugins/organic/organic.cpp b/plugins/organic/organic.cpp
index 7da4fc6f7..6eb933afa 100644
--- a/plugins/organic/organic.cpp
+++ b/plugins/organic/organic.cpp
@@ -306,7 +306,7 @@ void organicInstrument::playNote( NotePlayHandle * _n,
// fxKnob is [0;1]
float t = m_fx1Model.value();
- for (int i=0 ; i < frames ; i++)
+ for (int i=0 ; i < frames + offset ; i++)
{
_working_buffer[i][0] = waveshape( _working_buffer[i][0], t ) *
m_volModel.value() / 100.0f;
diff --git a/plugins/vst_base/RemoteVstPlugin.cpp b/plugins/vst_base/RemoteVstPlugin.cpp
index 48ab13743..5b4bbbd9b 100644
--- a/plugins/vst_base/RemoteVstPlugin.cpp
+++ b/plugins/vst_base/RemoteVstPlugin.cpp
@@ -734,6 +734,7 @@ void RemoteVstPlugin::init( const std::string & _plugin_file )
static void close_check( FILE* fp )
{
+ if (!fp) {return;}
if( fclose( fp ) )
{
perror( "fclose" );
@@ -1128,6 +1129,12 @@ void RemoteVstPlugin::saveChunkToFile( const std::string & _file )
if( len > 0 )
{
FILE* fp = F_OPEN_UTF8( _file, "wb" );
+ if (!fp)
+ {
+ fprintf( stderr,
+ "Error opening file for saving chunk.\n" );
+ return;
+ }
if ( fwrite( chunk, 1, len, fp ) != len )
{
fprintf( stderr,
@@ -1293,6 +1300,12 @@ void RemoteVstPlugin::savePreset( const std::string & _file )
pBank->numPrograms = endian_swap( uIntToFile );
FILE * stream = F_OPEN_UTF8( _file, "w" );
+ if (!stream)
+ {
+ fprintf( stderr,
+ "Error opening file for saving preset.\n" );
+ return;
+ }
fwrite ( pBank, 1, 28, stream );
fwrite ( progName, 1, isPreset ? 28 : 128, stream );
if ( chunky ) {
@@ -1345,6 +1358,12 @@ void RemoteVstPlugin::loadPresetFile( const std::string & _file )
unsigned int len = 0;
sBank * pBank = (sBank*) new char[ sizeof( sBank ) ];
FILE * stream = F_OPEN_UTF8( _file, "r" );
+ if (!stream)
+ {
+ fprintf( stderr,
+ "Error opening file for loading preset.\n" );
+ return;
+ }
if ( fread ( pBank, 1, 56, stream ) != 56 )
{
fprintf( stderr, "Error loading preset file.\n" );
@@ -1446,6 +1465,12 @@ void RemoteVstPlugin::loadChunkFromFile( const std::string & _file, int _len )
char * chunk = new char[_len];
FILE* fp = F_OPEN_UTF8( _file, "rb" );
+ if (!fp)
+ {
+ fprintf( stderr,
+ "Error opening file for loading chunk.\n" );
+ return;
+ }
if ( fread( chunk, 1, _len, fp ) != _len )
{
fprintf( stderr, "Error loading chunk from file.\n" );
diff --git a/plugins/zynaddsubfx/CMakeLists.txt b/plugins/zynaddsubfx/CMakeLists.txt
index d6fa9c727..f9cc4efd3 100644
--- a/plugins/zynaddsubfx/CMakeLists.txt
+++ b/plugins/zynaddsubfx/CMakeLists.txt
@@ -3,7 +3,7 @@ INCLUDE(BuildPlugin)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
# definitions for ZynAddSubFX
-IF(LMMS_BUILD_LINUX OR LMMS_BUILD_APPLE OR LMMS_BUILD_OPENBSD)
+IF(LMMS_BUILD_LINUX OR LMMS_BUILD_APPLE OR LMMS_BUILD_OPENBSD OR LMMS_BUILD_FREEBSD)
FIND_PACKAGE(X11)
INCLUDE_DIRECTORIES(${X11_INCLUDE_DIR})
ADD_DEFINITIONS(-DOS_LINUX)
diff --git a/src/core/Mixer.cpp b/src/core/Mixer.cpp
index 2550b072e..fd44b0459 100644
--- a/src/core/Mixer.cpp
+++ b/src/core/Mixer.cpp
@@ -1247,7 +1247,7 @@ void Mixer::fifoWriter::run()
disable_denormals();
#if 0
-#ifdef LMMS_BUILD_LINUX
+#if defined(LMMS_BUILD_LINUX) || defined(LMMS_BUILD_FREEBSD)
#ifdef LMMS_HAVE_SCHED_H
cpu_set_t mask;
CPU_ZERO( &mask );
diff --git a/src/core/ProjectRenderer.cpp b/src/core/ProjectRenderer.cpp
index 71a5aaff8..19bdf4be8 100644
--- a/src/core/ProjectRenderer.cpp
+++ b/src/core/ProjectRenderer.cpp
@@ -168,7 +168,7 @@ void ProjectRenderer::run()
{
MemoryManager::ThreadGuard mmThreadGuard; Q_UNUSED(mmThreadGuard);
#if 0
-#ifdef LMMS_BUILD_LINUX
+#if defined(LMMS_BUILD_LINUX) || defined(LMMS_BUILD_FREEBSD)
#ifdef LMMS_HAVE_SCHED_H
cpu_set_t mask;
CPU_ZERO( &mask );
diff --git a/src/core/SampleBuffer.cpp b/src/core/SampleBuffer.cpp
index 779592529..d0c39b13a 100644
--- a/src/core/SampleBuffer.cpp
+++ b/src/core/SampleBuffer.cpp
@@ -370,11 +370,14 @@ void SampleBuffer::directFloatWrite ( sample_t * & _fbuf, f_cnt_t _frames, int _
void SampleBuffer::normalizeSampleRate( const sample_rate_t _src_sr,
bool _keep_settings )
{
+ const sample_rate_t old_rate = m_sampleRate;
// do samplerate-conversion to our default-samplerate
if( _src_sr != mixerSampleRate() )
{
SampleBuffer * resampled = resample( _src_sr,
mixerSampleRate() );
+
+ m_sampleRate = mixerSampleRate();
MM_FREE( m_data );
m_frames = resampled->frames();
m_data = MM_ALLOC( sampleFrame, m_frames );
@@ -389,6 +392,16 @@ void SampleBuffer::normalizeSampleRate( const sample_rate_t _src_sr,
m_loopStartFrame = m_startFrame = 0;
m_loopEndFrame = m_endFrame = m_frames;
}
+ else if( old_rate != mixerSampleRate() )
+ {
+ auto old_rate_to_new_rate_ratio = static_cast(mixerSampleRate()) / old_rate;
+
+ m_startFrame = qBound(0, f_cnt_t(m_startFrame*old_rate_to_new_rate_ratio), m_frames);
+ m_endFrame = qBound(m_startFrame, f_cnt_t(m_endFrame*old_rate_to_new_rate_ratio), m_frames);
+ m_loopStartFrame = qBound(0, f_cnt_t(m_loopStartFrame*old_rate_to_new_rate_ratio), m_frames);
+ m_loopEndFrame = qBound(m_loopStartFrame, f_cnt_t(m_loopEndFrame*old_rate_to_new_rate_ratio), m_frames);
+ m_sampleRate = mixerSampleRate();
+ }
}
diff --git a/src/core/main.cpp b/src/core/main.cpp
index 1a1d61d8c..531a0a4da 100644
--- a/src/core/main.cpp
+++ b/src/core/main.cpp
@@ -721,7 +721,7 @@ int main( int argc, char * * argv )
// try to set realtime priority
-#ifdef LMMS_BUILD_LINUX
+#if defined(LMMS_BUILD_LINUX) || defined(LMMS_BUILD_FREEBSD)
#ifdef LMMS_HAVE_SCHED_H
#ifndef __OpenBSD__
struct sched_param sparam;
diff --git a/src/gui/MainWindow.cpp b/src/gui/MainWindow.cpp
index 08bc90852..acdbabb35 100644
--- a/src/gui/MainWindow.cpp
+++ b/src/gui/MainWindow.cpp
@@ -1518,7 +1518,12 @@ void MainWindow::exportProject(bool multiExport)
// Get first extension from selected dropdown.
// i.e. ".wav" from "WAV-File (*.wav), Dummy-File (*.dum)"
suffix = efd.selectedNameFilter().mid( stx + 2, etx - stx - 2 ).split( " " )[0].trimmed();
- exportFileName.remove( "." + suffix, Qt::CaseInsensitive );
+
+ Qt::CaseSensitivity cs = Qt::CaseSensitive;
+#if defined(LMMS_BUILD_APPLE) || defined(LMMS_BUILD_WIN32)
+ cs = Qt::CaseInsensitive;
+#endif
+ exportFileName.remove( "." + suffix, cs );
if ( efd.selectedFiles()[0].endsWith( suffix ) )
{
if( VersionedSaveDialog::fileExistsQuery( exportFileName + suffix,
diff --git a/src/gui/PianoView.cpp b/src/gui/PianoView.cpp
index c1be922c6..c5f1b623f 100644
--- a/src/gui/PianoView.cpp
+++ b/src/gui/PianoView.cpp
@@ -187,7 +187,7 @@ int PianoView::getKeyFromKeyEvent( QKeyEvent * _ke )
case 27: return 31; // ]
}
#endif
-#if defined(LMMS_BUILD_LINUX) || defined(LMMS_BUILD_OPENBSD)
+#if defined(LMMS_BUILD_LINUX) || defined(LMMS_BUILD_OPENBSD) || defined(LMMS_BUILD_FREEBSD)
switch( k )
{
case 52: return 0; // Z = C
diff --git a/src/gui/TrackContainerView.cpp b/src/gui/TrackContainerView.cpp
index 649323c07..bc3205730 100644
--- a/src/gui/TrackContainerView.cpp
+++ b/src/gui/TrackContainerView.cpp
@@ -55,8 +55,7 @@ TrackContainerView::TrackContainerView( TrackContainer * _tc ) :
m_trackViews(),
m_scrollArea( new scrollArea( this ) ),
m_ppt( DEFAULT_PIXELS_PER_TACT ),
- m_rubberBand( new RubberBand( m_scrollArea ) ),
- m_origin()
+ m_rubberBand( new RubberBand( m_scrollArea ) )
{
m_tc->setHook( this );
//keeps the direction of the widget, undepended on the locale
@@ -345,12 +344,8 @@ void TrackContainerView::dragEnterEvent( QDragEnterEvent * _dee )
arg( Track::SampleTrack ) );
}
-void TrackContainerView::selectRegionFromPixels(int xStart, int xEnd)
-{
- m_rubberBand->setEnabled( true );
- m_rubberBand->show();
- m_rubberBand->setGeometry( min( xStart, xEnd ), 0, max( xStart, xEnd ) - min( xStart, xEnd ), std::numeric_limits::max() );
-}
+
+
void TrackContainerView::stopRubberBand()
{
@@ -427,55 +422,18 @@ void TrackContainerView::dropEvent( QDropEvent * _de )
-void TrackContainerView::mousePressEvent( QMouseEvent * _me )
-{
- if( allowRubberband() == true )
- {
- m_origin = m_scrollArea->mapFromParent( _me->pos() );
- m_rubberBand->setEnabled( true );
- m_rubberBand->setGeometry( QRect( m_origin, QSize() ) );
- m_rubberBand->show();
- }
- QWidget::mousePressEvent( _me );
-}
-
-
-
-
-void TrackContainerView::mouseMoveEvent( QMouseEvent * _me )
-{
- if( rubberBandActive() == true )
- {
- m_rubberBand->setGeometry( QRect( m_origin,
- m_scrollArea->mapFromParent( _me->pos() ) ).
- normalized() );
- }
- QWidget::mouseMoveEvent( _me );
-}
-
-
-
-
-void TrackContainerView::mouseReleaseEvent( QMouseEvent * _me )
-{
- m_rubberBand->hide();
- m_rubberBand->setEnabled( false );
- QWidget::mouseReleaseEvent( _me );
-}
-
-
-
-
-
void TrackContainerView::resizeEvent( QResizeEvent * _re )
{
realignTracks();
QWidget::resizeEvent( _re );
}
+
+
+
RubberBand *TrackContainerView::rubberBand() const
{
- return m_rubberBand;
+ return m_rubberBand;
}
diff --git a/src/gui/editors/SongEditor.cpp b/src/gui/editors/SongEditor.cpp
index 6e23fcdbe..a077840d0 100644
--- a/src/gui/editors/SongEditor.cpp
+++ b/src/gui/editors/SongEditor.cpp
@@ -50,7 +50,7 @@
#include "TimeDisplayWidget.h"
#include "AudioDevice.h"
#include "PianoRoll.h"
-
+#include "Track.h"
positionLine::positionLine( QWidget * parent ) :
QWidget( parent )
@@ -80,16 +80,21 @@ SongEditor::SongEditor( Song * song ) :
m_proportionalSnap( false ),
m_scrollBack( false ),
m_smoothScroll( ConfigManager::inst()->value( "ui", "smoothscroll" ).toInt() ),
- m_mode(DrawMode)
+ m_mode(DrawMode),
+ m_origin(),
+ m_scrollPos(),
+ m_mousePos(),
+ m_rubberBandStartTrackview(0),
+ m_rubberbandStartMidipos(0),
+ m_currentZoomingValue(m_zoomingModel->value()),
+ m_trackHeadWidth(ConfigManager::inst()->value("ui", "compacttrackbuttons").toInt()==1
+ ? DEFAULT_SETTINGS_WIDGET_WIDTH_COMPACT + TRACK_OP_WIDTH_COMPACT
+ : DEFAULT_SETTINGS_WIDGET_WIDTH + TRACK_OP_WIDTH),
+ m_selectRegion(false)
{
m_zoomingModel->setParent(this);
m_snappingModel->setParent(this);
- // create time-line
- m_widgetWidthTotal = ConfigManager::inst()->value( "ui",
- "compacttrackbuttons" ).toInt()==1 ?
- DEFAULT_SETTINGS_WIDGET_WIDTH_COMPACT + TRACK_OP_WIDTH_COMPACT :
- DEFAULT_SETTINGS_WIDGET_WIDTH + TRACK_OP_WIDTH;
- m_timeLine = new TimeLineWidget( m_widgetWidthTotal, 32,
+ m_timeLine = new TimeLineWidget( m_trackHeadWidth, 32,
pixelsPerTact(),
m_song->m_playPos[Song::Mode_PlaySong],
m_currentPosition,
@@ -232,6 +237,10 @@ SongEditor::SongEditor( Song * song ) :
this, SLOT( scrolled( int ) ) );
connect( m_song, SIGNAL( lengthChanged( int ) ),
this, SLOT( updateScrollBar( int ) ) );
+ connect(m_leftRightScroll, SIGNAL(valueChanged(int)),this, SLOT(updateRubberband()));
+ connect(contentWidget()->verticalScrollBar(), SIGNAL(valueChanged(int)),this, SLOT(updateRubberband()));
+ connect(m_timeLine, SIGNAL(selectionFinished()), this, SLOT(stopSelectRegion()));
+
//Set up zooming model
for( float const & zoomLevel : m_zoomLevels )
@@ -346,6 +355,99 @@ void SongEditor::scrolled( int new_pos )
+void SongEditor::selectRegionFromPixels(int xStart, int xEnd)
+{
+ if (!m_selectRegion)
+ {
+ m_selectRegion = true;
+
+ //deselect all tcos
+ for (auto &it : findChildren()) { it->setSelected(false); }
+
+ rubberBand()->setEnabled(true);
+ rubberBand()->show();
+
+ //we save the position of scrollbars, mouse position and zooming level
+ m_origin = QPoint(xStart, 0);
+ m_scrollPos = QPoint(m_leftRightScroll->value(), contentWidget()->verticalScrollBar()->value());
+ m_currentZoomingValue = zoomingModel()->value();
+
+ //calculate the song position where the mouse was clicked
+ m_rubberbandStartMidipos = MidiTime((xStart - m_trackHeadWidth)
+ / pixelsPerTact() * MidiTime::ticksPerTact())
+ + m_currentPosition;
+ m_rubberBandStartTrackview = 0;
+ }
+ //the current mouse position within the borders of song editor
+ m_mousePos = QPoint(qMax(m_trackHeadWidth, qMin(xEnd, width()))
+ , std::numeric_limits::max());
+ updateRubberband();
+}
+
+
+
+
+void SongEditor::stopSelectRegion()
+{
+ m_selectRegion = false;
+}
+
+
+
+
+void SongEditor::updateRubberband()
+{
+ if (rubberBandActive())
+ {
+ int originX = m_origin.x();
+
+ //take care of the zooming
+ if (m_currentZoomingValue != m_zoomingModel->value())
+ {
+ originX = m_trackHeadWidth + (originX - m_trackHeadWidth)
+ * m_zoomLevels[m_zoomingModel->value()] / m_zoomLevels[m_currentZoomingValue];
+ }
+
+ //take care of the scrollbar position
+ int hs = (m_leftRightScroll->value() - m_scrollPos.x()) * pixelsPerTact();
+ int vs = contentWidget()->verticalScrollBar()->value() - m_scrollPos.y();
+
+ //the adjusted origin point
+ QPoint origin = QPoint(qMax(originX - hs, m_trackHeadWidth), m_origin.y() - vs);
+
+ //paint the rubber band rect
+ rubberBand()->setGeometry(QRect(origin,
+ contentWidget()->mapFromParent(QPoint(m_mousePos.x(), m_mousePos.y()))
+ ).normalized());
+
+ //the index of the TrackView the mouse is hover
+ int rubberBandTrackview = trackIndexFromSelectionPoint(m_mousePos.y());
+
+ //the miditime the mouse is hover
+ MidiTime rubberbandMidipos = MidiTime((qMin(m_mousePos.x(), width()) - m_trackHeadWidth)
+ / pixelsPerTact() * MidiTime::ticksPerTact())
+ + m_currentPosition;
+
+ //are tcos in the rect of selection?
+ for (auto &it : findChildren())
+ {
+ TrackContentObjectView * tco = dynamic_cast(it);
+ if (tco)
+ {
+ auto indexOfTrackView = trackViews().indexOf(tco->getTrackView());
+ bool isBeetweenRubberbandViews = indexOfTrackView >= qMin(m_rubberBandStartTrackview, rubberBandTrackview)
+ && indexOfTrackView <= qMax(m_rubberBandStartTrackview, rubberBandTrackview);
+ bool isBeetweenRubberbandMidiPos = tco->getTrackContentObject()->endPosition() >= qMin(m_rubberbandStartMidipos, rubberbandMidipos)
+ && tco->getTrackContentObject()->startPosition() <= qMax(m_rubberbandStartMidipos, rubberbandMidipos);
+ it->setSelected(isBeetweenRubberbandViews && isBeetweenRubberbandMidiPos);
+ }
+ }
+ }
+}
+
+
+
+
void SongEditor::setEditMode( EditMode mode )
{
m_mode = mode;
@@ -447,7 +549,7 @@ void SongEditor::wheelEvent( QWheelEvent * we )
z = qBound( 0, z, m_zoomingModel->size() - 1 );
- int x = (we->x() - m_widgetWidthTotal);
+ int x = (we->x() - m_trackHeadWidth);
// tact based on the mouse x-position where the scroll wheel was used
int tact= x / pixelsPerTact();
// what would be the tact in the new zoom level on the very same mouse x
@@ -480,7 +582,7 @@ void SongEditor::wheelEvent( QWheelEvent * we )
void SongEditor::closeEvent( QCloseEvent * ce )
- {
+{
if( parentWidget() )
{
parentWidget()->hide();
@@ -490,7 +592,53 @@ void SongEditor::closeEvent( QCloseEvent * ce )
hide();
}
ce->ignore();
- }
+}
+
+
+
+
+void SongEditor::mousePressEvent(QMouseEvent *me)
+{
+ if (allowRubberband())
+ {
+ //we save the position of scrollbars, mouse position and zooming level
+ m_scrollPos = QPoint(m_leftRightScroll->value(), contentWidget()->verticalScrollBar()->value());
+ m_origin = contentWidget()->mapFromParent(QPoint(me->pos().x(), me->pos().y()));
+ m_currentZoomingValue = zoomingModel()->value();
+
+ //paint the rubberband
+ rubberBand()->setEnabled(true);
+ rubberBand()->setGeometry(QRect(m_origin, QSize()));
+ rubberBand()->show();
+
+ //the trackView(index) and the miditime where the mouse was clicked
+ m_rubberBandStartTrackview = trackIndexFromSelectionPoint(me->y());
+ m_rubberbandStartMidipos = MidiTime((me->x() - m_trackHeadWidth)
+ / pixelsPerTact() * MidiTime::ticksPerTact())
+ + m_currentPosition;
+ }
+ QWidget::mousePressEvent(me);
+}
+
+
+
+
+void SongEditor::mouseMoveEvent(QMouseEvent *me)
+{
+ m_mousePos = me->pos();
+ updateRubberband();
+ QWidget::mouseMoveEvent(me);
+}
+
+
+
+
+void SongEditor::mouseReleaseEvent(QMouseEvent *me)
+{
+ rubberBand()->hide();
+ rubberBand()->setEnabled(false);
+ QWidget::mouseReleaseEvent(me);
+}
@@ -688,6 +836,7 @@ void SongEditor::zoomingChanged()
m_song->m_playPos[Song::Mode_PlaySong].m_timeLine->
setPixelsPerTact( pixelsPerTact() );
realignTracks();
+ updateRubberband();
}
@@ -713,6 +862,26 @@ bool SongEditor::allowRubberband() const
+int SongEditor::trackIndexFromSelectionPoint(int yPos)
+{
+ const TrackView * tv = trackViewAt(yPos - m_timeLine->height());
+ return tv ? indexOfTrackView(tv)
+ : yPos < m_timeLine->height() ? 0
+ : trackViews().count();
+}
+
+
+
+
+int SongEditor::indexOfTrackView(const TrackView *tv)
+{
+ return static_cast(std::distance(trackViews().begin(),
+ std::find(trackViews().begin(), trackViews().end(), tv)));
+}
+
+
+
+
ComboBoxModel *SongEditor::zoomingModel() const
{
return m_zoomingModel;
diff --git a/src/gui/widgets/Rubberband.cpp b/src/gui/widgets/Rubberband.cpp
index 6bf702edc..0a4e891b5 100644
--- a/src/gui/widgets/Rubberband.cpp
+++ b/src/gui/widgets/Rubberband.cpp
@@ -66,18 +66,6 @@ QVector RubberBand::selectedObjects() const
void RubberBand::resizeEvent( QResizeEvent * _re )
{
QRubberBand::resizeEvent( _re );
- if( isEnabled() )
- {
- QVector so = selectableObjects();
- for( QVector::iterator it = so.begin();
- it != so.end(); ++it )
- {
- ( *it )->setSelected( QRect( pos(), size() ).intersects(
- QRect( ( *it )->mapTo( parentWidget(),
- QPoint() ),
- ( *it )->size() ) ) );
- }
- }
}
diff --git a/src/lmmsconfig.h.in b/src/lmmsconfig.h.in
index 02d07f1e4..3ea9d749c 100644
--- a/src/lmmsconfig.h.in
+++ b/src/lmmsconfig.h.in
@@ -3,6 +3,7 @@
#cmakedefine LMMS_BUILD_WIN64
#cmakedefine LMMS_BUILD_APPLE
#cmakedefine LMMS_BUILD_OPENBSD
+#cmakedefine LMMS_BUILD_FREEBSD
#cmakedefine LMMS_BUILD_HAIKU
#cmakedefine LMMS_HOST_X86