Skip to content

Commit

Permalink
Allow drag-dropping onto Controller Rack
Browse files Browse the repository at this point in the history
* Implement connecting automatable model to controller by
  dragging its widget onto a controller in the controller rack
* Implement saving of automatable models with controller
  connections when their names must be quoted
* Let Engine::getAutomatableModel() return existing osc connections, too
  (in order to overwrite them)
  • Loading branch information
JohannesLorenz committed Nov 1, 2018
1 parent 7e7044d commit da9fcfc
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 15 deletions.
2 changes: 2 additions & 0 deletions include/AutomatableModel.h
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,8 @@ public slots:


private:
static bool mustQuoteName(const QString &name);

virtual void saveSettings( QDomDocument& doc, QDomElement& element )
{
saveSettings( doc, element, "value" );
Expand Down
2 changes: 2 additions & 0 deletions include/ControllerRackView.h
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@ public slots:

protected:
virtual void closeEvent( QCloseEvent * _ce );
virtual void dragEnterEvent( QDragEnterEvent *dee );
virtual void dropEvent( QDropEvent * de );

private slots:
void addController();
Expand Down
44 changes: 39 additions & 5 deletions src/core/AutomatableModel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,16 +89,23 @@ bool AutomatableModel::isAutomated() const
}



bool AutomatableModel::mustQuoteName(const QString& name)
{
QRegExp reg("^[A-Za-z0-9._-]+$");
return !reg.exactMatch(name);
}

void AutomatableModel::saveSettings( QDomDocument& doc, QDomElement& element, const QString& name )
{
bool mustQuote = mustQuoteName(name);

if( isAutomated() || m_scaleType != Linear )
{
// automation needs tuple of data (name, id, value)
// scale type also needs an extra value
// => it must be appended as a node

QRegExp reg("^[A-Za-z0-9._-]+$");
bool mustQuote = !reg.exactMatch(name);
QDomElement me = doc.createElement( mustQuote ? QString("automatablemodel") : name );
me.setAttribute( "id", ProjectJournal::idToSave( id() ) );
me.setAttribute( "value", m_value );
Expand All @@ -110,8 +117,18 @@ void AutomatableModel::saveSettings( QDomDocument& doc, QDomElement& element, co
}
else
{
// non automation, linear scale (default), can be saved as attribute
element.setAttribute( name, m_value );
if(mustQuote)
{
QDomElement me = doc.createElement( "automatablemodel" );
me.setAttribute( "nodename", name );
me.setAttribute( "value", m_value );
element.appendChild( me );
}
else
{
// non automation, linear scale (default), can be saved as attribute
element.setAttribute( name, m_value );
}
}

if( m_controllerConnection && m_controllerConnection->getController()->type()
Expand All @@ -131,7 +148,13 @@ void AutomatableModel::saveSettings( QDomDocument& doc, QDomElement& element, co
element.appendChild( controllerElement );
}

QDomElement element = doc.createElement( name );
bool mustQuote = mustQuoteName(name);
QString elementName = mustQuote ? "controllerconnection"
: name;

QDomElement element = doc.createElement( elementName );
if(mustQuote)
element.setAttribute( "nodename", name );
m_controllerConnection->saveSettings( doc, element );

controllerElement.appendChild( element );
Expand Down Expand Up @@ -170,6 +193,17 @@ void AutomatableModel::loadSettings( const QDomElement& element, const QString&
if( connectionNode.isElement() )
{
QDomNode thisConnection = connectionNode.toElement().namedItem( name );
if( !thisConnection.isElement() )
{
thisConnection = connectionNode.toElement().namedItem( "controllerconnection" );
QDomElement tcElement = thisConnection.toElement();
// sanity check
if( tcElement.isNull() || tcElement.attribute( "nodename" ) != name )
{
// no, that wasn't it, act as if we never found one
thisConnection.clear();
}
}
if( thisConnection.isElement() )
{
setControllerConnection( new ControllerConnection( (Controller*)NULL ) );
Expand Down
24 changes: 16 additions & 8 deletions src/core/Engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,16 +144,24 @@ AutomatableModel *LmmsCore::getAutomatableModel(const QString& val, bool hasOsc)
}
else
{
/* TODO: name */
AutomatableModel* spamod = SpaOscModelFactory(itr.value(), url.path()).res;
//SpaOscModel* spamod = new SpaOscModel(itr.value(), url.path().toUtf8().data());
if(spamod)
QMap<QString, AutomatableModel*>& connectedModels
= itr.value()->connectedModels;
auto itr2 = connectedModels.find(url.path());
if(itr2 != connectedModels.end())
{
itr.value()->connectedModels.insert(url.path(), spamod);
mod = spamod;
return *itr2;
}
else {
qDebug() << "LMMS: Could not create model from OSC port (received \"" << val << "\")";
else
{
AutomatableModel* spamod = SpaOscModelFactory(itr.value(), url.path()).res;
if(spamod)
{
itr.value()->connectedModels.insert(url.path(), spamod);
mod = spamod;
}
else {
qDebug() << "LMMS: Could not create model from OSC port (received \"" << val << "\")";
}
}
}
}
Expand Down
1 change: 1 addition & 0 deletions src/core/spa/SpaInstrument.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ void SpaInstrument::loadSettings( const QDomElement & _this )
for(QDomElement portnode = elem.firstChildElement();
!portnode.isNull();
portnode = portnode.nextSiblingElement())
if(portnode.nodeName() != "connection")
{
QString name = portnode.nodeName();
if(name == "automatablemodel")
Expand Down
35 changes: 33 additions & 2 deletions src/gui/widgets/ControllerRackView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,11 @@
#include "GuiApplication.h"
#include "MainWindow.h"
#include "GroupBox.h"
#include "ControllerConnection.h"
#include "ControllerRackView.h"
#include "ControllerView.h"
#include "LfoController.h"
#include "StringPairDrag.h"


ControllerRackView::ControllerRackView( ) :
Expand Down Expand Up @@ -87,6 +89,8 @@ ControllerRackView::ControllerRackView( ) :
subWin->resize( 350, 200 );
subWin->setFixedWidth( 350 );
subWin->setMinimumHeight( 200 );

setAcceptDrops(true);
}


Expand Down Expand Up @@ -202,7 +206,7 @@ void ControllerRackView::addController()


void ControllerRackView::closeEvent( QCloseEvent * _ce )
{
{
if( parentWidget() )
{
parentWidget()->hide();
Expand All @@ -212,5 +216,32 @@ void ControllerRackView::closeEvent( QCloseEvent * _ce )
hide();
}
_ce->ignore();
}
}

void ControllerRackView::dragEnterEvent( QDragEnterEvent *dee )
{
StringPairDrag::processDragEnterEvent( dee, "automatable_model" );
}

void ControllerRackView::dropEvent( QDropEvent *de )
{
QString type = StringPairDrag::decodeKey( de );
QString val = StringPairDrag::decodeValue( de );
// qDebug() << "DROP: type/val:" << type << ", " << val;

if( type == "automatable_model" )
{
AutomatableModel* mod =
Engine::getAutomatableModel( val,
de->mimeData()->hasFormat( "application/x-osc-stringpair" ));

de->acceptProposedAction();

if( mod->controllerConnection() )
{
delete mod->controllerConnection();
mod->setControllerConnection( nullptr );
}
}
}

0 comments on commit da9fcfc

Please sign in to comment.