2 * AutomationPatternView.cpp - implementation of view for AutomationPattern
4 * Copyright (c) 2008-2010 Tobias Doerffel <tobydox/at/users.sourceforge.net>
6 * This file is part of Linux MultiMedia Studio - http://lmms.sourceforge.net
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public
10 * License as published by the Free Software Foundation; either
11 * version 2 of the License, or (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
18 * You should have received a copy of the GNU General Public
19 * License along with this program (see COPYING); if not, write to the
20 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 * Boston, MA 02110-1301 USA.
25 #include <QtGui/QMouseEvent>
26 #include <QtGui/QPainter>
27 #include <QtGui/QMenu>
29 #include "AutomationPatternView.h"
30 #include "AutomationEditor.h"
31 #include "AutomationPattern.h"
34 #include "gui_templates.h"
35 #include "ProjectJournal.h"
36 #include "rename_dialog.h"
37 #include "string_pair_drag.h"
42 AutomationPatternView::AutomationPatternView( AutomationPattern
* _pattern
,
43 trackView
* _parent
) :
44 trackContentObjectView( _pattern
, _parent
),
49 connect( m_pat
, SIGNAL( dataChanged() ),
50 this, SLOT( update() ) );
52 setAttribute( Qt::WA_OpaquePaintEvent
, true );
53 setFixedHeight( parentWidget()->height() - 2 );
54 setAutoResizeEnabled( false );
56 toolTip::add( this, tr( "double-click to open this pattern in "
57 "automation editor" ) );
63 AutomationPatternView::~AutomationPatternView()
71 void AutomationPatternView::update()
76 m_pat
->changeLength( m_pat
->length() );
78 trackContentObjectView::update();
84 void AutomationPatternView::resetName()
86 m_pat
->setName( QString::null
);
92 void AutomationPatternView::changeName()
94 QString s
= m_pat
->name();
95 renameDialog
rename_dlg( s
);
104 void AutomationPatternView::disconnectObject( QAction
* _a
)
106 JournallingObject
* j
= engine::projectJournal()->
107 journallingObject( _a
->data().toInt() );
108 if( j
&& dynamic_cast<AutomatableModel
*>( j
) )
110 m_pat
->m_objects
.erase( qFind( m_pat
->m_objects
.begin(),
111 m_pat
->m_objects
.end(),
112 dynamic_cast<AutomatableModel
*>( j
) ) );
120 void AutomationPatternView::constructContextMenu( QMenu
* _cm
)
122 QAction
* a
= new QAction( embed::getIconPixmap( "automation" ),
123 tr( "Open in Automation editor" ), _cm
);
124 _cm
->insertAction( _cm
->actions()[0], a
);
125 connect( a
, SIGNAL( triggered( bool ) ),
126 m_pat
, SLOT( openInAutomationEditor() ) );
127 _cm
->insertSeparator( _cm
->actions()[1] );
131 _cm
->addAction( embed::getIconPixmap( "edit_erase" ),
132 tr( "Clear" ), m_pat
, SLOT( clear() ) );
135 _cm
->addAction( embed::getIconPixmap( "reload" ), tr( "Reset name" ),
136 this, SLOT( resetName() ) );
137 _cm
->addAction( embed::getIconPixmap( "edit_rename" ),
139 this, SLOT( changeName() ) );
140 if( !m_pat
->m_objects
.isEmpty() )
143 QMenu
* m
= new QMenu( tr( "%1 Connections" ).
144 arg( m_pat
->m_objects
.count() ), _cm
);
145 for( AutomationPattern::objectVector::iterator it
=
146 m_pat
->m_objects
.begin();
147 it
!= m_pat
->m_objects
.end(); ++it
)
151 a
= new QAction( tr( "Disconnect \"%1\"" ).
152 arg( ( *it
)->fullDisplayName() ), m
);
153 a
->setData( ( *it
)->id() );
157 connect( m
, SIGNAL( triggered( QAction
* ) ),
158 this, SLOT( disconnectObject( QAction
* ) ) );
168 void AutomationPatternView::mouseDoubleClickEvent( QMouseEvent
* _me
)
170 if( _me
->button() != Qt::LeftButton
)
175 m_pat
->openInAutomationEditor();
181 void AutomationPatternView::paintEvent( QPaintEvent
* )
183 if( m_needsUpdate
== false )
186 p
.drawPixmap( 0, 0, m_paintPixmap
);
190 m_needsUpdate
= false;
192 if( m_paintPixmap
.isNull() == true || m_paintPixmap
.size() != size() )
194 m_paintPixmap
= QPixmap( size() );
197 QPainter
p( &m_paintPixmap
);
199 QLinearGradient
lingrad( 0, 0, 0, height() );
200 const QColor c
= isSelected() ? QColor( 0, 0, 224 ) :
201 QColor( 96, 96, 96 );
202 lingrad
.setColorAt( 0, c
);
203 lingrad
.setColorAt( 0.5, Qt::black
);
204 lingrad
.setColorAt( 1, c
);
205 p
.setBrush( lingrad
);
206 p
.setPen( QColor( 0, 0, 0 ) );
207 p
.drawRect( QRect( 0, 0, width() - 1, height() - 1 ) );
209 const float ppt
= fixedTCOs() ?
210 ( parentWidget()->width() - 2 * TCO_BORDER_WIDTH
)
211 / (float) m_pat
->length().getTact() :
214 const int x_base
= TCO_BORDER_WIDTH
;
215 p
.setPen( QColor( 0, 0, 0 ) );
217 for( tact_t t
= 1; t
< m_pat
->length().getTact(); ++t
)
219 p
.drawLine( x_base
+ static_cast<int>( ppt
* t
) - 1,
220 TCO_BORDER_WIDTH
, x_base
+ static_cast<int>(
222 p
.drawLine( x_base
+ static_cast<int>( ppt
* t
) - 1,
223 height() - ( 4 + 2 * TCO_BORDER_WIDTH
),
224 x_base
+ static_cast<int>( ppt
* t
) - 1,
225 height() - 2 * TCO_BORDER_WIDTH
);
228 const float min
= m_pat
->firstObject()->minValue
<float>();
229 const float max
= m_pat
->firstObject()->maxValue
<float>();
231 const float y_scale
= max
- min
;
232 const float h
= ( height()-2*TCO_BORDER_WIDTH
) / y_scale
;
234 p
.translate( 0.0f
, max
* height() / y_scale
-1 );
237 QLinearGradient
lin2grad( 0, min
, 0, max
);
238 const QColor cl
= QColor( 255, 224, 0 );
239 const QColor cd
= QColor( 229, 158, 0 );
241 lin2grad
.setColorAt( 1, cl
);
242 lin2grad
.setColorAt( 0, cd
);
244 for( AutomationPattern::timeMap::const_iterator it
=
245 m_pat
->getTimeMap().begin();
246 it
!= m_pat
->getTimeMap().end(); ++it
)
248 const float x1
= x_base
+ it
.key() * ppt
/
249 midiTime::ticksPerTact();
251 if( it
+1 != m_pat
->getTimeMap().end() )
253 x2
= x_base
+ (it
+1).key() * ppt
/
254 midiTime::ticksPerTact() + 1;
258 x2
= (float)( width() - TCO_BORDER_WIDTH
);
260 p
.fillRect( QRectF( x1
, 0.0f
, x2
-x1
, it
.value() ),
265 p
.setFont( pointSize
<7>( p
.font() ) );
266 if( m_pat
->isMuted() || m_pat
->getTrack()->isMuted() )
268 p
.setPen( QColor( 192, 192, 192 ) );
272 p
.setPen( QColor( 0, 64, 255 ) );
275 p
.drawText( 2, p
.fontMetrics().height() - 1, m_pat
->name() );
277 if( m_pat
->isMuted() )
279 p
.drawPixmap( 3, p
.fontMetrics().height() + 1,
280 embed::getIconPixmap( "muted", 16, 16 ) );
286 p
.drawPixmap( 0, 0, m_paintPixmap
);
293 void AutomationPatternView::dragEnterEvent( QDragEnterEvent
* _dee
)
295 stringPairDrag::processDragEnterEvent( _dee
, "automatable_model" );
296 if( !_dee
->isAccepted() )
298 trackContentObjectView::dragEnterEvent( _dee
);
305 void AutomationPatternView::dropEvent( QDropEvent
* _de
)
307 QString type
= stringPairDrag::decodeKey( _de
);
308 QString val
= stringPairDrag::decodeValue( _de
);
309 if( type
== "automatable_model" )
311 AutomatableModel
* mod
= dynamic_cast<AutomatableModel
*>(
312 engine::projectJournal()->
313 journallingObject( val
.toInt() ) );
316 m_pat
->addObject( mod
);
320 if( engine::automationEditor() &&
321 engine::automationEditor()->currentPattern() == m_pat
)
323 engine::automationEditor()->setCurrentPattern( m_pat
);
328 trackContentObjectView::dropEvent( _de
);
335 #include "moc_AutomationPatternView.cxx"