Refactor the drawing of TCO's; Get rid of hardcoded colors in TCOs; Make TCO gradient configurable; Even out the color scheme

Thanks to @Fastigium for helping with the BB Pattern redraw problem
This commit is contained in:
Umcaruje committed 2016-03-02 21:58:27 +01:00
1 parent 8841b89b6d
commit f136ba3097
12 files changed
+466 -342

No files matched your search

+102 -83
View File
@@ -21,12 +21,12 @@
* Boston, MA 02110-1301 USA.
*
*/
#include "AutomationPatternView.h"
#include <QMouseEvent>
#include <QPainter>
#include <QMenu>
#include "AutomationPatternView.h"
#include "AutomationEditor.h"
#include "AutomationPattern.h"
#include "embed.h"
@@ -45,8 +45,7 @@ AutomationPatternView::AutomationPatternView( AutomationPattern * _pattern,
TrackView * _parent ) :
TrackContentObjectView( _pattern, _parent ),
m_pat( _pattern ),
m_paintPixmap(),
m_needsUpdate( true )
m_paintPixmap()
{
connect( m_pat, SIGNAL( dataChanged() ),
this, SLOT( update() ) );
@@ -54,7 +53,6 @@ AutomationPatternView::AutomationPatternView( AutomationPattern * _pattern,
this, SLOT( update() ) );
setAttribute( Qt::WA_OpaquePaintEvent, true );
setFixedHeight( parentWidget()->height() - 2 );
ToolTip::add( this, tr( "double-click to open this pattern in "
"automation editor" ) );
@@ -85,7 +83,6 @@ void AutomationPatternView::openInAutomationEditor()
void AutomationPatternView::update()
{
m_needsUpdate = true;
if( fixedTCOs() )
{
m_pat->changeLength( m_pat->length() );
@@ -245,82 +242,66 @@ void AutomationPatternView::mouseDoubleClickEvent( QMouseEvent * me )
void AutomationPatternView::paintEvent( QPaintEvent * )
{
if( m_needsUpdate == false )
QPainter painter( this );
if( !needsUpdate() )
{
QPainter p( this );
p.drawPixmap( 0, 0, m_paintPixmap );
painter.drawPixmap( 0, 0, m_paintPixmap );
return;
}
QPainter _p( this );
const QColor styleColor = _p.pen().brush().color();
setNeedsUpdate( false );
m_needsUpdate = false;
if( m_paintPixmap.isNull() == true || m_paintPixmap.size() != size() )
{
m_paintPixmap = QPixmap( size() );
}
m_paintPixmap = m_paintPixmap.isNull() == true || m_paintPixmap.size() != size()
? QPixmap( size() ) : m_paintPixmap;
QPainter p( &m_paintPixmap );
QLinearGradient lingrad( 0, 0, 0, height() );
QColor c;
if( !( m_pat->getTrack()->isMuted() || m_pat->isMuted() ) )
c = styleColor;
else
c = QColor( 80, 80, 80 );
if( isSelected() == true )
{
c.setRgb( qMax( c.red() - 128, 0 ), qMax( c.green() - 128, 0 ), 255 );
}
bool muted = m_pat->getTrack()->isMuted() || m_pat->isMuted();
bool current = gui->automationEditor()->currentPattern() == m_pat;
// state: selected, muted, normal
c = isSelected() ? selectedColor() : ( muted ? mutedBackgroundColor()
: painter.background().color() );
lingrad.setColorAt( 1, c.darker( 300 ) );
lingrad.setColorAt( 0, c );
p.setBrush( lingrad );
if( gui->automationEditor()->currentPattern() == m_pat )
p.setPen( c.lighter( 160 ) );
if( gradient() )
{
p.fillRect( rect(), lingrad );
}
else
p.setPen( c.lighter( 130 ) );
p.drawRect( 1, 1, width()-3, height()-3 );
{
p.fillRect( rect(), c );
}
const float ppt = fixedTCOs() ?
( parentWidget()->width() - 2 * TCO_BORDER_WIDTH )
/ (float) m_pat->length().getTact() :
pixelsPerTact();
const int x_base = TCO_BORDER_WIDTH;
p.setPen( c.darker( 300 ) );
for( tact_t t = 1; t < m_pat->length().getTact(); ++t )
{
const int tx = x_base + static_cast<int>( ppt * t ) - 1;
if( tx < ( width() - TCO_BORDER_WIDTH*2 ) )
{
p.drawLine( tx, TCO_BORDER_WIDTH, tx, 5 );
p.drawLine( tx, height() - ( 4 + 2 * TCO_BORDER_WIDTH ),
tx, height() - 2 * TCO_BORDER_WIDTH );
}
}
const float min = m_pat->firstObject()->minValue<float>();
const float max = m_pat->firstObject()->maxValue<float>();
const float y_scale = max - min;
const float h = ( height() - 2*TCO_BORDER_WIDTH ) / y_scale;
const float h = ( height() - 2 * TCO_BORDER_WIDTH ) / y_scale;
p.translate( 0.0f, max * height() / y_scale - TCO_BORDER_WIDTH );
p.scale( 1.0f, -h );
QLinearGradient lin2grad( 0, min, 0, max );
QColor col;
col = !muted ? painter.pen().brush().color() : mutedColor();
lin2grad.setColorAt( 1, fgColor().lighter( 150 ) );
lin2grad.setColorAt( 0.5, fgColor() );
lin2grad.setColorAt( 0, fgColor().darker( 150 ) );
lin2grad.setColorAt( 1, col.lighter( 150 ) );
lin2grad.setColorAt( 0.5, col );
lin2grad.setColorAt( 0, col.darker( 150 ) );
for( AutomationPattern::timeMap::const_iterator it =
m_pat->getTimeMap().begin();
@@ -332,67 +313,105 @@ void AutomationPatternView::paintEvent( QPaintEvent * )
MidiTime::ticksPerTact();
const float x2 = (float)( width() - TCO_BORDER_WIDTH );
if( x1 > ( width() - TCO_BORDER_WIDTH ) ) break;
p.fillRect( QRectF( x1, 0.0f, x2-x1, it.value() ),
lin2grad );
if( gradient() )
{
p.fillRect( QRectF( x1, 0.0f, x2 - x1, it.value() ), lin2grad );
}
else
{
p.fillRect( QRectF( x1, 0.0f, x2 - x1, it.value() ), col );
}
break;
}
float *values = m_pat->valuesAfter( it.key() );
for( int i = it.key(); i < (it+1).key(); i++ )
for( int i = it.key(); i < (it + 1).key(); i++ )
{
float value = values[i - it.key()];
const float x1 = x_base + i * ppt /
MidiTime::ticksPerTact();
const float x2 = x_base + (i+1) * ppt /
const float x2 = x_base + (i + 1) * ppt /
MidiTime::ticksPerTact();
if( x1 > ( width() - TCO_BORDER_WIDTH ) ) break;
p.fillRect( QRectF( x1, 0.0f, x2-x1, value ),
lin2grad );
if( gradient() )
{
p.fillRect( QRectF( x1, 0.0f, x2 - x1, value ), lin2grad );
}
else
{
p.fillRect( QRectF( x1, 0.0f, x2 - x1, value ), col );
}
}
delete [] values;
}
p.resetMatrix();
// bar lines
const int lineSize = 3;
p.setPen( c.darker( 300 ) );
for( tact_t t = 1; t < m_pat->length().getTact(); ++t )
{
const int tx = x_base + static_cast<int>( ppt * t ) - 2;
if( tx < ( width() - TCO_BORDER_WIDTH * 2 ) )
{
p.drawLine( tx, TCO_BORDER_WIDTH, tx, TCO_BORDER_WIDTH + lineSize );
p.drawLine( tx, rect().bottom() - ( lineSize + TCO_BORDER_WIDTH ),
tx, rect().bottom() - TCO_BORDER_WIDTH );
}
}
// recording icon for when recording automation
if( m_pat->isRecording() )
{
p.drawPixmap( 4, 14, *s_pat_rec );
p.drawPixmap( 1, rect().bottom() - s_pat_rec->height(),
*s_pat_rec );
}
// outer edge
p.setBrush( QBrush() );
if( gui->automationEditor()->currentPattern() == m_pat )
p.setPen( c.lighter( 130 ) );
else
p.setPen( c.darker( 300 ) );
p.drawRect( 0, 0, width()-1, height()-1 );
// pattern name
p.setFont( pointSize<8>( p.font() ) );
QColor text_color = ( m_pat->isMuted() || m_pat->getTrack()->isMuted() )
? QColor( 30, 30, 30 )
: textColor();
p.setPen( QColor( 0, 0, 0 ) );
p.drawText( 4, p.fontMetrics().height()+1, m_pat->name() );
p.setPen( text_color );
p.drawText( 3, p.fontMetrics().height(), m_pat->name() );
p.setRenderHint( QPainter::TextAntialiasing );
if( m_staticTextName.text() != m_pat->name() )
{
m_staticTextName.setText( m_pat->name() );
}
QFont font;
font.setHintingPreference( QFont::PreferFullHinting );
font.setPointSize( 8 );
p.setFont( font );
const int textTop = TCO_BORDER_WIDTH + 1;
const int textLeft = TCO_BORDER_WIDTH + 1;
p.setPen( textShadowColor() );
p.drawStaticText( textLeft + 1, textTop + 1, m_staticTextName );
p.setPen( textColor() );
p.drawStaticText( textLeft, textTop, m_staticTextName );
// inner border
p.setPen( c.lighter( current ? 160 : 130 ) );
p.drawRect( 1, 1, rect().right() - TCO_BORDER_WIDTH,
rect().bottom() - TCO_BORDER_WIDTH );
// outer border
p.setPen( current? c.lighter( 130 ) : c.darker( 300 ) );
p.drawRect( 0, 0, rect().right(), rect().bottom() );
// draw the 'muted' pixmap only if the pattern was manualy muted
if( m_pat->isMuted() )
{
p.drawPixmap( 3, p.fontMetrics().height() + 1,
embed::getIconPixmap( "muted", 16, 16 ) );
const int spacing = TCO_BORDER_WIDTH;
const int size = 14;
p.drawPixmap( spacing, height() - ( size + spacing ),
embed::getIconPixmap( "muted", size, size ) );
}
p.end();
_p.drawPixmap( 0, 0, m_paintPixmap );
painter.drawPixmap( 0, 0, m_paintPixmap );
}