From aff2987a433fdfac23321c5a8de495b483aa4e05 Mon Sep 17 00:00:00 2001 From: Vesa Date: Fri, 7 Mar 2014 10:26:47 +0200 Subject: [PATCH 1/4] Patternview: improve note drawing code, fix bugs (fixes #419) --- src/tracks/pattern.cpp | 62 +++++++++++++++++++++++++++++++----------- 1 file changed, 46 insertions(+), 16 deletions(-) diff --git a/src/tracks/pattern.cpp b/src/tracks/pattern.cpp index 545c21b0c..8ac83c90c 100644 --- a/src/tracks/pattern.cpp +++ b/src/tracks/pattern.cpp @@ -960,19 +960,29 @@ void patternView::paintEvent( QPaintEvent * ) height() - 2 * TCO_BORDER_WIDTH ); } +// melody pattern paint event + if( m_pat->m_patternType == pattern::MelodyPattern ) { - int central_key = 0; if( m_pat->m_notes.size() > 0 ) { // first determine the central tone so that we can // display the area where most of the m_notes are + // also calculate min/max tones so the tonal range can be + // properly stretched accross the pattern vertically + + int central_key = 0; + int max_key = 0; + int min_key = 9999999; int total_notes = 0; + for( NoteVector::Iterator it = m_pat->m_notes.begin(); it != m_pat->m_notes.end(); ++it ) { if( ( *it )->length() > 0 ) { + max_key = qMax( max_key, ( *it )->key() ); + min_key = qMin( min_key, ( *it )->key() ); central_key += ( *it )->key(); ++total_notes; } @@ -981,10 +991,18 @@ void patternView::paintEvent( QPaintEvent * ) if( total_notes > 0 ) { central_key = central_key / total_notes; + const int keyrange = qMax( qMax( max_key - central_key, central_key - min_key ), 1 ); + + // debug code + // qDebug( "keyrange: %d", keyrange ); - const int central_y = height() / 2; - int y_base = central_y + TCO_BORDER_WIDTH -1; + // determine height of the pattern view, sans borders + const int ht = height() - 1 - TCO_BORDER_WIDTH * 2; + + // determine maximum height value for drawing bounds checking + const int max_ht = height() - 1 - TCO_BORDER_WIDTH; + // set colour based on mute status if( m_pat->getTrack()->isMuted() || m_pat->isMuted() ) { @@ -992,28 +1010,40 @@ void patternView::paintEvent( QPaintEvent * ) } else { - p.setPen( QColor( 255, 255, 255 ) ); + p.setPen( QColor( 255, 255, 255 ) ); /// \todo make this a qproperty } + // scan through all the notes and draw them on the pattern for( NoteVector::Iterator it = m_pat->m_notes.begin(); it != m_pat->m_notes.end(); ++it ) { - const int y_pos = central_key - - ( *it )->key(); + // calculate relative y-position + const float y_key = + ( float( central_key - ( *it )->key() ) / keyrange + 1.0f ) / 2; + // multiply that by pattern height + const int y_pos = static_cast( TCO_BORDER_WIDTH + y_key * ht ); + + // debug code + // if( ( *it )->length() > 0 ) qDebug( "key %d, central_key %d, y_key %f, y_pos %d", ( *it )->key(), central_key, y_key, y_pos ); + // check that note isn't out of bounds, and has a length if( ( *it )->length() > 0 && - y_pos > -central_y && - y_pos < central_y ) + y_pos >= TCO_BORDER_WIDTH && + y_pos <= max_ht ) { - const int x1 = 2 * x_base + - static_cast( ( *it )->pos() * ( ppt - TCO_BORDER_WIDTH ) / - MidiTime::ticksPerTact() ); - const int x2 = - static_cast( ( ( *it )->pos() + ( *it )->length() ) * ( ppt - TCO_BORDER_WIDTH ) / MidiTime::ticksPerTact() ); - p.drawLine( x1, y_base + y_pos, - x2, y_base + y_pos ); - + // calculate start and end x-coords of the line to be drawn + const int x1 = x_base + + static_cast + ( ( *it )->pos() * ( ppt / MidiTime::ticksPerTact() ) ); + const int x2 = x_base + + static_cast + ( ( ( *it )->pos() + ( *it )->length() ) * ( ppt / MidiTime::ticksPerTact() ) ); + + // check bounds, draw line + if( x1 < width() - TCO_BORDER_WIDTH ) + p.drawLine( x1, y_pos, + qMin( x2, width() - TCO_BORDER_WIDTH ), y_pos ); } } } From 31fa7ca061aa5b0b6d39dab24630024ec32927b4 Mon Sep 17 00:00:00 2001 From: Vesa Date: Fri, 7 Mar 2014 11:54:17 +0200 Subject: [PATCH 2/4] AutomationPattern: fix a bug I accidentally introduced in length() --- src/core/AutomationPattern.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/core/AutomationPattern.cpp b/src/core/AutomationPattern.cpp index adebac163..76d2d2b16 100644 --- a/src/core/AutomationPattern.cpp +++ b/src/core/AutomationPattern.cpp @@ -165,6 +165,7 @@ const AutomatableModel * AutomationPattern::firstObject() const MidiTime AutomationPattern::length() const { + if( m_timeMap.isEmpty() ) return 0; timeMap::const_iterator it = m_timeMap.end(); return MidiTime( qMax( MidiTime( (it-1).key() ).getTact() + 1, 1 ), 0 ); } From 0947bcf70f1e8d7defff6a0d3ef1259158cba0d0 Mon Sep 17 00:00:00 2001 From: Vesa Date: Sat, 8 Mar 2014 11:43:05 +0200 Subject: [PATCH 3/4] Song editor: fix jittery tracks bug (issue #286) --- include/TrackContainerView.h | 6 +++--- src/core/track.cpp | 10 ++++++---- src/gui/TrackContainerView.cpp | 9 +++++++-- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/include/TrackContainerView.h b/include/TrackContainerView.h index a18bf5a78..48d8c4957 100644 --- a/include/TrackContainerView.h +++ b/include/TrackContainerView.h @@ -2,7 +2,7 @@ * TrackContainerView.h - view-component for TrackContainer * * Copyright (c) 2004-2014 Tobias Doerffel - * + * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * * This program is free software; you can redistribute it and/or @@ -23,8 +23,8 @@ */ -#ifndef _TRACK_CONTAINER_VIEW_H -#define _TRACK_CONTAINER_VIEW_H +#ifndef TRACK_CONTAINER_VIEW_H +#define TRACK_CONTAINER_VIEW_H #include #include diff --git a/src/core/track.cpp b/src/core/track.cpp index 3d0c563d5..66452bfa6 100644 --- a/src/core/track.cpp +++ b/src/core/track.cpp @@ -2403,10 +2403,12 @@ void trackView::mouseMoveEvent( QMouseEvent * _me ) else if( m_action == MoveTrack ) { // look which track-widget the mouse-cursor is over - const trackView * track_at_y = - m_trackContainerView->trackViewAt( - mapTo( m_trackContainerView->contentWidget(), - _me->pos() ).y() ); + const int y_pos = m_trackContainerView->contentWidget()->mapFromGlobal( _me->globalPos() ).y(); + const trackView * track_at_y = m_trackContainerView->trackViewAt( y_pos ); + +// debug code +// qDebug( "y position %d", y_pos ); + // a track-widget not equal to ourself? if( track_at_y != NULL && track_at_y != this ) { diff --git a/src/gui/TrackContainerView.cpp b/src/gui/TrackContainerView.cpp index 29a2e3295..51e0b7788 100644 --- a/src/gui/TrackContainerView.cpp +++ b/src/gui/TrackContainerView.cpp @@ -2,7 +2,7 @@ * TrackContainerView.cpp - view-component for TrackContainer * * Copyright (c) 2004-2014 Tobias Doerffel - * + * * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net * * This program is free software; you can redistribute it and/or @@ -252,11 +252,16 @@ void TrackContainerView::deleteTrackView( trackView * _tv ) const trackView * TrackContainerView::trackViewAt( const int _y ) const { - const int abs_y = _y + m_scrollArea->viewport()->y(); + const int abs_y = _y + m_scrollArea->verticalScrollBar()->value(); int y_cnt = 0; + +// debug code +// qDebug( "abs_y %d", abs_y ); + for( trackViewList::const_iterator it = m_trackViews.begin(); it != m_trackViews.end(); ++it ) { + i++; const int y_cnt1 = y_cnt; y_cnt += ( *it )->height(); if( abs_y >= y_cnt1 && abs_y < y_cnt ) From ee043f9b68458472a8c27b3d7d58d9165932e25a Mon Sep 17 00:00:00 2001 From: Vesa Date: Sat, 8 Mar 2014 13:14:21 +0200 Subject: [PATCH 4/4] Fix previous --- src/gui/TrackContainerView.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/gui/TrackContainerView.cpp b/src/gui/TrackContainerView.cpp index 51e0b7788..bfcbd62f9 100644 --- a/src/gui/TrackContainerView.cpp +++ b/src/gui/TrackContainerView.cpp @@ -261,7 +261,6 @@ const trackView * TrackContainerView::trackViewAt( const int _y ) const for( trackViewList::const_iterator it = m_trackViews.begin(); it != m_trackViews.end(); ++it ) { - i++; const int y_cnt1 = y_cnt; y_cnt += ( *it )->height(); if( abs_y >= y_cnt1 && abs_y < y_cnt )