Controllers are rendered more dynamically

ControllerRackView now uses a layout to organize the ControllerViews.
The ControllerViews in turn use layouts to organize their widgets
(labels and push button). ControllerView now inherits from QFrame
instead of QWidget. The (static) background image for controllers was
deleted because the ControllerView can now be resized dynamically.

Song: Added specific signals for added and removed controllers. Also
removed a TODO by putting the functionality to remove all controllers in
a method (removeAllControllers).

Deleted Controllers now don't unregister from Song during deletion. This
has to be done by the client (Hollywood principle - "Don't call us, we
call you.").

TODO: For some strange reason I cannot programmatically resize the
controller rack to make it fit the controllers on my screen.
This commit is contained in:
Michael Gregorius
2015-07-29 22:35:06 +02:00
parent 27c5295388
commit cd0176b5af
8 changed files with 120 additions and 112 deletions

View File

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.1 KiB

View File

@@ -34,8 +34,10 @@
class QPushButton;
class QScrollArea;
class QVBoxLayout;
class ControllerView;
class Controller;
class ControllerRackView : public QWidget, public SerializingObject
@@ -56,12 +58,13 @@ public:
public slots:
void deleteController( ControllerView * _view );
void onControllerAdded( Controller * );
void onControllerRemoved( Controller * );
protected:
virtual void closeEvent( QCloseEvent * _ce );
private slots:
virtual void update();
void addController();
@@ -69,8 +72,12 @@ private:
QVector<ControllerView *> m_controllerViews;
QScrollArea * m_scrollArea;
QVBoxLayout * m_scrollAreaLayout;
QPushButton * m_addButton;
// Stores the index of where to insert the next ControllerView.
// Needed so that the StretchItem always stays at the last position.
int m_nextIndex;
} ;
#endif

View File

@@ -25,7 +25,7 @@
#ifndef CONTROLLER_VIEW_H
#define CONTROLLER_VIEW_H
#include <QWidget>
#include <QFrame>
#include "AutomatableModel.h"
#include "Controller.h"
@@ -39,7 +39,7 @@ class QMdiSubWindow;
class LedCheckBox;
class ControllerView : public QWidget, public ModelView
class ControllerView : public QFrame, public ModelView
{
Q_OBJECT
public:
@@ -70,15 +70,14 @@ signals:
protected:
virtual void contextMenuEvent( QContextMenuEvent * _me );
virtual void paintEvent( QPaintEvent * _pe );
virtual void modelChanged();
virtual void mouseDoubleClickEvent( QMouseEvent * event );
private:
QPixmap m_bg;
QMdiSubWindow * m_subWindow;
ControllerDialog * m_controllerDlg;
QLabel * m_nameLabel;
bool m_show;
} ;

View File

@@ -323,6 +323,8 @@ private:
void saveControllerStates( QDomDocument & doc, QDomElement & element );
void restoreControllerStates( const QDomElement & element );
void removeAllControllers();
AutomationTrack * m_globalAutomationTrack;
@@ -376,6 +378,8 @@ signals:
void lengthChanged( int tacts );
void tempoChanged( bpm_t newBPM );
void timeSignatureChanged( int oldTicksPerTact, int ticksPerTact );
void controllerAdded( Controller * );
void controllerRemoved( Controller * );
} ;

View File

@@ -95,11 +95,6 @@ Controller::~Controller()
s_controllers.remove( idx );
}
if( Engine::getSong() )
{
Engine::getSong()->removeController( this );
}
m_valueBuffer.clear();
// Remove connections by destroyed signal
}

View File

@@ -828,11 +828,7 @@ void Song::clearProject()
gui->getProjectNotes()->clear();
}
// Move to function
while( !m_controllers.empty() )
{
delete m_controllers.last();
}
removeAllControllers();
emit dataChanged();
@@ -1215,6 +1211,19 @@ void Song::restoreControllerStates( const QDomElement & element )
}
void Song::removeAllControllers()
{
for (int i = 0; i < m_controllers.size(); ++i)
{
delete m_controllers.at(i);
}
m_controllers.clear();
}
void Song::exportProjectTracks()
{
exportProject( true );
@@ -1383,12 +1392,14 @@ void Song::setModified()
void Song::addController( Controller * c )
void Song::addController( Controller * controller )
{
if( c != NULL && m_controllers.contains( c ) == false )
if( controller && !m_controllers.contains( controller ) )
{
m_controllers.append( c );
emit dataChanged();
m_controllers.append( controller );
emit controllerAdded( controller );
this->setModified();
}
}
@@ -1402,11 +1413,10 @@ void Song::removeController( Controller * controller )
{
m_controllers.remove( index );
if( Engine::getSong() )
{
Engine::getSong()->setModified();
}
emit dataChanged();
emit controllerRemoved( controller );
delete controller;
this->setModified();
}
}

View File

@@ -31,6 +31,7 @@
#include <QVBoxLayout>
#include <QMdiArea>
#include <QMessageBox>
#include <QVBoxLayout>
#include "Song.h"
#include "embed.h"
@@ -43,32 +44,32 @@
ControllerRackView::ControllerRackView( ) :
QWidget()
QWidget(),
m_nextIndex(0)
{
setMinimumWidth( 250 );
setMaximumWidth( 250 );
resize( 250, 160 );
setWindowIcon( embed::getIconPixmap( "controller" ) );
setWindowTitle( tr( "Controller Rack" ) );
m_scrollArea = new QScrollArea( this );
m_scrollArea->setVerticalScrollBarPolicy( Qt::ScrollBarAlwaysOn );
m_scrollArea->setHorizontalScrollBarPolicy( Qt::ScrollBarAlwaysOff );
m_scrollArea->setPalette( QApplication::palette( m_scrollArea ) );
m_scrollArea->setMinimumHeight( 64 );
QWidget * scrollAreaWidget = new QWidget( m_scrollArea );
m_scrollAreaLayout = new QVBoxLayout( scrollAreaWidget );
m_scrollAreaLayout->addStretch();
scrollAreaWidget->setLayout( m_scrollAreaLayout );
m_scrollArea->setWidget( scrollAreaWidget );
m_scrollArea->setWidgetResizable( true );
m_addButton = new QPushButton( this );
m_addButton->setText( tr( "Add" ) );
QWidget * w = new QWidget();
m_scrollArea->setWidget( w );
connect( m_addButton, SIGNAL( clicked() ),
this, SLOT( addController() ) );
connect( Engine::getSong(), SIGNAL( dataChanged() ),
this, SLOT( update() ) );
Song * song = Engine::getSong();
connect( song, SIGNAL( controllerAdded( Controller* ) ), SLOT( onControllerAdded( Controller* ) ) );
connect( song, SIGNAL( controllerRemoved( Controller* ) ), SLOT( onControllerRemoved( Controller* ) ) );
QVBoxLayout * layout = new QVBoxLayout();
layout->addWidget( m_scrollArea );
@@ -82,8 +83,10 @@ ControllerRackView::ControllerRackView( ) :
flags &= ~Qt::WindowMaximizeButtonHint;
subWin->setWindowFlags( flags );
parentWidget()->setAttribute( Qt::WA_DeleteOnClose, false );
parentWidget()->move( 880, 310 );
subWin->setAttribute( Qt::WA_DeleteOnClose, false );
subWin->move( 880, 310 );
resize( 600, 400 );
}
@@ -91,8 +94,6 @@ ControllerRackView::ControllerRackView( ) :
ControllerRackView::~ControllerRackView()
{
// delete scroll-area with all children
delete m_scrollArea;
}
@@ -119,8 +120,7 @@ void ControllerRackView::deleteController( ControllerView * _view )
{
Controller * c = _view->getController();
int connectionCount = c->connectionCount();
if( connectionCount > 0 )
if( c->connectionCount() > 0 )
{
QMessageBox msgBox;
msgBox.setIcon( QMessageBox::Question );
@@ -134,58 +134,63 @@ void ControllerRackView::deleteController( ControllerView * _view )
}
}
m_controllerViews.erase( qFind( m_controllerViews.begin(),
m_controllerViews.end(), _view ) );
delete _view;
delete c;
update();
Song * song = Engine::getSong();
song->removeController( c );
}
void ControllerRackView::update()
void ControllerRackView::onControllerAdded( Controller * controller )
{
QWidget * w = m_scrollArea->widget();
Song * s = Engine::getSong();
QWidget * scrollAreaWidget = m_scrollArea->widget();
setUpdatesEnabled( false );
ControllerView * controllerView = new ControllerView( controller, scrollAreaWidget );
int i = 0;
for( i = 0; i < m_controllerViews.size(); ++i )
{
delete m_controllerViews[i];
}
connect( controllerView, SIGNAL( deleteController( ControllerView * ) ),
this, SLOT( deleteController( ControllerView * ) ), Qt::QueuedConnection );
m_controllerViews.clear();
for( i = 0; i < s->m_controllers.size(); ++i )
{
ControllerView * v = new ControllerView( s->m_controllers[i], w );
connect( v, SIGNAL( deleteController( ControllerView * ) ),
this, SLOT( deleteController( ControllerView * ) ),
Qt::QueuedConnection );
m_controllerViews.append( v );
v->move( 0, i*32 );
v->show();
}
w->setFixedSize( 210, i*32 );
setUpdatesEnabled( true );
QWidget::update();
m_controllerViews.append( controllerView );
m_scrollAreaLayout->insertWidget( m_nextIndex, controllerView );
++m_nextIndex;
}
void ControllerRackView::onControllerRemoved( Controller * removedController )
{
ControllerView * viewOfRemovedController = 0;
QVector<ControllerView *>::const_iterator end = m_controllerViews.end();
for ( QVector<ControllerView *>::const_iterator it = m_controllerViews.begin(); it != end; ++it)
{
ControllerView *currentControllerView = *it;
if ( currentControllerView->getController() == removedController )
{
viewOfRemovedController = currentControllerView;
break;
}
}
if (viewOfRemovedController )
{
m_controllerViews.erase( qFind( m_controllerViews.begin(),
m_controllerViews.end(), viewOfRemovedController ) );
delete viewOfRemovedController;
--m_nextIndex;
}
}
void ControllerRackView::addController()
{
// TODO: Eventually let the user pick from available controller types
Engine::getSong()->addController( new LfoController( Engine::getSong() ) );
update();
// fix bug which always made ControllerRackView loose focus when adding
// new controller

View File

@@ -31,6 +31,7 @@
#include <QPainter>
#include <QInputDialog>
#include <QWhatsThis>
#include <QLayout>
#include "ControllerView.h"
@@ -46,22 +47,32 @@
ControllerView::ControllerView( Controller * _model, QWidget * _parent ) :
QWidget( _parent ),
QFrame( _parent ),
ModelView( _model, this ),
m_bg( embed::getIconPixmap( "controller_bg" ) ),
m_subWindow( NULL ),
m_controllerDlg( NULL ),
m_show( true )
{
setFixedSize( 210, 32 );
this->setFrameStyle( QFrame::StyledPanel );
this->setFrameShadow( QFrame::Raised );
QVBoxLayout *vBoxLayout = new QVBoxLayout(this);
QHBoxLayout *hBox = new QHBoxLayout();
vBoxLayout->addLayout(hBox);
QLabel *label = new QLabel( "<b>" + _model->displayName() + "</b>", this);
hBox->addWidget(label);
QPushButton * controlsButton = new QPushButton( tr( "Controls" ), this );
connect( controlsButton, SIGNAL( clicked() ), SLOT( editControls() ) );
hBox->addWidget(controlsButton);
m_nameLabel = new QLabel(_model->name(), this);
vBoxLayout->addWidget(m_nameLabel);
QPushButton * ctls_btn = new QPushButton( tr( "Controls" ), this );
QFont f = ctls_btn->font();
ctls_btn->setFont( pointSize<8>( f ) );
ctls_btn->setGeometry( 140, 2, 50, 14 );
connect( ctls_btn, SIGNAL( clicked() ),
this, SLOT( editControls() ) );
m_controllerDlg = getController()->createDialog( gui->mainWindow()->workspace() );
@@ -90,7 +101,6 @@ ControllerView::ControllerView( Controller * _model, QWidget * _parent ) :
ControllerView::~ControllerView()
{
delete m_subWindow;
}
@@ -128,28 +138,6 @@ void ControllerView::deleteController()
void ControllerView::paintEvent( QPaintEvent * )
{
QPainter p( this );
p.drawPixmap( 0, 0, m_bg );
QFont f = pointSizeF( font(), 7.5f );
f.setBold( true );
p.setFont( f );
Controller * c = castModel<Controller>();
p.setPen( QColor( 64, 64, 64 ) );
p.drawText( 7, 13, c->displayName() );
p.setPen( Qt::white );
p.drawText( 6, 12, c->displayName() );
f.setBold( false );
p.setFont( f );
p.drawText( 8, 26, c->name() );
}
void ControllerView::mouseDoubleClickEvent( QMouseEvent * event )
{
@@ -162,7 +150,7 @@ void ControllerView::mouseDoubleClickEvent( QMouseEvent * event )
if( ok && !new_name.isEmpty() )
{
c->setName( new_name );
update();
m_nameLabel->setText( new_name );
}
}