detuning display, automation time, journalling and some improvements

git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/trunk/lmms@433 0778d3d1-df1d-0410-868b-ea421aaaa00d
This commit is contained in:
Javier Serrano Polo
2006-12-06 00:36:30 +00:00
parent cdb1167a39
commit 933a295ebd
25 changed files with 957 additions and 240 deletions

View File

@@ -1,3 +1,73 @@
2006-12-06 Javier Serrano Polo <jasp00/at/terra/dot/es>
* include/note.h:
* src/core/note.cpp:
show detuning in the piano roll
* include/piano_roll.h:
* src/core/piano_roll.cpp:
- show note detuning
- save last key when starting to play, fixes held notes bug
- removed cursor enter/leave events, they could be ignored
- optimized unsafe loops
* include/xqmap.h:
initial release, QMap with lowerBound for Qt3
* include/automation_pattern.h:
* src/tracks/automation_pattern.cpp:
- use lowerBound find, resets to proper values
- work with inverted midi time
* include/automation_editor.h:
* src/core/automation_editor.cpp:
- work with inverted midi time
- fixed display of hidden values
- added red cross
- update detuning in the piano roll
- removed cursor enter/leave events, they could be ignored
- optimized unsafe loops
- minor optimizations
* include/note_play_handle.h:
* src/core/arp_and_chords_tab_widget.cpp:
set subnotes' BB track
* data/track_icons/*.png:
re-added corrupted images
* src/core/name_label.cpp:
added bad pixmap protection
* src/audio/audio_alsa.cpp:
- removed unnecessary asynchronous behaviour, fixes large audio buffers
- fill the whole period buffer, avoids underrun in synchronous mode
* src/core/setup_dialog.cpp:
don't use the journal
* include/journalling_object.h:
ease short disabling
* include/automatable_object.h:
- use light journal disabling
- use the journal if necessary
* src/widgets/knob.cpp:
* src/widgets/lcd_spinbox.cpp:
* src/widgets/volume_knob.cpp:
use the journal if necessary
* src/widgets/tempo_sync_knob.cpp:
- change icon when changing mode, fixes automation crash
- disable the journal when calculating sync time
* src/core/bb_editor.cpp:
don't create TCOs when there aren't any BB tracks
* src/tracks/instrument_track.cpp:
removed temporary fix
2006-12-05 Tobias Doerffel <tobydox/at/users/dot/sourceforge/dot/net>
* plugins/ladspa_effect/caps/Makefile.am:

View File

@@ -350,7 +350,8 @@ lmms_SOURCES = \
$(srcdir)/include/dummy_effect.h \
$(srcdir)/include/ladspa-1.1.h \
$(srcdir)/include/meter_dialog.h \
$(srcdir)/include/qxembed.h
$(srcdir)/include/qxembed.h \
$(srcdir)/include/xqmap.h

View File

@@ -2,8 +2,8 @@
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.50)
AC_INIT(lmms, 0.2.1-svn20061205, lmms-devel/at/lists/dot/sf/dot/net)
AM_INIT_AUTOMAKE(lmms, 0.2.1-svn20061205)
AC_INIT(lmms, 0.2.1-svn20061206, lmms-devel/at/lists/dot/sf/dot/net)
AM_INIT_AUTOMAKE(lmms, 0.2.1-svn20061206)
AM_CONFIG_HEADER(config.h)

View File

@@ -62,13 +62,13 @@ public:
const T _max = 0,
const T _step = defaultRelStep() ) :
journallingObject( _engine ),
m_oldValue( _val ),
m_value( _val ),
m_minValue( _min ),
m_maxValue( _max ),
m_step( _step ),
m_automation_pattern( NULL ),
m_track( _track )
m_track( _track ),
m_journalEntryReady( FALSE )
{
m_curLevel = level( _val );
m_minLevel = level( _min );
@@ -161,13 +161,13 @@ public:
inline virtual void setInitValue( const T _value )
{
saveJournallingState( FALSE );
bool journalling = testAndSetJournalling( FALSE );
setValue( _value );
if( m_automation_pattern )
{
setFirstValue();
}
restoreJournallingState();
setJournalling( journalling );
}
inline virtual void setValue( const T _value )
@@ -197,10 +197,11 @@ public:
it->fittedValue( value() ) !=
it->value() )
{
it->saveJournallingState(
bool journalling =
it->testAndSetJournalling(
isJournalling() );
it->setValue( value() );
it->restoreJournallingState();
it->setJournalling( journalling );
}
}
}
@@ -380,7 +381,7 @@ public:
protected:
virtual void redoStep( journalEntry & _je )
{
saveJournallingState( FALSE );
bool journalling = testAndSetJournalling( FALSE );
/*#ifndef QT3
setValue( static_cast<T>( value() +
_je.data().value<EDIT_STEP_TYPE>() ) );
@@ -388,7 +389,7 @@ protected:
setValue( static_cast<T>( value() + static_cast<EDIT_STEP_TYPE>(
_je.data().toDouble() ) ) );
//#endif
restoreJournallingState();
setJournalling( journalling );
}
virtual void undoStep( journalEntry & _je )
@@ -403,13 +404,25 @@ protected:
redoStep( je );
}
// most objects will need this temporarily
T m_oldValue;
inline void prepareJournalEntryFromOldVal( void )
{
m_oldValue = value();
saveJournallingState( FALSE );
m_journalEntryReady = TRUE;
}
inline void addJournalEntryFromOldToCurVal( void )
{
addJournalEntry( journalEntry( 0, value() - m_oldValue ) );
if( m_journalEntryReady )
{
restoreJournallingState();
if( value() != m_oldValue )
{
addJournalEntry( journalEntry( 0, value() -
m_oldValue ) );
}
m_journalEntryReady = FALSE;
}
}
inline void setFirstValue( void )
@@ -438,6 +451,10 @@ private:
QPointer<automationPattern> m_automation_pattern;
track * m_track;
// most objects will need this temporarily
T m_oldValue;
bool m_journalEntryReady;
QVariant m_data;
typedef vvector<autoObj *> autoObjVector;
@@ -483,11 +500,11 @@ private:
{
return;
}
saveJournallingState( FALSE );
bool journalling = testAndSetJournalling( FALSE );
m_automation_pattern->setUpdateFirst( FALSE );
setValue( _level * m_step );
m_automation_pattern->setUpdateFirst( TRUE );
restoreJournallingState();
setJournalling( journalling );
}
inline int level( T _value ) const

View File

@@ -88,11 +88,14 @@ public:
}
public slots:
void update( void );
protected:
typedef automationPattern::timeMap timeMap;
virtual void closeEvent( QCloseEvent * _ce );
virtual void enterEvent( QEvent * _e );
virtual void keyPressEvent( QKeyEvent * _ke );
virtual void leaveEvent( QEvent * _e );
virtual void mousePressEvent( QMouseEvent * _me );
@@ -195,7 +198,6 @@ private:
comboBox * m_quantizeComboBox;
QPixmap m_paintPixmap;
bool m_cursorInside;
automationPattern * m_pattern;
@@ -238,7 +240,7 @@ private:
timeLine * m_timeLine;
bool m_scrollBack;
bool xVisible( int _x );
void drawCross( QPainter & _p );
bool inBBEditor( void );

View File

@@ -31,6 +31,12 @@
#include "track.h"
#include "level_object.h"
#ifdef QT3
#include "xqmap.h"
#endif
@@ -38,7 +44,12 @@ class automationPattern : public QObject, public journallingObject
{
Q_OBJECT
public:
typedef QMap<midiTime, int> timeMap;
// map negative midiTime to level
#ifdef QT3
typedef XQMap<int, int> timeMap;
#else
typedef QMap<int, int> timeMap;
#endif
automationPattern( track * _track, levelObject * _object );
automationPattern( engine * _engine, levelObject * _object );

View File

@@ -172,6 +172,13 @@ protected:
m_journalling = _sr;
}
inline bool testAndSetJournalling( const bool _sr )
{
bool old_journalling = m_journalling;
m_journalling = _sr;
return( old_journalling );
}
// to be implemented by sub-objects
virtual void FASTCALL saveSettings( QDomDocument & _doc,

View File

@@ -177,6 +177,8 @@ public:
void editDetuningPattern( void );
void detachCurrentDetuning( void );
bool hasDetuningInfo( void );
protected:
virtual void FASTCALL saveSettings( QDomDocument & _doc,

View File

@@ -181,6 +181,10 @@ public:
{
m_bbTrack = _bb_track;
}
void setBBTrackFrom( notePlayHandle * _handle )
{
m_bbTrack = _handle->m_bbTrack;
}
virtual bool supportsParallelizing( void ) const

View File

@@ -95,7 +95,6 @@ public:
protected:
virtual void closeEvent( QCloseEvent * _ce );
virtual void enterEvent( QEvent * _e );
virtual void keyPressEvent( QKeyEvent * _ke );
virtual void keyReleaseEvent( QKeyEvent * _ke );
virtual void leaveEvent( QEvent * _e );
@@ -215,7 +214,6 @@ private:
comboBox * m_noteLenComboBox;
QPixmap m_paintPixmap;
bool m_cursorInside;
pattern * m_pattern;
@@ -244,7 +242,6 @@ private:
midiTime m_lenOfNewNotes;
int m_startKey; // first key when drawing
int m_keyMouseOver;
int m_lastKey;
noteVector m_notesToCopy;
@@ -257,6 +254,7 @@ private:
timeLine * m_timeLine;
bool m_scrollBack;
void drawDetuningInfo( QPainter & _p, note * _n, Uint16 _x, Uint16 _y );
bool mouseOverNote( void );
note * noteUnderMouse( void );
noteVector::iterator noteIteratorUnderMouse( void );

519
include/xqmap.h Normal file
View File

@@ -0,0 +1,519 @@
/*
* XQMap.h - eXtended QMap template for Qt3
*
* Copyright (c) 2006 Javier Serrano Polo <jasp00/at/users.sourceforge.net>
*
* This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*
* You should have received a copy of the GNU General Public
* License along with this program (see COPYING); if not, write to the
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301 USA.
*
*/
#ifndef XQMAP_H
#define XQMAP_H
#include <qmap.h>
template<class Key, class T>
class XQMapPrivate : public QMapPrivate<Key, T>
{
public:
typedef QMapConstIterator<Key, T> ConstIterator;
typedef QMapNode<Key, T> * NodePtr;
XQMapPrivate( void );
XQMapPrivate( const XQMapPrivate<Key, T> * _map );
ConstIterator lowerBound( const Key & _k ) const;
};
template<class Key, class T>
Q_INLINE_TEMPLATES XQMapPrivate<Key, T>::XQMapPrivate( void )
{
}
template<class Key, class T>
Q_INLINE_TEMPLATES XQMapPrivate<Key, T>::XQMapPrivate(
const XQMapPrivate<Key, T> * _map ) :
QMapPrivate<Key, T>( _map )
{
}
template<class Key, class T>
Q_INLINE_TEMPLATES Q_TYPENAME XQMapPrivate<Key, T>::ConstIterator
XQMapPrivate<Key, T>::lowerBound( const Key & _k ) const
{
QMapNodeBase * y = QMapPrivate<Key, T>::header; // Last node
QMapNodeBase * x = QMapPrivate<Key, T>::header->parent; // Root node
while( x != 0 ) {
// If as k <= key(x) go left
if( !( QMapPrivate<Key, T>::key( x ) < _k ) )
{
y = x;
x = x->left;
}
else
{
x = x->right;
}
}
// Was _k bigger then the biggest element of the tree? Return end()
if( y == QMapPrivate<Key, T>::header )
{
return( ConstIterator( QMapPrivate<Key, T>::header ) );
}
return( ConstIterator( (NodePtr)y ) );
}
template<class Key, class T>
class XQMap
{
public:
/**
* Typedefs
*/
typedef Key key_type;
typedef T mapped_type;
typedef QPair<const key_type, mapped_type> value_type;
typedef value_type * pointer;
typedef const value_type * const_pointer;
typedef value_type & reference;
typedef const value_type & const_reference;
#ifndef QT_NO_STL
typedef ptrdiff_t difference_type;
#else
typedef int difference_type;
#endif
typedef size_t size_type;
typedef QMapIterator<Key, T> iterator;
typedef QMapConstIterator<Key, T> const_iterator;
typedef QPair<iterator, bool> insert_pair;
typedef QMapIterator<Key, T> Iterator;
typedef QMapConstIterator<Key, T> ConstIterator;
typedef T ValueType;
typedef XQMapPrivate<Key, T> Priv;
/**
* API
*/
XQMap( void )
{
m_sh = new XQMapPrivate<Key, T>;
}
XQMap( const XQMap<Key, T> & _m )
{
m_sh = _m.m_sh;
m_sh->ref();
}
#ifndef QT_NO_STL
XQMap( const std::map<Key, T> & _m )
{
m_sh = new XQMapPrivate<Key, T>;
Q_TYPENAME std::map<Key, T>::const_iterator it = _m.begin();
for( ; it != _m.end(); ++it )
{
value_type p( ( *it ).first, ( *it ).second );
insert( p );
}
}
#endif
~XQMap()
{
if( m_sh->deref() )
{
delete m_sh;
}
}
XQMap<Key, T> & operator=( const XQMap<Key, T> & _m );
#ifndef QT_NO_STL
XQMap<Key, T> & operator=( const std::map<Key, T> & _m )
{
clear();
Q_TYPENAME std::map<Key, T>::const_iterator it = _m.begin();
for( ; it != _m.end(); ++it )
{
value_type p( ( *it ).first, ( *it ).second );
insert( p );
}
return( *this );
}
#endif
iterator begin( void )
{
detach();
return( m_sh->begin() );
}
iterator end( void )
{
detach();
return( m_sh->end() );
}
const_iterator begin( void ) const
{
return( ( (const Priv *)m_sh )->begin() );
}
const_iterator end( void ) const
{
return( ( (const Priv *)m_sh )->end() );
}
const_iterator constBegin( void ) const
{
return( begin() );
}
const_iterator constEnd( void ) const
{
return( end() );
}
iterator replace( const Key & _k, const T & _v )
{
remove( _k );
return( insert( _k, _v ) );
}
size_type size( void ) const
{
return( m_sh->node_count );
}
bool empty( void ) const
{
return( m_sh->node_count == 0 );
}
QPair<iterator, bool> insert( const value_type & _x );
void erase( iterator _it )
{
detach();
m_sh->remove( _it );
}
void erase( const key_type & _k );
size_type count( const key_type & _k ) const;
T & operator[]( const Key & _k );
void clear( void );
iterator find( const Key & _k )
{
detach();
return( iterator( m_sh->find( _k ).node ) );
}
iterator lowerBound( const Key & _k )
{
detach();
return( iterator( m_sh->lowerBound( _k ).node ) );
}
const_iterator find( const Key & _k ) const
{
return( m_sh->find( _k ) );
}
const_iterator lowerBound( const Key & _k ) const
{
return( m_sh->lowerBound( _k ) );
}
const T & operator[]( const Key & _k ) const
{
QT_CHECK_INVALID_MAP_ELEMENT;
return( m_sh->find( _k ).data() );
}
bool contains( const Key & _k ) const
{
return( find( _k ) != end() );
}
size_type count( void ) const
{
return( m_sh->node_count );
}
QValueList<Key> keys( void ) const
{
QValueList<Key> r;
for( const_iterator i = begin(); i != end(); ++i )
{
r.append( i.key() );
}
return( r );
}
QValueList<T> values( void ) const
{
QValueList<T> r;
for( const_iterator i = begin(); i != end(); ++i )
r.append( *i );
return( r );
}
bool isEmpty( void ) const
{
return( m_sh->node_count == 0 );
}
iterator insert( const Key & _key, const T & _value,
bool _overwrite = TRUE );
void remove( iterator _it )
{
detach();
m_sh->remove( _it );
}
void remove( const Key & _k );
#if defined( Q_FULL_TEMPLATE_INSTANTIATION )
bool operator==( const XQMap<Key, T> & ) const
{
return( FALSE );
}
#ifndef QT_NO_STL
bool operator==( const std::map<Key, T> & ) const
{
return( FALSE );
}
#endif
#endif
protected:
/**
* Helpers
*/
void detach( void )
{
if( m_sh->count > 1 )
{
detachInternal();
}
}
Priv * m_sh;
private:
void detachInternal( void );
friend class QDeepCopy< XQMap<Key, T> >;
} ;
template<class Key, class T>
Q_INLINE_TEMPLATES XQMap<Key, T> & XQMap<Key, T>::operator=(
const XQMap<Key, T> & _m )
{
_m.m_sh->ref();
if( m_sh->deref() )
{
delete m_sh;
}
m_sh = _m.m_sh;
return( *this );
}
template<class Key, class T>
Q_INLINE_TEMPLATES Q_TYPENAME XQMap<Key, T>::insert_pair
XQMap<Key, T>::insert( const Q_TYPENAME XQMap<Key, T>::value_type & _x )
{
detach();
size_type n = size();
iterator it = m_sh->insertSingle( _x.first );
bool inserted = FALSE;
if( n < size() )
{
inserted = TRUE;
it.data() = _x.second;
}
return( QPair<iterator, bool>( it, inserted ) );
}
template<class Key, class T>
Q_INLINE_TEMPLATES void XQMap<Key, T>::erase( const Key & _k )
{
detach();
iterator it( m_sh->find( _k ).node );
if( it != end() )
{
m_sh->remove( it );
}
}
template<class Key, class T>
Q_INLINE_TEMPLATES Q_TYPENAME XQMap<Key, T>::size_type
XQMap<Key, T>::count( const Key & _k ) const
{
const_iterator it( m_sh->find( _k ).node );
if( it != end() )
{
size_type c = 0;
while( it != end() )
{
++it;
++c;
}
return( c );
}
return( 0 );
}
template<class Key, class T>
Q_INLINE_TEMPLATES T & XQMap<Key, T>::operator[]( const Key & _k )
{
detach();
QMapNode<Key, T> * p = m_sh->find( _k ).node;
if( p != m_sh->end().node )
{
return( p->data );
}
return( insert( _k, T() ).data() );
}
template<class Key, class T>
Q_INLINE_TEMPLATES void XQMap<Key, T>::clear( void )
{
if( m_sh->count == 1 )
{
m_sh->clear();
}
else
{
m_sh->deref();
m_sh = new XQMapPrivate<Key, T>;
}
}
template<class Key, class T>
Q_INLINE_TEMPLATES Q_TYPENAME XQMap<Key, T>::iterator XQMap<Key, T>::insert(
const Key & _key, const T & _value, bool _overwrite )
{
detach();
size_type n = size();
iterator it = m_sh->insertSingle( _key );
if( _overwrite || n < size() )
{
it.data() = _value;
}
return( it );
}
template<class Key, class T>
Q_INLINE_TEMPLATES void XQMap<Key, T>::remove( const Key & _k )
{
detach();
iterator it( m_sh->find( _k ).node );
if( it != end() )
{
m_sh->remove( it );
}
}
template<class Key, class T>
Q_INLINE_TEMPLATES void XQMap<Key, T>::detachInternal( void )
{
m_sh->deref();
m_sh = new XQMapPrivate<Key, T>( m_sh );
}
#ifndef QT_NO_DATASTREAM
template<class Key, class T>
Q_INLINE_TEMPLATES QDataStream & operator>>( QDataStream & _s,
XQMap<Key, T> & _m )
{
_m.clear();
Q_UINT32 c;
_s >> c;
for( Q_UINT32 i = 0; i < c; ++i )
{
Key k;
T t;
_s >> k >> t;
_m.insert( k, t );
if( _s.atEnd() )
{
break;
}
}
return( _s );
}
template<class Key, class T>
Q_INLINE_TEMPLATES QDataStream & operator<<( QDataStream & _s,
const XQMap<Key, T> & _m )
{
_s << (Q_UINT32)_m.size();
QMapConstIterator<Key, T> it = _m.begin();
for( ; it != _m.end(); ++it )
{
_s << it.key() << it.data();
}
return( _s );
}
#endif
#endif

View File

@@ -79,7 +79,7 @@ audioALSA::audioALSA( const sample_rate_t _sample_rate, bool & _success_ful,
probeDevice().ascii(),
#endif
SND_PCM_STREAM_PLAYBACK,
SND_PCM_NONBLOCK ) ) < 0 )
0 ) ) < 0 )
{
printf( "Playback open error: %s\n", snd_strerror( err ) );
return;
@@ -221,25 +221,47 @@ void audioALSA::run( void )
int_sample_t * outbuf = bufferAllocator::alloc<int_sample_t>(
getMixer()->framesPerAudioBuffer() *
channels() );
int_sample_t * pcmbuf = bufferAllocator::alloc<int_sample_t>(
m_periodSize * channels() );
m_quit = FALSE;
int outbuf_size = getMixer()->framesPerAudioBuffer() * channels();
int outbuf_pos = 0;
int pcmbuf_size = m_periodSize * channels();
while( m_quit == FALSE )
{
const f_cnt_t frames = getNextBuffer( temp );
int_sample_t * ptr = pcmbuf;
int len = pcmbuf_size;
while( len )
{
if( outbuf_pos == 0 )
{
const fpab_t frames = getNextBuffer( temp );
convertToS16( temp, frames, getMixer()->masterGain(), outbuf,
m_convertEndian );
convertToS16( temp, frames,
getMixer()->masterGain(),
outbuf,
m_convertEndian );
}
int min_len = tMin( len, outbuf_size - outbuf_pos );
memcpy( ptr, outbuf + outbuf_pos,
min_len * sizeof( int_sample_t ) );
ptr += min_len;
len -= min_len;
outbuf_pos += min_len;
outbuf_pos %= outbuf_size;
}
f_cnt_t frame = 0;
int_sample_t * ptr = outbuf;
f_cnt_t frames = m_periodSize;
ptr = pcmbuf;
while( frame < frames )
while( frames )
{
int err = snd_pcm_writei( m_handle, ptr, frames );
if( err == -EAGAIN )
{
usleep( 10 );
continue;
}
@@ -253,12 +275,13 @@ void audioALSA::run( void )
break; // skip this buffer
}
ptr += err * channels();
frame += err;
frames -= err;
}
}
bufferAllocator::free( temp );
bufferAllocator::free( outbuf );
bufferAllocator::free( pcmbuf );
}

View File

@@ -476,6 +476,7 @@ void arpAndChordsTabWidget::processNote( notePlayHandle * _n )
_n->getInstrumentTrack(),
_n->framesAhead(),
_n->frames(), note_copy );
note_play_handle->setBBTrackFrom( _n );
// add sub-note to base-note, now all stuff is
// done by notePlayHandle::play_note()
_n->addSubNote( note_play_handle );
@@ -638,6 +639,7 @@ void arpAndChordsTabWidget::processNote( notePlayHandle * _n )
gated_frames,
new_note,
TRUE );
note_play_handle->setBBTrackFrom( _n );
// add sub-note to base-note - now all stuff is done by
// notePlayHandle::playNote()

View File

@@ -89,7 +89,6 @@ automationEditor::automationEditor( engine * _engine ) :
QWidget( _engine->getMainWindow()->workspace() ),
journallingObject( _engine ),
m_paintPixmap(),
m_cursorInside( FALSE ),
m_pattern( NULL ),
m_min_level( 0 ),
m_max_level( 0 ),
@@ -678,10 +677,10 @@ void automationEditor::updatePaintPixmap( void )
if( validPattern() == TRUE )
{
timeMap & time_map = m_pattern->getTimeMap();
for( timeMap::iterator it = time_map.begin(), it_next;
it != time_map.end(); ++it )
timeMap::iterator it = time_map.end();
do
{
--it;
Sint32 len_tact_64th = 4;
#ifdef QT3
@@ -690,36 +689,35 @@ void automationEditor::updatePaintPixmap( void )
const int level = it.value();
#endif
Sint32 pos_tact_64th = it.key();
Sint32 pos_tact_64th = -it.key();
const int x = ( pos_tact_64th - m_currentPosition ) *
m_ppt / 64;
it_next = it;
++it_next;
int next_x;
int rect_width;
if( it_next != time_map.end() )
if( x > width() - VALUES_WIDTH )
{
Sint32 next_pos_tact_64th = it_next.key();
next_x = ( next_pos_tact_64th
break;
}
int rect_width;
if( it != time_map.begin() )
{
timeMap::iterator it_prev = it;
--it_prev;
Sint32 next_pos_tact_64th = -it_prev.key();
int next_x = ( next_pos_tact_64th
- m_currentPosition ) * m_ppt / 64;
// skip this value if not in visible area at all
if( next_x < 0 )
{
continue;
}
rect_width = next_x - x;
}
else
{
next_x = -1;
rect_width = width() - x;
}
// skip this value if not in visible area at all
if( !xVisible( x ) && !xVisible( next_x )
&& it_next != time_map.end() )
{
continue;
}
// is the value in visible area?
if( ( level >= m_bottom_level && level <= m_top_level )
|| ( level > m_top_level && m_top_level >= 0 )
@@ -776,7 +774,7 @@ void automationEditor::updatePaintPixmap( void )
rect_width, rect_height,
is_selected );
}
}
} while( it != time_map.begin() );
}
else
{
@@ -852,15 +850,6 @@ void automationEditor::closeEvent( QCloseEvent * _ce )
void automationEditor::enterEvent( QEvent * _e )
{
m_cursorInside = TRUE;
QWidget::enterEvent( _e );
}
void automationEditor::keyPressEvent( QKeyEvent * _ke )
{
switch( _ke->key() )
@@ -1018,7 +1007,6 @@ void automationEditor::leaveEvent( QEvent * _e )
{
QApplication::restoreOverrideCursor();
}
m_cursorInside = FALSE;
QWidget::leaveEvent( _e );
}
@@ -1062,9 +1050,9 @@ void automationEditor::mousePressEvent( QMouseEvent * _me )
// and check whether the user clicked on an
// existing value
if( pos_tact_64th >= it.key() &&
if( pos_tact_64th >= -it.key() &&
len > 0 &&
pos_tact_64th <= it.key() + len &&
pos_tact_64th <= -it.key() + len &&
#ifdef QT3
it.data() == level )
#else
@@ -1094,18 +1082,13 @@ void automationEditor::mousePressEvent( QMouseEvent * _me )
// reset it so that it can be used for
// ops (move, resize) after this
// code-block
it = time_map.begin();
while( it != time_map.end() &&
it.key() != new_time )
{
++it;
}
it = time_map.find( -new_time );
}
// move it
m_action = MOVE_VALUE;
int aligned_x = (int)( (float)( (
it.key() -
-it.key() -
m_currentPosition ) *
m_ppt ) / 64.0f );
m_moveXOffset = x - aligned_x - 1;
@@ -1123,7 +1106,7 @@ void automationEditor::mousePressEvent( QMouseEvent * _me )
if( it != time_map.end() )
{
m_pattern->removeValue( it.key() );
m_pattern->removeValue( -it.key() );
eng()->getSongEditor()->setModified();
}
}
@@ -1268,8 +1251,8 @@ void automationEditor::mouseMoveEvent( QMouseEvent * _me )
{
// and check whether the cursor is over an
// existing value
if( pos_tact_64th >= it.key() &&
pos_tact_64th <= it.key() +
if( pos_tact_64th >= -it.key() &&
pos_tact_64th <= -it.key() +
//TODO: Add constant
4 &&
#ifdef QT3
@@ -1456,31 +1439,27 @@ void automationEditor::mouseMoveEvent( QMouseEvent * _me )
for( timeMap::iterator it = m_selValuesForMove.begin();
it != m_selValuesForMove.end(); ++it )
{
int value_tact = it.key().getTact() + tact_diff;
int value_tact_64th = it.key().getTact64th() +
int value_tact = ( -it.key() >> 6 ) + tact_diff;
int value_tact_64th = ( -it.key() & 63 ) +
tact_64th_diff;
while( value_tact_64th < 0 )
// ensure value_tact_64th range
if( value_tact_64th >> 6 )
{
--value_tact;
value_tact_64th += 64;
value_tact += value_tact_64th >> 6;
value_tact_64th &= 63;
}
while( value_tact_64th > 64 )
{
++value_tact;
value_tact_64th -= 64;
}
m_pattern->removeValue( it.key() );
m_pattern->removeValue( -it.key() );
midiTime new_value_pos( value_tact,
value_tact_64th );
#ifdef QT3
new_selValuesForMove[
m_pattern->putValue( new_value_pos,
-m_pattern->putValue( new_value_pos,
it.data () + level_diff,
FALSE )]
= it.data() + level_diff;
#else
new_selValuesForMove[
m_pattern->putValue( new_value_pos,
-m_pattern->putValue( new_value_pos,
it.value () + level_diff,
FALSE )]
= it.value() + level_diff;
@@ -1590,31 +1569,26 @@ void automationEditor::paintEvent( QPaintEvent * )
#endif
p.drawPixmap( 0, 0, m_paintPixmap );
if( m_cursorInside == TRUE )
{
p.setClipRect( VALUES_WIDTH, TOP_MARGIN, width() - VALUES_WIDTH,
p.setClipRect( VALUES_WIDTH, TOP_MARGIN, width() - VALUES_WIDTH,
height() - TOP_MARGIN - SCROLLBAR_SIZE );
if( validPattern() == TRUE )
{
//TODO: What's this?
p.fillRect( 10, height() + 3 - SCROLLBAR_SIZE,
width() - 10, DEFAULT_Y_DELTA - 7,
QColor( 64, 64, 64 ) );
}
const QPixmap * cursor = NULL;
// draw current edit-mode-icon below the cursor
switch( m_editMode )
{
case DRAW: cursor = s_toolDraw; break;
case ERASE: cursor = s_toolErase; break;
case SELECT: cursor = s_toolSelect; break;
case MOVE: cursor = s_toolMove; break;
}
p.drawPixmap( mapFromGlobal( QCursor::pos() ) + QPoint( 8, 8 ),
*cursor );
if( validPattern() == TRUE )
{
drawCross( p );
}
const QPixmap * cursor = NULL;
// draw current edit-mode-icon below the cursor
switch( m_editMode )
{
case DRAW: cursor = s_toolDraw; break;
case ERASE: cursor = s_toolErase; break;
case SELECT: cursor = s_toolSelect; break;
case MOVE: cursor = s_toolMove; break;
}
p.drawPixmap( mapFromGlobal( QCursor::pos() ) + QPoint( 8, 8 ),
*cursor );
#ifndef QT4
// and blit all the drawn stuff on the screen...
bitBlt( this, rect().topLeft(), &draw_pm );
@@ -1624,6 +1598,26 @@ void automationEditor::paintEvent( QPaintEvent * )
inline void automationEditor::drawCross( QPainter & _p )
{
QPoint mouse_pos = mapFromGlobal( QCursor::pos() );
int level = getLevel( mouse_pos.y() );
int grid_bottom = height() - SCROLLBAR_SIZE - 1;
int cross_y = m_y_auto ?
grid_bottom - (int)roundf( ( grid_bottom - TOP_MARGIN )
* ( level - m_min_level )
/ (float)( m_max_level - m_min_level ) ) :
grid_bottom - ( level - m_bottom_level ) * m_y_delta;
_p.setPen( QColor( 0xFF, 0x33, 0x33 ) );
_p.drawLine( VALUES_WIDTH, cross_y, width(), cross_y );
_p.drawLine( mouse_pos.x(), TOP_MARGIN, mouse_pos.x(),
height() - SCROLLBAR_SIZE );
}
// responsible for moving/resizing scrollbars after window-resizing
void automationEditor::resizeEvent( QResizeEvent * )
{
@@ -1919,7 +1913,7 @@ void automationEditor::selectAll( void )
const int level = it.value();
#endif
Uint32 pos_tact_64th = it.key();
Uint32 pos_tact_64th = -it.key();
if( level <= m_selectStartLevel || first_time )
{
// if we move start-level down, we have to add
@@ -1988,7 +1982,7 @@ void automationEditor::getSelectedValues( timeMap & _selected_values )
#else
int level = it.value();
#endif
Sint32 pos_tact_64th = it.key();
Sint32 pos_tact_64th = -it.key();
if( level > sel_level_start && level <= sel_level_end &&
pos_tact_64th >= sel_pos_start &&
@@ -2011,8 +2005,6 @@ void automationEditor::copySelectedValues( void )
if( !selected_values.isEmpty() )
{
midiTime start_pos( selected_values.begin().key().getTact(),
0 );
for( timeMap::iterator it = selected_values.begin();
it != selected_values.end(); ++it )
{
@@ -2048,9 +2040,6 @@ void automationEditor::cutSelectedValues( void )
{
eng()->getSongEditor()->setModified();
midiTime start_pos( selected_values.begin().key().getTact(),
0 );
for( timeMap::iterator it = selected_values.begin();
it != selected_values.end(); ++it )
{
@@ -2059,7 +2048,7 @@ void automationEditor::cutSelectedValues( void )
#else
m_valuesToCopy[it.key()] = it.value();
#endif
m_pattern->removeValue( it.key() );
m_pattern->removeValue( -it.key() );
}
}
@@ -2082,7 +2071,7 @@ void automationEditor::pasteValues( void )
for( timeMap::iterator it = m_valuesToCopy.begin();
it != m_valuesToCopy.end(); ++it )
{
m_pattern->putValue( it.key() + m_currentPosition,
m_pattern->putValue( -it.key() + m_currentPosition,
#ifdef QT3
it.data() );
#else
@@ -2116,7 +2105,7 @@ void automationEditor::deleteSelectedValues( void )
for( timeMap::iterator it = selected_values.begin();
it != selected_values.end(); ++it )
{
m_pattern->removeValue( it.key() );
m_pattern->removeValue( -it.key() );
}
if( update_after_delete == TRUE )
@@ -2241,18 +2230,23 @@ void automationEditor::updateTopBottomLevels( void )
inline bool automationEditor::xVisible( int _x )
inline bool automationEditor::inBBEditor( void )
{
return( _x >= 0 && _x <= width() - VALUES_WIDTH );
return( m_pattern->getTrack()->getTrackContainer()
== eng()->getBBEditor() );
}
inline bool automationEditor::inBBEditor( void )
void automationEditor::update( void )
{
return( m_pattern->getTrack()->getTrackContainer()
== eng()->getBBEditor() );
QWidget::update();
// Note detuning?
if( m_pattern && !m_pattern->getTrack() )
{
eng()->getPianoRoll()->update();
}
}

View File

@@ -462,6 +462,11 @@ void bbEditor::updateAfterTrackAdd( void )
void bbEditor::createTCOsForBB( csize _bb )
{
if( numOfBBs() == 0 )
{
return;
}
trackVector tv = tracks();
for( trackVector::iterator it = tv.begin(); it != tv.end(); ++it )
{

View File

@@ -83,16 +83,22 @@ void nameLabel::setPixmap( const QPixmap & _pixmap )
void nameLabel::setPixmapFile( const QString & _file )
{
m_pixmapFile = _file;
if( QFileInfo( m_pixmapFile ).isRelative() )
QPixmap new_pixmap;
if( QFileInfo( _file ).isRelative() )
{
m_pixmap = QPixmap( configManager::inst()->trackIconsDir() +
m_pixmapFile );
new_pixmap = QPixmap( configManager::inst()->trackIconsDir() +
_file );
}
else
{
m_pixmap = QPixmap( m_pixmapFile );
new_pixmap = QPixmap( _file );
}
if( new_pixmap.isNull() )
{
return;
}
m_pixmap = new_pixmap;
m_pixmapFile = _file;
emit( pixmapChanged() );
update();
}

View File

@@ -342,4 +342,14 @@ void note::detachCurrentDetuning( void )
bool note::hasDetuningInfo( void )
{
automationPattern::timeMap map =
m_detuning->getAutomationPattern()->getTimeMap();
return( map.size() > 1 || map[0] != 0 );
}
#endif

View File

@@ -79,6 +79,9 @@
#include "piano_widget.h"
typedef automationPattern::timeMap timeMap;
extern tones whiteKeys[]; // defined in piano_widget.cpp
@@ -136,7 +139,6 @@ pianoRoll::pianoRoll( engine * _engine ) :
QWidget( _engine->getMainWindow()->workspace() ),
journallingObject( _engine ),
m_paintPixmap(),
m_cursorInside( FALSE ),
m_pattern( NULL ),
m_currentPosition(),
m_recording( FALSE ),
@@ -148,7 +150,6 @@ pianoRoll::pianoRoll( engine * _engine ) :
m_ppt( DEFAULT_PR_PPT ),
m_lenOfNewNotes( midiTime( 0, 16 ) ),
m_startKey( INITIAL_START_KEY ),
m_keyMouseOver( INITIAL_START_KEY ),
m_lastKey( 0 ),
m_editMode( DRAW ),
m_scrollBack( FALSE )
@@ -870,6 +871,12 @@ void pianoRoll::updatePaintPixmap( void )
int y_base = height() - PR_BOTTOM_MARGIN - m_notesEditHeight - 1;
if( validPattern() == TRUE )
{
QPainter p_detuning( &m_paintPixmap );
p_detuning.setClipRect( WHITE_KEY_WIDTH, PR_TOP_MARGIN,
width() - WHITE_KEY_WIDTH,
height() - PR_TOP_MARGIN - PR_BOTTOM_MARGIN
- m_notesEditHeight );
noteVector & notes = m_pattern->notes();
const int visible_keys = ( height() - PR_TOP_MARGIN -
@@ -946,6 +953,13 @@ void pianoRoll::updatePaintPixmap( void )
( *it )->getVolume() / 2,
x + WHITE_KEY_WIDTH + 1,
height() - PR_BOTTOM_MARGIN );
if( ( *it )->hasDetuningInfo() )
{
drawDetuningInfo( p_detuning, *it,
x + WHITE_KEY_WIDTH,
y_base - key * KEY_LINE_HEIGHT );
}
}
}
else
@@ -987,6 +1001,39 @@ void pianoRoll::updatePaintPixmap( void )
inline void pianoRoll::drawDetuningInfo( QPainter & _p, note * _n, Uint16 _x,
Uint16 _y )
{
Uint16 middle_y = _y + KEY_LINE_HEIGHT / 2;
_p.setPen( QColor( 0xFF, 0xDF, 0x20 ) );
timeMap & map = _n->detuning()->getAutomationPattern()->getTimeMap();
timeMap::iterator it = map.end();
do
{
--it;
Sint32 pos_tact_64th = -it.key();
if( pos_tact_64th > _n->length() )
{
break;
}
Uint16 pos_x = _x + pos_tact_64th * m_ppt / 64;
#ifdef QT3
const int level = it.data();
#else
const int level = it.value();
#endif
Uint16 pos_y = middle_y - level * KEY_LINE_HEIGHT / 10;
_p.drawLine( pos_x - 1, pos_y, pos_x + 1, pos_y );
_p.drawLine( pos_x, pos_y - 1, pos_x, pos_y + 1 );
} while( it != map.begin() );
}
void pianoRoll::removeSelection( void )
{
m_selectStartTact64th = 0;
@@ -1008,15 +1055,6 @@ void pianoRoll::closeEvent( QCloseEvent * _ce )
void pianoRoll::enterEvent( QEvent * _e )
{
m_cursorInside = TRUE;
QWidget::enterEvent( _e );
}
void pianoRoll::keyPressEvent( QKeyEvent * _ke )
{
if( validPattern() )
@@ -1215,7 +1253,6 @@ void pianoRoll::leaveEvent( QEvent * _e )
{
QApplication::restoreOverrideCursor();
}
m_cursorInside = FALSE;
QWidget::leaveEvent( _e );
}
@@ -1455,6 +1492,7 @@ void pianoRoll::mousePressEvent( QMouseEvent * _me )
if( play_note == TRUE && m_recording == FALSE &&
eng()->getSongEditor()->playing() == FALSE )
{
m_lastKey = key_num;
m_pattern->getInstrumentTrack()->processInEvent(
midiEvent( NOTE_ON, 0, key_num,
vol * 127 / 100 ),
@@ -1479,7 +1517,7 @@ void pianoRoll::mouseReleaseEvent( QMouseEvent * _me )
else
{
m_pattern->getInstrumentTrack()->processInEvent(
midiEvent( NOTE_OFF, 0, getKey( _me->y() ), 0 ),
midiEvent( NOTE_OFF, 0, m_lastKey, 0 ),
midiTime() );
}
}
@@ -1505,22 +1543,18 @@ void pianoRoll::mouseMoveEvent( QMouseEvent * _me )
return;
}
// save current last-key-var
int released_key = m_lastKey;
if( _me->y() > PR_TOP_MARGIN )
{
bool edit_note = ( _me->y() > height() -
PR_BOTTOM_MARGIN - m_notesEditHeight );
int key_num = getKey( _me->y() );
m_keyMouseOver = key_num;
int x = _me->x();
// is the calculated key different from current key?
// (could be the user just moved the cursor one pixel up/down
// but is still on the same key)
if( key_num != released_key &&
if( key_num != m_lastKey &&
m_action != CHANGE_NOTE_VOLUME &&
m_action != MOVE_SELECTION &&
edit_note == FALSE &&
@@ -1532,7 +1566,7 @@ void pianoRoll::mouseMoveEvent( QMouseEvent * _me )
Qt::LeftButton )
{
m_pattern->getInstrumentTrack()->processInEvent(
midiEvent( NOTE_OFF, 0, released_key, 0 ),
midiEvent( NOTE_OFF, 0, m_lastKey, 0 ),
midiTime() );
if(
#ifdef QT4
@@ -1547,6 +1581,7 @@ void pianoRoll::mouseMoveEvent( QMouseEvent * _me )
m_recording == FALSE &&
eng()->getSongEditor()->playing() == FALSE )
{
m_lastKey = key_num;
m_pattern->getInstrumentTrack()->processInEvent(
midiEvent( NOTE_ON, 0, key_num,
DEFAULT_VOLUME * 127 / 100 ),
@@ -1886,15 +1921,11 @@ void pianoRoll::mouseMoveEvent( QMouseEvent * _me )
int note_tact_64th =
( *it )->pos().getTact64th() +
tact_64th_diff;
while( note_tact_64th < 0 )
// ensure note_tact_64th range
if( note_tact_64th >> 6 )
{
--note_tact;
note_tact_64th += 64;
}
while( note_tact_64th > 64 )
{
++note_tact;
note_tact_64th -= 64;
note_tact += note_tact_64th >> 6;
note_tact_64th &= 63;
}
midiTime new_note_pos( note_tact,
note_tact_64th );
@@ -2019,34 +2050,32 @@ void pianoRoll::paintEvent( QPaintEvent * )
#endif
p.drawPixmap( 0, 0, m_paintPixmap );
if( m_cursorInside == TRUE )
{
p.setClipRect( WHITE_KEY_WIDTH, PR_TOP_MARGIN, width() -
p.setClipRect( WHITE_KEY_WIDTH, PR_TOP_MARGIN, width() -
WHITE_KEY_WIDTH, height() - PR_TOP_MARGIN -
m_notesEditHeight - PR_BOTTOM_MARGIN );
if( validPattern() == TRUE )
{
p.fillRect( 10, height() + 3 - PR_BOTTOM_MARGIN -
if( validPattern() == TRUE )
{
int key_num = getKey( mapFromGlobal( QCursor::pos() ).y() );
p.fillRect( 10, height() + 3 - PR_BOTTOM_MARGIN -
m_notesEditHeight - KEY_LINE_HEIGHT *
( m_keyMouseOver - m_startKey + 1 ),
( key_num - m_startKey + 1 ),
width() - 10, KEY_LINE_HEIGHT - 7,
QColor( 64, 64, 64 ) );
}
const QPixmap * cursor = NULL;
// draw current edit-mode-icon below the cursor
switch( m_editMode )
{
case DRAW: cursor = s_toolDraw; break;
case ERASE: cursor = s_toolErase; break;
case SELECT: cursor = s_toolSelect; break;
case MOVE: cursor = s_toolMove; break;
case OPEN: cursor = s_toolOpen; break;
}
p.drawPixmap( mapFromGlobal( QCursor::pos() ) + QPoint( 8, 8 ),
*cursor );
}
const QPixmap * cursor = NULL;
// draw current edit-mode-icon below the cursor
switch( m_editMode )
{
case DRAW: cursor = s_toolDraw; break;
case ERASE: cursor = s_toolErase; break;
case SELECT: cursor = s_toolSelect; break;
case MOVE: cursor = s_toolMove; break;
case OPEN: cursor = s_toolOpen; break;
}
p.drawPixmap( mapFromGlobal( QCursor::pos() ) + QPoint( 8, 8 ),
*cursor );
#ifndef QT4
// and blit all the drawn stuff on the screen...
bitBlt( this, rect().topLeft(), &draw_pm );
@@ -2152,7 +2181,7 @@ int pianoRoll::getKey( int _y )
key_num = NOTES_PER_OCTAVE * OCTAVES - 1;
}
return( m_lastKey = key_num );
return( key_num );
}

View File

@@ -205,7 +205,7 @@ setupDialog::setupDialog( engine * _engine, configTabs _tab_to_open ) :
ledCheckBox * disable_tooltips = new ledCheckBox(
tr( "Disable tooltips (no spurious "
"interrupts while playing)" ),
misc_tw, NULL, eng(), NULL );
misc_tw, NULL, NULL, NULL );
disable_tooltips->move( 10, 18 );
disable_tooltips->setChecked( m_disableToolTips );
connect( disable_tooltips, SIGNAL( toggled( bool ) ),
@@ -216,7 +216,7 @@ setupDialog::setupDialog( engine * _engine, configTabs _tab_to_open ) :
tr( "Classical knob usability (move "
"cursor around knob to change "
"value)" ),
misc_tw, NULL, eng(), NULL );
misc_tw, NULL, NULL, NULL );
classical_knob_usability->move( 10, 36 );
classical_knob_usability->setChecked( m_classicalKnobUsability );
connect( classical_knob_usability, SIGNAL( toggled( bool ) ),
@@ -225,7 +225,7 @@ setupDialog::setupDialog( engine * _engine, configTabs _tab_to_open ) :
ledCheckBox * gimp_like_windows = new ledCheckBox(
tr( "GIMP-like windows (no MDI)" ),
misc_tw, NULL, eng(), NULL );
misc_tw, NULL, NULL, NULL );
gimp_like_windows->move( 10, 54 );
gimp_like_windows->setChecked( m_gimpLikeWindows );
connect( gimp_like_windows, SIGNAL( toggled( bool ) ),
@@ -234,7 +234,7 @@ setupDialog::setupDialog( engine * _engine, configTabs _tab_to_open ) :
ledCheckBox * no_wizard = new ledCheckBox(
tr( "Do not show wizard after up-/downgrade" ),
misc_tw, NULL, eng(), NULL );
misc_tw, NULL, NULL, NULL );
no_wizard->move( 10, 72 );
no_wizard->setChecked( m_noWizard );
connect( no_wizard, SIGNAL( toggled( bool ) ),
@@ -244,7 +244,7 @@ setupDialog::setupDialog( engine * _engine, configTabs _tab_to_open ) :
ledCheckBox * no_msg = new ledCheckBox(
tr( "Do not show message after "
"closing this dialog" ),
misc_tw, NULL, eng(), NULL );
misc_tw, NULL, NULL, NULL );
no_msg->move( 10, 90 );
no_msg->setChecked( m_noMsgAfterSetup );
connect( no_msg, SIGNAL( toggled( bool ) ),
@@ -253,7 +253,7 @@ setupDialog::setupDialog( engine * _engine, configTabs _tab_to_open ) :
ledCheckBox * dbv = new ledCheckBox(
tr( "Display volume as dbV " ),
misc_tw, NULL, eng(), NULL );
misc_tw, NULL, NULL, NULL );
dbv->move( 10, 108 );
dbv->setChecked( m_displaydBV );
connect( dbv, SIGNAL( toggled( bool ) ),
@@ -262,7 +262,7 @@ setupDialog::setupDialog( engine * _engine, configTabs _tab_to_open ) :
ledCheckBox * no_mmpz = new ledCheckBox(
tr( "Do not compress project files per default" ),
misc_tw, NULL, eng(), NULL );
misc_tw, NULL, NULL, NULL );
no_mmpz->move( 10, 126 );
no_mmpz->setChecked( m_noMMPZ );
connect( no_mmpz, SIGNAL( toggled( bool ) ),
@@ -436,7 +436,7 @@ setupDialog::setupDialog( engine * _engine, configTabs _tab_to_open ) :
ledCheckBox * disable_ch_act_ind = new ledCheckBox(
tr( "Disable channel activity indicators" ),
ui_fx_tw, NULL, eng(), NULL );
ui_fx_tw, NULL, NULL, NULL );
disable_ch_act_ind->move( 10, 20 );
disable_ch_act_ind->setChecked( m_disableChActInd );
connect( disable_ch_act_ind, SIGNAL( toggled( bool ) ),
@@ -445,7 +445,7 @@ setupDialog::setupDialog( engine * _engine, configTabs _tab_to_open ) :
ledCheckBox * manual_ch_piano = new ledCheckBox(
tr( "Only press keys on channel-piano manually" ),
ui_fx_tw, NULL, eng(), NULL );
ui_fx_tw, NULL, NULL, NULL );
manual_ch_piano->move( 10, 40 );
manual_ch_piano->setChecked( m_manualChPiano );
connect( manual_ch_piano, SIGNAL( toggled( bool ) ),
@@ -460,9 +460,8 @@ setupDialog::setupDialog( engine * _engine, configTabs _tab_to_open ) :
QLabel * par_level_lbl = new QLabel( tr( "Parallelizing level" ),
smp_supp_tw );
par_level_lbl->move( 10, 15 );
lcdSpinBox * par_level = new lcdSpinBox( 1, 16, 2, smp_supp_tw,
tr( "SMP-level" ),
eng(), NULL );
lcdSpinBox * par_level = new lcdSpinBox( 1, 16, 2, smp_supp_tw, NULL,
NULL, NULL );
par_level->setValue( m_parLevel );
connect( par_level, SIGNAL( valueChanged( int ) ),
this, SLOT( setParallelizingLevel( int ) ) );

View File

@@ -145,7 +145,7 @@ midiTime automationPattern::length( void ) const
it != m_time_map.end();
++it )
{
max_length = tMax<Sint32>( max_length, it.key() );
max_length = tMax<Sint32>( max_length, -it.key() );
}
if( max_length % 64 == 0 )
{
@@ -166,7 +166,7 @@ midiTime automationPattern::putValue( const midiTime & _time, const int _value,
eng()->getAutomationEditor()->quantization() ) :
_time;
m_time_map[new_time] = _value;
m_time_map[-new_time] = _value;
return( new_time );
}
@@ -178,7 +178,7 @@ void automationPattern::removeValue( const midiTime & _time )
{
if( _time != 0 )
{
m_time_map.remove( _time );
m_time_map.remove( -_time );
}
}
@@ -199,12 +199,7 @@ void automationPattern::clear( void )
int automationPattern::valueAt( const midiTime & _time )
{
if( m_time_map.contains( _time ) )
{
return( m_time_map[_time] );
}
//TODO: Return a better value!!
return( 0 );
return( m_time_map.lowerBound( -_time ).value() );
}
@@ -216,7 +211,7 @@ void automationPattern::saveSettings( QDomDocument & _doc, QDomElement & _this )
++it )
{
QDomElement element = _doc.createElement( "time" );
element.setAttribute( "pos", static_cast<Sint32>( it.key() ) );
element.setAttribute( "pos", -it.key() );
element.setAttribute( "value", m_object->levelToLabel(
it.value() ) );
_this.appendChild( element );
@@ -238,7 +233,7 @@ void automationPattern::loadSettings( const QDomElement & _this )
{
continue;
}
m_time_map[midiTime( element.attribute( "pos" ).toInt() )]
m_time_map[-element.attribute( "pos" ).toInt()]
= m_object->labelToLevel(
element.attribute( "value" ) );
}
@@ -276,9 +271,9 @@ const QString automationPattern::name( void )
void automationPattern::processMidiTime( const midiTime & _time )
{
timeMap::iterator it = m_time_map.find( _time );
if( it != m_time_map.end() )
if( _time >= 0 )
{
timeMap::iterator it = m_time_map.lowerBound( -_time );
m_object->setLevel( it.value() );
}
}

View File

@@ -919,7 +919,7 @@ bool FASTCALL instrumentTrack::play( const midiTime & _start,
trackContentObject * tco = getTCO( _tco_num );
tcos.push_back( tco );
bb_track = bbTrack::findBBTrack( _tco_num, eng() );
if( bb_track != NULL && !( bb_track->automationDisabled( this )
if( !( bb_track->automationDisabled( this )
|| dynamic_cast<pattern *>( tco )->empty() ) )
{
sendMidiTime( _start );

View File

@@ -432,8 +432,7 @@ void knob::mousePressEvent( QMouseEvent * _me )
eng()->getMainWindow()->isCtrlPressed() == FALSE &&
eng()->getMainWindow()->isShiftPressed() == FALSE )
{
setJournalling( FALSE );
m_oldValue = value();
prepareJournalEntryFromOldVal();
const QPoint & p = _me->pos();
m_origMousePos = p;
@@ -509,7 +508,6 @@ void knob::mouseMoveEvent( QMouseEvent * _me )
//! Mouse Release Event handler
void knob::mouseReleaseEvent( QMouseEvent * /* _me*/ )
{
setJournalling( TRUE );
addJournalEntryFromOldToCurVal();
if( m_buttonPressed )

View File

@@ -219,7 +219,7 @@ void lcdSpinBox::mousePressEvent( QMouseEvent * _me )
{
m_origMousePos = _me->globalPos();
QApplication::setOverrideCursor( Qt::BlankCursor );
m_oldValue = value();
prepareJournalEntryFromOldVal();
}
}

View File

@@ -316,8 +316,6 @@ void tempoSyncKnob::calculateTempoSyncTime( bpm_t _bpm )
"/" +
QString::number( m_custom->getDenominator() ) +
")";
m_tempoSyncIcon = embed::getIconPixmap(
"dont_know" );
conversionFactor =
static_cast<float>( m_custom->getDenominator() ) /
static_cast<float>( m_custom->getNumerator() );
@@ -325,73 +323,101 @@ void tempoSyncKnob::calculateTempoSyncTime( bpm_t _bpm )
case DOUBLE_WHOLE_NOTE:
m_tempoSyncDescription = tr(
"Synced to Eight Beats" );
m_tempoSyncIcon = embed::getIconPixmap(
"note_double_whole" );
conversionFactor = 0.125;
break;
case WHOLE_NOTE:
m_tempoSyncDescription = tr(
"Synced to Whole Note" );
m_tempoSyncIcon = embed::getIconPixmap(
"note_whole" );
conversionFactor = 0.25;
break;
case HALF_NOTE:
m_tempoSyncDescription = tr(
"Synced to Half Note" );
m_tempoSyncIcon = embed::getIconPixmap(
"note_half" );
conversionFactor = 0.5;
break;
case QUARTER_NOTE:
m_tempoSyncDescription = tr(
"Synced to Quarter Note" );
m_tempoSyncIcon = embed::getIconPixmap(
"note_quarter" );
conversionFactor = 1.0;
break;
case EIGHTH_NOTE:
m_tempoSyncDescription = tr(
"Synced to 8th Note" );
m_tempoSyncIcon = embed::getIconPixmap(
"note_eighth" );
conversionFactor = 2.0;
break;
case SIXTEENTH_NOTE:
m_tempoSyncDescription = tr(
"Synced to 16th Note" );
m_tempoSyncIcon = embed::getIconPixmap(
"note_sixteenth" );
conversionFactor = 4.0;
break;
case THIRTYSECOND_NOTE:
m_tempoSyncDescription = tr(
"Synced to 32nd Note" );
conversionFactor = 8.0;
break;
default: ;
}
bool journalling = testAndSetJournalling( FALSE );
setValue( 60000.0 / ( _bpm * conversionFactor * m_scale ) );
setJournalling( journalling );
}
else
{
m_tempoSyncDescription = tr( "Tempo Sync" );
}
if( m_tempoSyncMode != m_tempoLastSyncMode )
{
switch( m_tempoSyncMode )
{
case NO_SYNC:
m_tempoSyncIcon = embed::getIconPixmap(
"tempo_sync" );
break;
case CUSTOM:
m_tempoSyncIcon = embed::getIconPixmap(
"dont_know" );
break;
case DOUBLE_WHOLE_NOTE:
m_tempoSyncIcon = embed::getIconPixmap(
"note_double_whole" );
break;
case WHOLE_NOTE:
m_tempoSyncIcon = embed::getIconPixmap(
"note_whole" );
break;
case HALF_NOTE:
m_tempoSyncIcon = embed::getIconPixmap(
"note_half" );
break;
case QUARTER_NOTE:
m_tempoSyncIcon = embed::getIconPixmap(
"note_quarter" );
break;
case EIGHTH_NOTE:
m_tempoSyncIcon = embed::getIconPixmap(
"note_eighth" );
break;
case SIXTEENTH_NOTE:
m_tempoSyncIcon = embed::getIconPixmap(
"note_sixteenth" );
break;
case THIRTYSECOND_NOTE:
m_tempoSyncIcon = embed::getIconPixmap(
"note_thirtysecond" );
conversionFactor = 8.0;
break;
default:
printf( "tempoSyncKnob::calculateTempoSyncTime"
": invalid tempoSyncMode" );
break;
}
setValue( 60000.0 / ( _bpm * conversionFactor * m_scale ) );
}
else
{
m_tempoSyncDescription = tr( "Tempo Sync" );
m_tempoSyncIcon = embed::getIconPixmap( "tempo_sync" );
}
if( m_tempoSyncMode != m_tempoLastSyncMode )
{
emit syncModeChanged( m_tempoSyncMode );
emit syncDescriptionChanged( m_tempoSyncDescription );
emit syncIconChanged();
m_tempoLastSyncMode = m_tempoSyncMode;
}
m_tempoLastSyncMode = m_tempoSyncMode;
}

View File

@@ -70,8 +70,7 @@ void volumeKnob::mousePressEvent( QMouseEvent * _me )
if( _me->button() == Qt::LeftButton &&
eng()->getMainWindow()->isCtrlPressed() == FALSE )
{
setJournalling( FALSE );
m_oldValue = value();
prepareJournalEntryFromOldVal();
const QPoint & p = _me->pos();
m_origMousePos = p;