optimized piano roll and automation editor paint events

git-svn-id: https://lmms.svn.sf.net/svnroot/lmms/trunk/lmms@620 0778d3d1-df1d-0410-868b-ea421aaaa00d
This commit is contained in:
Javier Serrano Polo
2007-12-11 02:32:19 +00:00
parent d3c33b9bd6
commit 1c8f58e765
8 changed files with 700 additions and 702 deletions

View File

@@ -1,3 +1,19 @@
2007-12-11 Javier Serrano Polo <jasp00/at/terra/dot/es>
* include/automation_editor.h:
* include/piano_roll.h:
* src/core/automation_editor.cpp:
* src/core/piano_roll.cpp:
optimized paint events
* data/themes/default/style.css:
* src/core/automation_editor.cpp:
* src/core/piano_roll.cpp:
use styled background
* src/core/track_container.cpp:
update display after loading settings
2007-12-07 Javier Serrano Polo <jasp00/at/terra/dot/es>
* include/main_window.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.4.0-svn20071207, lmms-devel/at/lists/dot/sf/dot/net)
AM_INIT_AUTOMAKE(lmms, 0.4.0-svn20071207)
AC_INIT(lmms, 0.4.0-svn20071211, lmms-devel/at/lists/dot/sf/dot/net)
AM_INIT_AUTOMAKE(lmms, 0.4.0-svn20071211)
AM_CONFIG_HEADER(config.h)

View File

@@ -4,12 +4,20 @@ QMdiArea {
background-image: url(resources:background_artwork.png);
}
automationEditor {
background-color: rgb(0, 0, 0);
}
captionMenu::item:disabled {
color: white;
background-color: rgb(0, 0, 192);
text-align: center;
}
pianoRoll {
background-color: rgb(0, 0, 0);
}
trackOperationsWidget > QPushButton {
max-height: 26px;
max-width: 26px;

View File

@@ -190,7 +190,6 @@ private:
int m_bottom_level;
int m_top_level;
void updatePaintPixmap( QPixmap & _p );
void updateTopBottomLevels( void );
QScrollBar * m_leftRightScroll;

View File

@@ -164,8 +164,6 @@ private:
midiTime newNoteLen( void ) const;
void updatePaintPixmap( QPixmap & _p );
static QPixmap * s_whiteKeyBigPm;
static QPixmap * s_whiteKeySmallPm;

View File

@@ -29,16 +29,16 @@
#include "automation_editor.h"
#include <Qt/QtXml>
#include <QtGui/QApplication>
#include <QtGui/QButtonGroup>
#include <QtGui/QKeyEvent>
#include <QtGui/QLabel>
#include <QtGui/QLayout>
#include <QtGui/QMdiArea>
#include <QtGui/QPainter>
#include <QtGui/QScrollBar>
#include <QtGui/QStyleOption>
#include <QtGui/QWheelEvent>
#include <QtGui/QMdiArea>
#ifndef __USE_XOPEN
@@ -161,9 +161,13 @@ automationEditor::automationEditor( void ) :
// init scrollbars
m_leftRightScroll = new QScrollBar( Qt::Horizontal, this );
m_topBottomScroll = new QScrollBar( Qt::Vertical, this );
m_leftRightScroll->setSingleStep( 1 );
connect( m_leftRightScroll, SIGNAL( valueChanged( int ) ), this,
SLOT( horScrolled( int ) ) );
m_topBottomScroll = new QScrollBar( Qt::Vertical, this );
m_topBottomScroll->setSingleStep( 1 );
m_topBottomScroll->setPageStep( 20 );
connect( m_topBottomScroll, SIGNAL( valueChanged( int ) ), this,
SLOT( verScrolled( int ) ) );
@@ -439,321 +443,6 @@ inline void automationEditor::drawValueRect( QPainter & _p,
void automationEditor::updatePaintPixmap( QPixmap & _p )
{
_p.fill( QColor( 0, 0, 0 ) );
QPainter p( &_p );
// set font-size to 8
p.setFont( pointSize<8>( p.font() ) );
int grid_height = height() - TOP_MARGIN - SCROLLBAR_SIZE;
// start drawing at the bottom
int grid_bottom = height() - SCROLLBAR_SIZE - 1;
p.fillRect( 0, TOP_MARGIN, VALUES_WIDTH, height() - TOP_MARGIN,
QColor( 0x33, 0x33, 0x33 ) );
// print value numbers
int font_height = p.fontMetrics().height();
Qt::Alignment text_flags =
(Qt::Alignment)( Qt::AlignRight | Qt::AlignVCenter );
if( m_pattern )
{
if( m_y_auto )
{
int y[] = { grid_bottom, TOP_MARGIN + font_height / 2 };
int level[] = { m_min_level, m_max_level };
for( int i = 0; i < 2; ++i )
{
const QString & label = m_pattern->object()
->levelToLabel( level[i] );
p.setPen( QColor( 240, 240, 240 ) );
p.drawText( 1, y[i] - font_height + 1,
VALUES_WIDTH - 10, 2 * font_height,
text_flags, label );
p.setPen( QColor( 0, 0, 0 ) );
p.drawText( 0, y[i] - font_height,
VALUES_WIDTH - 10, 2 * font_height,
text_flags, label );
}
}
else
{
int y = grid_bottom;
int level = m_bottom_level;
int printable = tMax( 1, 5 * DEFAULT_Y_DELTA
/ m_y_delta );
int module = level % printable;
if( module )
{
int inv_module = ( printable - module )
% printable;
y -= inv_module * m_y_delta;
level += inv_module;
}
for( ; y >= TOP_MARGIN && level <= m_top_level;
y -= printable * m_y_delta, level += printable )
{
const QString & label = m_pattern->object()
->levelToLabel( level );
p.setPen( QColor( 240, 240, 240 ) );
p.drawText( 1, y - font_height + 1,
VALUES_WIDTH - 10, 2 * font_height,
text_flags, label );
p.setPen( QColor( 0, 0, 0 ) );
p.drawText( 0, y - font_height,
VALUES_WIDTH - 10, 2 * font_height,
text_flags, label );
}
}
}
// set clipping area, because we are not allowed to paint over
// keyboard...
p.setClipRect( VALUES_WIDTH, TOP_MARGIN, width() - VALUES_WIDTH,
grid_height );
// draw vertical raster
int tact_16th = m_currentPosition / 4;
const int offset = ( m_currentPosition % 4 ) * m_ppt /
DEFAULT_STEPS_PER_TACT / 4;
if( m_pattern )
{
int x_line_end = m_y_auto || m_top_level < m_max_level ?
TOP_MARGIN :
grid_bottom - ( m_top_level - m_bottom_level )
* m_y_delta;
for( int x = VALUES_WIDTH - offset; x < width();
x += m_ppt / DEFAULT_STEPS_PER_TACT, ++tact_16th )
{
if( x >= VALUES_WIDTH )
{
// every tact-start needs to be a bright line
if( tact_16th % 16 == 0 )
{
p.setPen( QColor( 0x7F, 0x7F, 0x7F ) );
}
// normal line
else if( tact_16th % 4 == 0 )
{
p.setPen( QColor( 0x5F, 0x5F, 0x5F ) );
}
// weak line
else
{
p.setPen( QColor( 0x3F, 0x3F, 0x3F ) );
}
p.drawLine( x, grid_bottom, x, x_line_end );
}
}
if( m_y_auto )
{
QPen pen( QColor( 0x4F, 0x4F, 0x4F ) );
p.setPen( pen );
p.drawLine( VALUES_WIDTH, grid_bottom, width(),
grid_bottom );
pen.setStyle( Qt::DotLine );
p.setPen( pen );
float y_delta = ( grid_bottom - TOP_MARGIN ) / 8.0f;
for( int i = 1; i < 8; ++i )
{
int y = (int)( grid_bottom - i * y_delta );
p.drawLine( VALUES_WIDTH, y, width(), y );
}
}
else
{
for( int y = grid_bottom, level = m_bottom_level;
y >= TOP_MARGIN && level <= m_top_level;
y -= m_y_delta, ++level )
{
if( level % 5 == 0 )
{
p.setPen( QColor( 0x4F, 0x4F, 0x4F ) );
}
else
{
p.setPen( QColor( 0x3F, 0x3F, 0x3F ) );
}
// draw level line
p.drawLine( VALUES_WIDTH, y, width(), y );
}
}
}
// following code draws all visible values
// setup selection-vars
int sel_pos_start = m_selectStartTact64th;
int sel_pos_end = m_selectStartTact64th + m_selectedTact64th;
if( sel_pos_start > sel_pos_end )
{
qSwap<int>( sel_pos_start, sel_pos_end );
}
int sel_level_start = m_selectStartLevel;
int sel_level_end = sel_level_start + m_selectedLevels;
if( sel_level_start > sel_level_end )
{
qSwap<int>( sel_level_start, sel_level_end );
}
if( validPattern() == TRUE )
{
timeMap & time_map = m_pattern->getTimeMap();
timeMap::iterator it = time_map.end();
do
{
--it;
Sint32 len_tact_64th = 4;
const int level = it.value();
Sint32 pos_tact_64th = -it.key();
const int x = ( pos_tact_64th - m_currentPosition ) *
m_ppt / 64;
if( x > width() - VALUES_WIDTH )
{
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
{
rect_width = width() - x;
}
// is the value in visible area?
if( ( level >= m_bottom_level && level <= m_top_level )
|| ( level > m_top_level && m_top_level >= 0 )
|| ( level < m_bottom_level
&& m_bottom_level <= 0 ) )
{
bool is_selected = FALSE;
// if we're in move-mode, we may only draw
// values in selected area, that have originally
// been selected and not values that are now in
// selection because the user moved it...
if( m_editMode == MOVE )
{
if( m_selValuesForMove.contains(
it.key() ) )
{
is_selected = TRUE;
}
}
else if( level >= sel_level_start &&
level <= sel_level_end &&
pos_tact_64th >= sel_pos_start &&
pos_tact_64th + len_tact_64th <=
sel_pos_end )
{
is_selected = TRUE;
}
// we've done and checked all, lets draw the
// value
int y_start;
int rect_height;
if( m_y_auto )
{
y_start = grid_bottom
- ( grid_bottom - TOP_MARGIN )
* ( level - m_min_level )
/ ( m_max_level - m_min_level );
int y_end = grid_bottom
+ ( grid_bottom - TOP_MARGIN )
* m_min_level
/ ( m_max_level - m_min_level );
rect_height = y_end - y_start;
}
else
{
y_start = grid_bottom - ( level
- m_bottom_level )
* m_y_delta;
rect_height = level * m_y_delta;
}
drawValueRect( p, x + VALUES_WIDTH, y_start,
rect_width, rect_height,
is_selected );
}
} while( it != time_map.begin() );
}
else
{
QFont f = p.font();
f.setBold( TRUE );
p.setFont( pointSize<14>( f ) );
p.setPen( QColor( 0, 255, 0 ) );
p.drawText( VALUES_WIDTH + 20, TOP_MARGIN + 40,
width() - VALUES_WIDTH - 20 - SCROLLBAR_SIZE,
grid_height - 40, Qt::TextWordWrap,
tr( "Please open an automation pattern with "
"the context menu of a control!" ) );
}
p.setClipRect( VALUES_WIDTH, TOP_MARGIN, width() - VALUES_WIDTH,
grid_height );
// now draw selection-frame
int x = ( sel_pos_start - m_currentPosition ) * m_ppt / 64;
int w = ( sel_pos_end - sel_pos_start ) * m_ppt / 64;
int y, h;
if( m_y_auto )
{
y = grid_bottom - (int)roundf( ( grid_bottom - TOP_MARGIN )
* ( sel_level_start - m_min_level )
/ (float)( m_max_level - m_min_level ) );
h = grid_bottom - (int)roundf( ( grid_bottom - TOP_MARGIN )
* ( sel_level_end - m_min_level )
/ (float)( m_max_level - m_min_level ) ) - y;
}
else
{
y = grid_bottom - ( sel_level_start - m_bottom_level )
* m_y_delta;
h = ( sel_level_start - sel_level_end ) * m_y_delta;
}
p.setPen( QColor( 0, 64, 192 ) );
p.drawRect( x + VALUES_WIDTH, y, w, h );
int l = ( validPattern() == TRUE )? (int) m_pattern->length() : 0;
// reset scroll-range
m_leftRightScroll->setRange( 0, l );
m_leftRightScroll->setSingleStep( 1 );
m_leftRightScroll->setPageStep( l );
}
void automationEditor::removeSelection( void )
{
m_selectStartTact64th = 0;
@@ -1467,15 +1156,318 @@ inline void automationEditor::drawCross( QPainter & _p )
void automationEditor::paintEvent( QPaintEvent * )
void automationEditor::paintEvent( QPaintEvent * _pe )
{
QPixmap paintPixmap( size() );
updatePaintPixmap( paintPixmap );
QStyleOption opt;
opt.initFrom( this );
QPainter p( this );
p.drawPixmap( 0, 0, paintPixmap );
style()->drawPrimitive( QStyle::PE_Widget, &opt, &p, this );
// set font-size to 8
p.setFont( pointSize<8>( p.font() ) );
int grid_height = height() - TOP_MARGIN - SCROLLBAR_SIZE;
// start drawing at the bottom
int grid_bottom = height() - SCROLLBAR_SIZE - 1;
p.fillRect( 0, TOP_MARGIN, VALUES_WIDTH, height() - TOP_MARGIN,
QColor( 0x33, 0x33, 0x33 ) );
// print value numbers
int font_height = p.fontMetrics().height();
Qt::Alignment text_flags =
(Qt::Alignment)( Qt::AlignRight | Qt::AlignVCenter );
if( m_pattern )
{
if( m_y_auto )
{
int y[] = { grid_bottom, TOP_MARGIN + font_height / 2 };
int level[] = { m_min_level, m_max_level };
for( int i = 0; i < 2; ++i )
{
const QString & label = m_pattern->object()
->levelToLabel( level[i] );
p.setPen( QColor( 240, 240, 240 ) );
p.drawText( 1, y[i] - font_height + 1,
VALUES_WIDTH - 10, 2 * font_height,
text_flags, label );
p.setPen( QColor( 0, 0, 0 ) );
p.drawText( 0, y[i] - font_height,
VALUES_WIDTH - 10, 2 * font_height,
text_flags, label );
}
}
else
{
int y = grid_bottom;
int level = m_bottom_level;
int printable = tMax( 1, 5 * DEFAULT_Y_DELTA
/ m_y_delta );
int module = level % printable;
if( module )
{
int inv_module = ( printable - module )
% printable;
y -= inv_module * m_y_delta;
level += inv_module;
}
for( ; y >= TOP_MARGIN && level <= m_top_level;
y -= printable * m_y_delta, level += printable )
{
const QString & label = m_pattern->object()
->levelToLabel( level );
p.setPen( QColor( 240, 240, 240 ) );
p.drawText( 1, y - font_height + 1,
VALUES_WIDTH - 10, 2 * font_height,
text_flags, label );
p.setPen( QColor( 0, 0, 0 ) );
p.drawText( 0, y - font_height,
VALUES_WIDTH - 10, 2 * font_height,
text_flags, label );
}
}
}
// set clipping area, because we are not allowed to paint over
// keyboard...
p.setClipRect( VALUES_WIDTH, TOP_MARGIN, width() - VALUES_WIDTH,
height() - TOP_MARGIN - SCROLLBAR_SIZE );
grid_height );
// draw vertical raster
int tact_16th = m_currentPosition / 4;
const int offset = ( m_currentPosition % 4 ) * m_ppt /
DEFAULT_STEPS_PER_TACT / 4;
if( m_pattern )
{
int x_line_end = m_y_auto || m_top_level < m_max_level ?
TOP_MARGIN :
grid_bottom - ( m_top_level - m_bottom_level )
* m_y_delta;
for( int x = VALUES_WIDTH - offset; x < width();
x += m_ppt / DEFAULT_STEPS_PER_TACT, ++tact_16th )
{
if( x >= VALUES_WIDTH )
{
// every tact-start needs to be a bright line
if( tact_16th % 16 == 0 )
{
p.setPen( QColor( 0x7F, 0x7F, 0x7F ) );
}
// normal line
else if( tact_16th % 4 == 0 )
{
p.setPen( QColor( 0x5F, 0x5F, 0x5F ) );
}
// weak line
else
{
p.setPen( QColor( 0x3F, 0x3F, 0x3F ) );
}
p.drawLine( x, grid_bottom, x, x_line_end );
}
}
if( m_y_auto )
{
QPen pen( QColor( 0x4F, 0x4F, 0x4F ) );
p.setPen( pen );
p.drawLine( VALUES_WIDTH, grid_bottom, width(),
grid_bottom );
pen.setStyle( Qt::DotLine );
p.setPen( pen );
float y_delta = ( grid_bottom - TOP_MARGIN ) / 8.0f;
for( int i = 1; i < 8; ++i )
{
int y = (int)( grid_bottom - i * y_delta );
p.drawLine( VALUES_WIDTH, y, width(), y );
}
}
else
{
for( int y = grid_bottom, level = m_bottom_level;
y >= TOP_MARGIN && level <= m_top_level;
y -= m_y_delta, ++level )
{
if( level % 5 == 0 )
{
p.setPen( QColor( 0x4F, 0x4F, 0x4F ) );
}
else
{
p.setPen( QColor( 0x3F, 0x3F, 0x3F ) );
}
// draw level line
p.drawLine( VALUES_WIDTH, y, width(), y );
}
}
}
// following code draws all visible values
// setup selection-vars
int sel_pos_start = m_selectStartTact64th;
int sel_pos_end = m_selectStartTact64th + m_selectedTact64th;
if( sel_pos_start > sel_pos_end )
{
qSwap<int>( sel_pos_start, sel_pos_end );
}
int sel_level_start = m_selectStartLevel;
int sel_level_end = sel_level_start + m_selectedLevels;
if( sel_level_start > sel_level_end )
{
qSwap<int>( sel_level_start, sel_level_end );
}
if( validPattern() == TRUE )
{
timeMap & time_map = m_pattern->getTimeMap();
timeMap::iterator it = time_map.end();
do
{
--it;
Sint32 len_tact_64th = 4;
const int level = it.value();
Sint32 pos_tact_64th = -it.key();
const int x = ( pos_tact_64th - m_currentPosition ) *
m_ppt / 64;
if( x > width() - VALUES_WIDTH )
{
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
{
rect_width = width() - x;
}
// is the value in visible area?
if( ( level >= m_bottom_level && level <= m_top_level )
|| ( level > m_top_level && m_top_level >= 0 )
|| ( level < m_bottom_level
&& m_bottom_level <= 0 ) )
{
bool is_selected = FALSE;
// if we're in move-mode, we may only draw
// values in selected area, that have originally
// been selected and not values that are now in
// selection because the user moved it...
if( m_editMode == MOVE )
{
if( m_selValuesForMove.contains(
it.key() ) )
{
is_selected = TRUE;
}
}
else if( level >= sel_level_start &&
level <= sel_level_end &&
pos_tact_64th >= sel_pos_start &&
pos_tact_64th + len_tact_64th <=
sel_pos_end )
{
is_selected = TRUE;
}
// we've done and checked all, lets draw the
// value
int y_start;
int rect_height;
if( m_y_auto )
{
y_start = grid_bottom
- ( grid_bottom - TOP_MARGIN )
* ( level - m_min_level )
/ ( m_max_level - m_min_level );
int y_end = grid_bottom
+ ( grid_bottom - TOP_MARGIN )
* m_min_level
/ ( m_max_level - m_min_level );
rect_height = y_end - y_start;
}
else
{
y_start = grid_bottom - ( level
- m_bottom_level )
* m_y_delta;
rect_height = level * m_y_delta;
}
drawValueRect( p, x + VALUES_WIDTH, y_start,
rect_width, rect_height,
is_selected );
}
} while( it != time_map.begin() );
}
else
{
QFont f = p.font();
f.setBold( TRUE );
p.setFont( pointSize<14>( f ) );
p.setPen( QColor( 0, 255, 0 ) );
p.drawText( VALUES_WIDTH + 20, TOP_MARGIN + 40,
width() - VALUES_WIDTH - 20 - SCROLLBAR_SIZE,
grid_height - 40, Qt::TextWordWrap,
tr( "Please open an automation pattern with "
"the context menu of a control!" ) );
}
// now draw selection-frame
int x = ( sel_pos_start - m_currentPosition ) * m_ppt / 64;
int w = ( sel_pos_end - sel_pos_start ) * m_ppt / 64;
int y, h;
if( m_y_auto )
{
y = grid_bottom - (int)roundf( ( grid_bottom - TOP_MARGIN )
* ( sel_level_start - m_min_level )
/ (float)( m_max_level - m_min_level ) );
h = grid_bottom - (int)roundf( ( grid_bottom - TOP_MARGIN )
* ( sel_level_end - m_min_level )
/ (float)( m_max_level - m_min_level ) ) - y;
}
else
{
y = grid_bottom - ( sel_level_start - m_bottom_level )
* m_y_delta;
h = ( sel_level_start - sel_level_end ) * m_y_delta;
}
p.setPen( QColor( 0, 64, 192 ) );
p.drawRect( x + VALUES_WIDTH, y, w, h );
// TODO: Get this out of paint event
int l = ( validPattern() == TRUE )? (int) m_pattern->length() : 0;
// reset scroll-range
if( m_leftRightScroll->maximum() != l )
{
m_leftRightScroll->setRange( 0, l );
m_leftRightScroll->setPageStep( l );
}
if( validPattern() == TRUE )
{
@@ -1493,7 +1485,6 @@ void automationEditor::paintEvent( QPaintEvent * )
}
p.drawPixmap( mapFromGlobal( QCursor::pos() ) + QPoint( 8, 8 ),
*cursor );
}
@@ -1525,9 +1516,6 @@ void automationEditor::resizeEvent( QResizeEvent * )
m_topBottomScroll->setRange( m_scroll_level, m_scroll_level );
}
m_topBottomScroll->setSingleStep( 1 );
m_topBottomScroll->setPageStep( 20 );
m_topBottomScroll->setValue( m_scroll_level );
if( engine::getSongEditor() )

View File

@@ -29,16 +29,16 @@
#include "piano_roll.h"
#include <Qt/QtXml>
#include <QtGui/QApplication>
#include <QtGui/QButtonGroup>
#include <QtGui/QClipboard>
#include <QtGui/QKeyEvent>
#include <QtGui/QLabel>
#include <QtGui/QLayout>
#include <QtGui/QPainter>
#include <QtGui/QWheelEvent>
#include <QtGui/QMdiArea>
#include <QtGui/QPainter>
#include <QtGui/QStyleOption>
#include <QtGui/QWheelEvent>
#ifndef __USE_XOPEN
@@ -244,9 +244,13 @@ pianoRoll::pianoRoll( void ) :
// init scrollbars
m_leftRightScroll = new QScrollBar( Qt::Horizontal, this );
m_topBottomScroll = new QScrollBar( Qt::Vertical, this );
m_leftRightScroll->setSingleStep( 1 );
connect( m_leftRightScroll, SIGNAL( valueChanged( int ) ), this,
SLOT( horScrolled( int ) ) );
m_topBottomScroll = new QScrollBar( Qt::Vertical, this );
m_topBottomScroll->setSingleStep( 1 );
m_topBottomScroll->setPageStep( 20 );
connect( m_topBottomScroll, SIGNAL( valueChanged( int ) ), this,
SLOT( verScrolled( int ) ) );
@@ -601,365 +605,6 @@ inline void pianoRoll::drawDetuningInfo( QPainter & _p, note * _n, Uint16 _x,
void pianoRoll::updatePaintPixmap( QPixmap & _p )
{
_p.fill( QColor( 0, 0, 0 ) );
QPainter p( &_p );
// set font-size to 8
p.setFont( pointSize<8>( p.font() ) );
// y_offset is used to align the piano-keys on the key-lines
int y_offset = 0;
// calculate y_offset according to first key
switch( prKeyOrder[m_startKey % NOTES_PER_OCTAVE] )
{
case PR_BLACK_KEY: y_offset = KEY_LINE_HEIGHT/4; break;
case PR_WHITE_KEY_BIG: y_offset = KEY_LINE_HEIGHT/2; break;
case PR_WHITE_KEY_SMALL:
if( prKeyOrder[( ( m_startKey + 1 ) %
NOTES_PER_OCTAVE)] != PR_BLACK_KEY )
{
y_offset = KEY_LINE_HEIGHT / 2;
}
break;
}
// start drawing at the bottom
int key_line_y = height() - PR_BOTTOM_MARGIN - m_notesEditHeight - 1;
// used for aligning black-keys later
int first_white_key_height = WHITE_KEY_SMALL_HEIGHT;
// key-counter - only needed for finding out whether the processed
// key is the first one
int keys_processed = 0;
int key = m_startKey;
// draw all white keys...
for( int y = key_line_y + 1 + y_offset; y > PR_TOP_MARGIN;
key_line_y -= KEY_LINE_HEIGHT, ++keys_processed )
{
// check for white key that is only half visible on the
// bottom of piano-roll
if( keys_processed == 0 &&
prKeyOrder[m_startKey % NOTES_PER_OCTAVE] ==
PR_BLACK_KEY )
{
// draw it!
p.drawPixmap( PIANO_X, y - WHITE_KEY_SMALL_HEIGHT,
*s_whiteKeySmallPm );
// update y-pos
y -= WHITE_KEY_SMALL_HEIGHT / 2;
// move first black key down (we didn't draw whole
// white key so black key needs to be lifted down)
// (default for first_white_key_height =
// WHITE_KEY_SMALL_HEIGHT, so WHITE_KEY_SMALL_HEIGHT/2
// is smaller)
first_white_key_height = WHITE_KEY_SMALL_HEIGHT / 2;
}
// check whether to draw a big or a small white key
if( prKeyOrder[key % NOTES_PER_OCTAVE] == PR_WHITE_KEY_SMALL )
{
// draw a small one...
p.drawPixmap( PIANO_X, y - WHITE_KEY_SMALL_HEIGHT,
*s_whiteKeySmallPm );
// update y-pos
y -= WHITE_KEY_SMALL_HEIGHT;
}
else if( prKeyOrder[key % NOTES_PER_OCTAVE] ==
PR_WHITE_KEY_BIG )
{
// draw a big one...
p.drawPixmap( PIANO_X, y-WHITE_KEY_BIG_HEIGHT,
*s_whiteKeyBigPm );
// if a big white key has been the first key,
// black keys needs to be lifted up
if( keys_processed == 0 )
{
first_white_key_height = WHITE_KEY_BIG_HEIGHT;
}
// update y-pos
y -= WHITE_KEY_BIG_HEIGHT;
}
// label C-keys...
if( static_cast<tones>( key % NOTES_PER_OCTAVE ) == C )
{
p.setPen( QColor( 240, 240, 240 ) );
p.drawText( C_KEY_LABEL_X + 1, y+14, "C" +
QString::number( static_cast<int>( key /
NOTES_PER_OCTAVE ) ) );
p.setPen( QColor( 0, 0, 0 ) );
p.drawText( C_KEY_LABEL_X, y + 13, "C" +
QString::number( static_cast<int>( key /
NOTES_PER_OCTAVE ) ) );
p.setPen( QColor( 0x4F, 0x4F, 0x4F ) );
}
else
{
p.setPen( QColor( 0x3F, 0x3F, 0x3F ) );
}
// draw key-line
p.drawLine( WHITE_KEY_WIDTH, key_line_y, width(), key_line_y );
++key;
}
// reset all values, because now we're going to draw all black keys
key = m_startKey;
keys_processed = 0;
int white_cnt = 0;
// and go!
for( int y = height() - PR_BOTTOM_MARGIN - m_notesEditHeight + y_offset;
y > PR_TOP_MARGIN; ++keys_processed )
{
// check for black key that is only half visible on the bottom
// of piano-roll
if( keys_processed == 0
// current key may not be a black one
&& prKeyOrder[key % NOTES_PER_OCTAVE] != PR_BLACK_KEY
// but the previous one must be black (we must check this
// because there might be two white keys (E-F)
&& prKeyOrder[( key - 1 ) % NOTES_PER_OCTAVE] ==
PR_BLACK_KEY )
{
// draw the black key!
p.drawPixmap( PIANO_X, y - BLACK_KEY_HEIGHT / 2,
*s_blackKeyPm );
// is the one after the start-note a black key??
if( prKeyOrder[( key + 1 ) % NOTES_PER_OCTAVE] !=
PR_BLACK_KEY )
{
// no, then move it up!
y -= KEY_LINE_HEIGHT / 2;
}
}
// current key black?
if( prKeyOrder[key % NOTES_PER_OCTAVE] == PR_BLACK_KEY )
{
// then draw it (calculation of y very complicated,
// but that's the only working solution, sorry...)
p.drawPixmap( PIANO_X, y - ( first_white_key_height -
WHITE_KEY_SMALL_HEIGHT ) -
WHITE_KEY_SMALL_HEIGHT/2 - 1 -
BLACK_KEY_HEIGHT, *s_blackKeyPm );
// update y-pos
y -= WHITE_KEY_BIG_HEIGHT;
// reset white-counter
white_cnt = 0;
}
else
{
// simple workaround for increasing x if there were
// two white keys (e.g. between E and F)
++white_cnt;
if( white_cnt > 1 )
{
y -= WHITE_KEY_BIG_HEIGHT/2;
}
}
++key;
}
// erase the area below the piano, because there might be keys that
// should be only half-visible
p.fillRect( QRect( 0, height() - PR_BOTTOM_MARGIN - m_notesEditHeight,
WHITE_KEY_WIDTH, m_notesEditHeight ),
QColor( 0, 0, 0 ) );
// set clipping area, because we are not allowed to paint over
// keyboard...
p.setClipRect( WHITE_KEY_WIDTH, PR_TOP_MARGIN,
width() - WHITE_KEY_WIDTH,
height() - PR_TOP_MARGIN - PR_BOTTOM_MARGIN );
// draw vertical raster
int tact_16th = m_currentPosition / 4;
const int offset = ( m_currentPosition % 4 ) * m_ppt /
DEFAULT_STEPS_PER_TACT / 4;
for( int x = WHITE_KEY_WIDTH - offset; x < width();
x += m_ppt / DEFAULT_STEPS_PER_TACT, ++tact_16th )
{
if( x >= WHITE_KEY_WIDTH )
{
// every tact-start needs to be a bright line
if( tact_16th % 16 == 0 )
{
p.setPen( QColor( 0x7F, 0x7F, 0x7F ) );
}
// normal line
else if( tact_16th % 4 == 0 )
{
p.setPen( QColor( 0x5F, 0x5F, 0x5F ) );
}
// weak line
else
{
p.setPen( QColor( 0x3F, 0x3F, 0x3F ) );
}
p.drawLine( x, PR_TOP_MARGIN, x, height() -
PR_BOTTOM_MARGIN );
}
}
// following code draws all notes in visible area + volume-lines
p.setClipRect( WHITE_KEY_WIDTH, PR_TOP_MARGIN, width() -
WHITE_KEY_WIDTH, height() - PR_TOP_MARGIN -
PR_BOTTOM_MARGIN );
// setup selection-vars
int sel_pos_start = m_selectStartTact64th;
int sel_pos_end = m_selectStartTact64th+m_selectedTact64th;
if( sel_pos_start > sel_pos_end )
{
qSwap<int>( sel_pos_start, sel_pos_end );
}
int sel_key_start = m_selectStartKey - m_startKey + 1;
int sel_key_end = sel_key_start + m_selectedKeys;
if( sel_key_start > sel_key_end )
{
qSwap<int>( sel_key_start, sel_key_end );
}
int y_base = height() - PR_BOTTOM_MARGIN - m_notesEditHeight - 1;
if( validPattern() == TRUE )
{
QPainter p_detuning( &_p );
p_detuning.setClipRect( WHITE_KEY_WIDTH, PR_TOP_MARGIN,
width() - WHITE_KEY_WIDTH,
height() - PR_TOP_MARGIN - PR_BOTTOM_MARGIN
- m_notesEditHeight );
const noteVector & notes = m_pattern->notes();
const int visible_keys = ( height() - PR_TOP_MARGIN -
PR_BOTTOM_MARGIN - m_notesEditHeight ) /
KEY_LINE_HEIGHT + 2;
for( noteVector::const_iterator it = notes.begin();
it != notes.end(); ++it )
{
Sint32 len_tact_64th = ( *it )->length();
if( len_tact_64th == 0 )
{
continue;
}
else if( len_tact_64th < 0 )
{
len_tact_64th = 4;
}
const int key = ( *it )->key() - m_startKey + 1;
Sint32 pos_tact_64th = ( *it )->pos();
int note_width = len_tact_64th * m_ppt / 64;
const int x = ( pos_tact_64th - m_currentPosition ) *
m_ppt / 64;
// skip this note if not in visible area at all
if( !( x + note_width >= 0 &&
x <= width() - WHITE_KEY_WIDTH ) )
{
continue;
}
// is the note in visible area?
if( key > 0 && key <= visible_keys )
{
bool is_selected = FALSE;
// if we're in move-mode, we may only draw notes
// in selected area, that have originally been
// selected and not notes that are now in
// selection because the user moved it...
if( m_editMode == MOVE )
{
if( qFind( m_selNotesForMove.begin(),
m_selNotesForMove.end(),
*it ) !=
m_selNotesForMove.end() )
{
is_selected = TRUE;
}
}
else if( key > sel_key_start &&
key <= sel_key_end &&
pos_tact_64th >= sel_pos_start &&
pos_tact_64th + len_tact_64th <=
sel_pos_end )
{
is_selected = TRUE;
}
// we've done and checked all, lets draw the
// note
drawNoteRect( p, x + WHITE_KEY_WIDTH,
y_base - key * KEY_LINE_HEIGHT,
note_width,
is_selected,
( *it )->length() < 0 );
}
// draw volume-line of note
p.setPen( QPen( QColor( 0, 255, 0 ), NE_LINE_WIDTH ) );
p.drawLine( x + WHITE_KEY_WIDTH + 1,
height() - PR_BOTTOM_MARGIN -
( *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
{
QFont f = p.font();
f.setBold( TRUE );
p.setFont( pointSize<14>( f ) );
p.setPen( QColor( 0, 255, 0 ) );
p.drawText( WHITE_KEY_WIDTH + 20, PR_TOP_MARGIN + 40,
tr( "Please open a pattern by double-clicking "
"on it!" ) );
}
p.setClipRect( WHITE_KEY_WIDTH, PR_TOP_MARGIN, width() -
WHITE_KEY_WIDTH, height() - PR_TOP_MARGIN -
m_notesEditHeight - PR_BOTTOM_MARGIN );
// now draw selection-frame
int x = ( ( sel_pos_start - m_currentPosition ) * m_ppt ) / 64;
int w = ( ( ( sel_pos_end - m_currentPosition ) * m_ppt ) /
64 ) - x;
int y = (int) y_base - sel_key_start * KEY_LINE_HEIGHT;
int h = (int) y_base - sel_key_end * KEY_LINE_HEIGHT - y;
p.setPen( QColor( 0, 64, 192 ) );
p.drawRect( x + WHITE_KEY_WIDTH, y, w, h );
int l = ( validPattern() == TRUE )? (int) m_pattern->length() : 0;
// reset scroll-range
m_leftRightScroll->setRange( 0, l );
m_leftRightScroll->setSingleStep( 1 );
m_leftRightScroll->setPageStep( l );
}
void pianoRoll::removeSelection( void )
{
m_selectStartTact64th = 0;
@@ -1917,17 +1562,362 @@ void pianoRoll::mouseMoveEvent( QMouseEvent * _me )
void pianoRoll::paintEvent( QPaintEvent * _pe)
void pianoRoll::paintEvent( QPaintEvent * _pe )
{
QPixmap paintPixmap( size() );
updatePaintPixmap( paintPixmap );
QStyleOption opt;
opt.initFrom( this );
QPainter p( this );
style()->drawPrimitive( QStyle::PE_Widget, &opt, &p, this );
p.drawPixmap( 0, 0, paintPixmap );
// set font-size to 8
p.setFont( pointSize<8>( p.font() ) );
// y_offset is used to align the piano-keys on the key-lines
int y_offset = 0;
// calculate y_offset according to first key
switch( prKeyOrder[m_startKey % NOTES_PER_OCTAVE] )
{
case PR_BLACK_KEY: y_offset = KEY_LINE_HEIGHT/4; break;
case PR_WHITE_KEY_BIG: y_offset = KEY_LINE_HEIGHT/2; break;
case PR_WHITE_KEY_SMALL:
if( prKeyOrder[( ( m_startKey + 1 ) %
NOTES_PER_OCTAVE)] != PR_BLACK_KEY )
{
y_offset = KEY_LINE_HEIGHT / 2;
}
break;
}
// start drawing at the bottom
int key_line_y = height() - PR_BOTTOM_MARGIN - m_notesEditHeight - 1;
// used for aligning black-keys later
int first_white_key_height = WHITE_KEY_SMALL_HEIGHT;
// key-counter - only needed for finding out whether the processed
// key is the first one
int keys_processed = 0;
int key = m_startKey;
// draw all white keys...
for( int y = key_line_y + 1 + y_offset; y > PR_TOP_MARGIN;
key_line_y -= KEY_LINE_HEIGHT, ++keys_processed )
{
// check for white key that is only half visible on the
// bottom of piano-roll
if( keys_processed == 0 &&
prKeyOrder[m_startKey % NOTES_PER_OCTAVE] ==
PR_BLACK_KEY )
{
// draw it!
p.drawPixmap( PIANO_X, y - WHITE_KEY_SMALL_HEIGHT,
*s_whiteKeySmallPm );
// update y-pos
y -= WHITE_KEY_SMALL_HEIGHT / 2;
// move first black key down (we didn't draw whole
// white key so black key needs to be lifted down)
// (default for first_white_key_height =
// WHITE_KEY_SMALL_HEIGHT, so WHITE_KEY_SMALL_HEIGHT/2
// is smaller)
first_white_key_height = WHITE_KEY_SMALL_HEIGHT / 2;
}
// check whether to draw a big or a small white key
if( prKeyOrder[key % NOTES_PER_OCTAVE] == PR_WHITE_KEY_SMALL )
{
// draw a small one...
p.drawPixmap( PIANO_X, y - WHITE_KEY_SMALL_HEIGHT,
*s_whiteKeySmallPm );
// update y-pos
y -= WHITE_KEY_SMALL_HEIGHT;
}
else if( prKeyOrder[key % NOTES_PER_OCTAVE] ==
PR_WHITE_KEY_BIG )
{
// draw a big one...
p.drawPixmap( PIANO_X, y-WHITE_KEY_BIG_HEIGHT,
*s_whiteKeyBigPm );
// if a big white key has been the first key,
// black keys needs to be lifted up
if( keys_processed == 0 )
{
first_white_key_height = WHITE_KEY_BIG_HEIGHT;
}
// update y-pos
y -= WHITE_KEY_BIG_HEIGHT;
}
// label C-keys...
if( static_cast<tones>( key % NOTES_PER_OCTAVE ) == C )
{
p.setPen( QColor( 240, 240, 240 ) );
p.drawText( C_KEY_LABEL_X + 1, y+14, "C" +
QString::number( static_cast<int>( key /
NOTES_PER_OCTAVE ) ) );
p.setPen( QColor( 0, 0, 0 ) );
p.drawText( C_KEY_LABEL_X, y + 13, "C" +
QString::number( static_cast<int>( key /
NOTES_PER_OCTAVE ) ) );
p.setPen( QColor( 0x4F, 0x4F, 0x4F ) );
}
else
{
p.setPen( QColor( 0x3F, 0x3F, 0x3F ) );
}
// draw key-line
p.drawLine( WHITE_KEY_WIDTH, key_line_y, width(), key_line_y );
++key;
}
// reset all values, because now we're going to draw all black keys
key = m_startKey;
keys_processed = 0;
int white_cnt = 0;
// and go!
for( int y = height() - PR_BOTTOM_MARGIN - m_notesEditHeight + y_offset;
y > PR_TOP_MARGIN; ++keys_processed )
{
// check for black key that is only half visible on the bottom
// of piano-roll
if( keys_processed == 0
// current key may not be a black one
&& prKeyOrder[key % NOTES_PER_OCTAVE] != PR_BLACK_KEY
// but the previous one must be black (we must check this
// because there might be two white keys (E-F)
&& prKeyOrder[( key - 1 ) % NOTES_PER_OCTAVE] ==
PR_BLACK_KEY )
{
// draw the black key!
p.drawPixmap( PIANO_X, y - BLACK_KEY_HEIGHT / 2,
*s_blackKeyPm );
// is the one after the start-note a black key??
if( prKeyOrder[( key + 1 ) % NOTES_PER_OCTAVE] !=
PR_BLACK_KEY )
{
// no, then move it up!
y -= KEY_LINE_HEIGHT / 2;
}
}
// current key black?
if( prKeyOrder[key % NOTES_PER_OCTAVE] == PR_BLACK_KEY )
{
// then draw it (calculation of y very complicated,
// but that's the only working solution, sorry...)
p.drawPixmap( PIANO_X, y - ( first_white_key_height -
WHITE_KEY_SMALL_HEIGHT ) -
WHITE_KEY_SMALL_HEIGHT/2 - 1 -
BLACK_KEY_HEIGHT, *s_blackKeyPm );
// update y-pos
y -= WHITE_KEY_BIG_HEIGHT;
// reset white-counter
white_cnt = 0;
}
else
{
// simple workaround for increasing x if there were
// two white keys (e.g. between E and F)
++white_cnt;
if( white_cnt > 1 )
{
y -= WHITE_KEY_BIG_HEIGHT/2;
}
}
++key;
}
// erase the area below the piano, because there might be keys that
// should be only half-visible
p.fillRect( QRect( 0, height() - PR_BOTTOM_MARGIN - m_notesEditHeight,
WHITE_KEY_WIDTH, m_notesEditHeight ),
QColor( 0, 0, 0 ) );
// set clipping area, because we are not allowed to paint over
// keyboard...
p.setClipRect( WHITE_KEY_WIDTH, PR_TOP_MARGIN,
width() - WHITE_KEY_WIDTH,
height() - PR_TOP_MARGIN - PR_BOTTOM_MARGIN );
// draw vertical raster
int tact_16th = m_currentPosition / 4;
const int offset = ( m_currentPosition % 4 ) * m_ppt /
DEFAULT_STEPS_PER_TACT / 4;
for( int x = WHITE_KEY_WIDTH - offset; x < width();
x += m_ppt / DEFAULT_STEPS_PER_TACT, ++tact_16th )
{
if( x >= WHITE_KEY_WIDTH )
{
// every tact-start needs to be a bright line
if( tact_16th % 16 == 0 )
{
p.setPen( QColor( 0x7F, 0x7F, 0x7F ) );
}
// normal line
else if( tact_16th % 4 == 0 )
{
p.setPen( QColor( 0x5F, 0x5F, 0x5F ) );
}
// weak line
else
{
p.setPen( QColor( 0x3F, 0x3F, 0x3F ) );
}
p.drawLine( x, PR_TOP_MARGIN, x, height() -
PR_BOTTOM_MARGIN );
}
}
// following code draws all notes in visible area + volume-lines
// setup selection-vars
int sel_pos_start = m_selectStartTact64th;
int sel_pos_end = m_selectStartTact64th+m_selectedTact64th;
if( sel_pos_start > sel_pos_end )
{
qSwap<int>( sel_pos_start, sel_pos_end );
}
int sel_key_start = m_selectStartKey - m_startKey + 1;
int sel_key_end = sel_key_start + m_selectedKeys;
if( sel_key_start > sel_key_end )
{
qSwap<int>( sel_key_start, sel_key_end );
}
int y_base = height() - PR_BOTTOM_MARGIN - m_notesEditHeight - 1;
if( validPattern() == TRUE )
{
QPainter p_detuning( this );
p_detuning.setClipRect( WHITE_KEY_WIDTH, PR_TOP_MARGIN,
width() - WHITE_KEY_WIDTH,
height() - PR_TOP_MARGIN - PR_BOTTOM_MARGIN
- m_notesEditHeight );
const noteVector & notes = m_pattern->notes();
const int visible_keys = ( height() - PR_TOP_MARGIN -
PR_BOTTOM_MARGIN - m_notesEditHeight ) /
KEY_LINE_HEIGHT + 2;
for( noteVector::const_iterator it = notes.begin();
it != notes.end(); ++it )
{
Sint32 len_tact_64th = ( *it )->length();
if( len_tact_64th == 0 )
{
continue;
}
else if( len_tact_64th < 0 )
{
len_tact_64th = 4;
}
const int key = ( *it )->key() - m_startKey + 1;
Sint32 pos_tact_64th = ( *it )->pos();
int note_width = len_tact_64th * m_ppt / 64;
const int x = ( pos_tact_64th - m_currentPosition ) *
m_ppt / 64;
// skip this note if not in visible area at all
if( !( x + note_width >= 0 &&
x <= width() - WHITE_KEY_WIDTH ) )
{
continue;
}
// is the note in visible area?
if( key > 0 && key <= visible_keys )
{
bool is_selected = FALSE;
// if we're in move-mode, we may only draw notes
// in selected area, that have originally been
// selected and not notes that are now in
// selection because the user moved it...
if( m_editMode == MOVE )
{
if( qFind( m_selNotesForMove.begin(),
m_selNotesForMove.end(),
*it ) !=
m_selNotesForMove.end() )
{
is_selected = TRUE;
}
}
else if( key > sel_key_start &&
key <= sel_key_end &&
pos_tact_64th >= sel_pos_start &&
pos_tact_64th + len_tact_64th <=
sel_pos_end )
{
is_selected = TRUE;
}
// we've done and checked all, lets draw the
// note
drawNoteRect( p, x + WHITE_KEY_WIDTH,
y_base - key * KEY_LINE_HEIGHT,
note_width,
is_selected,
( *it )->length() < 0 );
}
// draw volume-line of note
p.setPen( QPen( QColor( 0, 255, 0 ), NE_LINE_WIDTH ) );
p.drawLine( x + WHITE_KEY_WIDTH + 1,
height() - PR_BOTTOM_MARGIN -
( *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
{
QFont f = p.font();
f.setBold( TRUE );
p.setFont( pointSize<14>( f ) );
p.setPen( QColor( 0, 255, 0 ) );
p.drawText( WHITE_KEY_WIDTH + 20, PR_TOP_MARGIN + 40,
tr( "Please open a pattern by double-clicking "
"on it!" ) );
}
p.setClipRect( WHITE_KEY_WIDTH, PR_TOP_MARGIN, width() -
WHITE_KEY_WIDTH, height() - PR_TOP_MARGIN -
m_notesEditHeight - PR_BOTTOM_MARGIN );
// now draw selection-frame
int x = ( ( sel_pos_start - m_currentPosition ) * m_ppt ) / 64;
int w = ( ( ( sel_pos_end - m_currentPosition ) * m_ppt ) /
64 ) - x;
int y = (int) y_base - sel_key_start * KEY_LINE_HEIGHT;
int h = (int) y_base - sel_key_end * KEY_LINE_HEIGHT - y;
p.setPen( QColor( 0, 64, 192 ) );
p.drawRect( x + WHITE_KEY_WIDTH, y, w, h );
// TODO: Get this out of paint event
int l = ( validPattern() == TRUE )? (int) m_pattern->length() : 0;
// reset scroll-range
if( m_leftRightScroll->maximum() != l )
{
m_leftRightScroll->setRange( 0, l );
m_leftRightScroll->setPageStep( l );
}
// horizontal line for the key under the cursor
if( validPattern() == TRUE )
{
int key_num = getKey( mapFromGlobal( QCursor::pos() ).y() );
@@ -1950,7 +1940,6 @@ void pianoRoll::paintEvent( QPaintEvent * _pe)
}
p.drawPixmap( mapFromGlobal( QCursor::pos() ) + QPoint( 8, 8 ),
*cursor );
}
@@ -1974,8 +1963,6 @@ void pianoRoll::resizeEvent( QResizeEvent * )
m_totalKeysToScroll = total_pixels * NOTES_PER_OCTAVE / OCTAVE_HEIGHT;
m_topBottomScroll->setRange( 0, m_totalKeysToScroll );
m_topBottomScroll->setSingleStep( 1 );
m_topBottomScroll->setPageStep( 20 );
if( m_startKey > m_totalKeysToScroll )
{

View File

@@ -151,6 +151,8 @@ void trackContainer::loadSettings( const QDomElement & _this )
mainWindow::restoreWidgetState( this, _this );
realignTracks();
pd->setValue( start_val + _this.childNodes().count() );
if( was_null )