Beispiel #1
0
void GraphScene::init(InitType initType)
{
    // Remove all nodes from the scene (and thus also connecting edges)
    for (int row = 0; row < m_gridLayout->rowCount(); row++) {
        for (int column = 0; column < m_gridLayout->columnCount(); column++) {
            // If there is a node in that cell of the grid layout, remove it
            removeItem(static_cast<NodeItem *>(m_gridLayout->itemAt(row, column)));
        }
    }

    switch(initType) {                                      // Check how to init the scene
        case EmptyInit:
            setInputNode(NULL);                             // Reset input/output nodes
            setOuputNode(NULL);
            break;
        case StandardInit:
            NodeItem *n1 = new NodeItem(NULL, this);        // Create default input/output nodes
            n1->setName("1");
            m_gridLayout->addItem(n1, 0, 0);
            NodeItem *n2 = new NodeItem(NULL, this);
            n2->setName("2");
            m_gridLayout->addItem(n2, 0, 1);

            addEdge(n1, n2);                                // and wire them with an edge
            setInputNode(n1);                               // Set default input/output nodes
            setOuputNode(n2);
            break;
    }
    setSceneRect(QRectF());
    emit graphChanged();
}
bool GraphComponent::closeSelectedPlugins ()
{
    DBG ("GraphComponent::closeSelectedPlugins");

    jassert (host != 0);

    if (selectedNodes.getNumSelected () > 0)
    {
        for (int i = 0; i < selectedNodes.getNumSelected (); i++)
        {
            GraphNodeComponent* selected = selectedNodes.getSelectedItem (i);

            BasePlugin* plugin = (BasePlugin*) selected->getUserData ();
            if (plugin)
            {
                if (owner->isPluginEditorWindowOpen (plugin))
                    owner->closePluginEditorWindow (plugin);

                host->closePlugin (plugin);

                selectedNodes.deselect (selected);
                deletePluginNode (selected);
            }
        }

        selectedNodes.deselectAll ();

        graphChanged ();
        
        return true;
    }
    
    return false;
}
Beispiel #3
0
void    GraphView::setGraph( qan::Graph* graph )
{
    if ( graph == nullptr ) {
        qDebug() << "qan::GraphView::setGraph(): Error: Setting a nullptr graph in Qan.GraphView is not supported.";
        return;
    }
    _graph = graph;
    _graph->setContainerItem( getContainerItem() );
    emit graphChanged();
}
Beispiel #4
0
bool AudioOutput::setOutputDevice(const AudioOutputDevice &newDevice)
{
    K_XT(AudioOutput);
    if (!xt->m_xine) {
        // remember the choice until we have a xine_t
        m_device = newDevice;
        return true;
    }

    xine_audio_port_t *port = createPort(newDevice);
    if (!port) {
        debug() << Q_FUNC_INFO << "new audio port is invalid";
        return false;
    }

    KeepReference<> *keep = new KeepReference<>;
    keep->addObject(xt);
    keep->ready();

    AudioOutputXT *newXt = new AudioOutputXT;
    newXt->m_audioPort = port;
    newXt->m_xine = xt->m_xine;
    m_threadSafeObject = newXt;

    m_device = newDevice;
    SourceNode *src = source();
    if (src) {
        QList<WireCall> wireCall;
        QList<WireCall> unwireCall;
        wireCall << WireCall(src, this);
        unwireCall << WireCall(src, QExplicitlySharedDataPointer<SinkNodeXT>(xt));
        QCoreApplication::postEvent(XineThread::instance(), new RewireEvent(wireCall, unwireCall));
        graphChanged();
    }

    AudioDataOutputXT *dataOutput = dynamic_cast<AudioDataOutputXT*>(m_source->threadSafeObject().data());
    if (dataOutput)
        dataOutput->intercept(xt->m_audioPort);

    return true;
}
Beispiel #5
0
bool GraphScene::loadFrom(const QString &fileName)
{
    QFile file(fileName);
    if (file.exists() && file.open(QFile::ReadOnly)) {
        QTextStream stream(&file);
        QHash<QString, NodeItem *> nodes;                   // Temporary hashmap for faster lookup

        init(EmptyInit);                                    // Create an empty scene

        QString line;
        do {                                                // Iterate over all the lines in the file
            line = stream.readLine();                       // and split the line at ' ' characters
            const QStringList splittedLine = line.split(" ");
            if (splittedLine[0] == "node") {
                // Found a node, add it to the scene
                NodeItem *node = new NodeItem(NULL, this);
                node->setName(splittedLine[1]);
                NodeItem::NodeType nodeType = static_cast<NodeItem::NodeType>(splittedLine[2].toInt());
                switch (nodeType) {
                    case NodeItem::InputNode:
                        setInputNode(node);                 // We found the input node
                        break;
                    case NodeItem::OutputNode:
                        setOuputNode(node);                 // We found the ouput node
                        break;
                    case NodeItem::StandardNode:
                        // This should already be set by default but doesn't harm here
                        node->setNodeType(NodeItem::StandardNode);
                        break;
                }
                // There is obviously a (Matlab) formula attached, parse it...
                if (splittedLine.length() > 5) {
                    int formulaStart = line.indexOf('"');
                    QString formula = line;
                    formula.remove(0, formulaStart);
                    while (!formula.endsWith('"')) {        // Formula spans multiple lines
                        formula += '\n' + stream.readLine();
                    }
                    formula.chop(1);                        // Remove leading '"'
                    formula.remove(0, 1);                   // Remove trailing '"'
                    node->setFormula(formula);
                }

                nodes.insert(node->name(), node);
                m_gridLayout->addItem(node, splittedLine[3].toInt(), splittedLine[4].toInt());
            } else if (splittedLine[0] == "edge") {
                NodeItem *start = nodes[splittedLine[2]];   // Found an edge, add it to the scene
                NodeItem *end = nodes[splittedLine[3]];

                DirectedEdgeItem *edge = addEdge(start, end);
                edge->setName(splittedLine[1]);
                // There is obviously a (Matlab) formula attached, parse it...
                if (splittedLine.length() > 4) {
                    int formulaStart = line.indexOf('"');
                    QString formula = line;
                    formula.remove(0, formulaStart);
                    while (!formula.endsWith('"')) {        // Formula spans multiple lines
                        formula += '\n' + stream.readLine();
                    }
                    formula.chop(1);                        // Remove leading '"'
                    formula.remove(0, 1);                   // Remove trailing '"'
                    edge->setFormula(formula);
                }
            }
        } while (!line.isNull());

        emit graphChanged();
        file.close();
        return true;
    }
    return false;
}
Beispiel #6
0
bool QNodeGraph::eventFilter(QObject *o, QEvent *e)
{
	QGraphicsSceneMouseEvent *me = (QGraphicsSceneMouseEvent*) e;

	switch ((int) e->type())
	{
        case QEvent::KeyPress:
            {
                QKeyEvent *k = static_cast<QKeyEvent *>(e);
                switch(k->key())
                {
                    case Qt::Key_P:
                        {
                            parseGraph();

                            break;
                        }
                    case Qt::Key_X:
                        {
                            BaseSDFOP* op = new Mandelbulb_SDFOP();
                            DistanceOpNode *c = new DistanceOpNode(op, scene, 0);

                            break;
                        }
                    case Qt::Key_C:
                        {
                            BaseSDFOP* op = new Union_SDFOP();
                            DistanceOpNode *c = new DistanceOpNode(op, scene, 0);

                            break;
                        }
                    case Qt::Key_V:
                        {
                            BaseSDFOP* op = new Sphere_SDFOP(1.0);
                            DistanceOpNode *c = new DistanceOpNode(op, scene, 0);

                            break;
                        }
                }
                break;
            }
        case QEvent::GraphicsSceneMousePress:
            {
                switch ((int) me->button())
                {
                    case Qt::LeftButton:
                        {
                            QGraphicsItem *item = itemAt(me->scenePos());
                            if (item && item->type() == QNEPort::Type)
                            {
                                conn = new QNEConnection(0);
                                scene->addItem(conn);
                                conn->setPort1((QNEPort*) item);
                                conn->setPos1(item->scenePos());
                                conn->setPos2(me->scenePos());
                                conn->updatePath();

//                                emit graphChanged();

                                return true;
                            } else if (item && item->type() == QNEBlock::Type)
                            {
                                /* if (selBlock)
                    selBlock->setSelected(); */
                                // selBlock = (QNEBlock*) item;


                            }
                            break;
                        }
                    case Qt::RightButton:
                        {
                            QGraphicsItem *item = itemAt(me->scenePos());
                            if (item && (item->type() == QNEConnection::Type || item->type() == QNEBlock::Type))
                            {
                                delete item;
                                emit graphChanged();
                            }
                            // if (selBlock == (QNEBlock*) item)
                            // selBlock = 0;

                            break;
                        }
                }
            }
        case QEvent::GraphicsSceneMouseMove:
            {
                if (conn)
                {
                    conn->setPos2(me->scenePos());
                    conn->updatePath();
                    return true;
                }
                break;
            }
        case QEvent::GraphicsSceneMouseRelease:
            {
                if (conn && me->button() == Qt::LeftButton)
                {
                    QGraphicsItem *item = itemAt(me->scenePos());
                    if (item && item->type() == QNEPort::Type)
                    {
                        QNEPort *port1 = conn->port1();
                        QNEPort *port2 = (QNEPort*) item;

                        if (port1->block() != port2->block() && port1->isOutput() != port2->isOutput() && !port1->isConnected(port2))
                        {
                            conn->setPos2(port2->scenePos());
                            conn->setPort2(port2);
                            conn->updatePath();
                            conn = 0;

                            emit graphChanged();

                            return true;
                        }
                    }

                    delete conn;
                    conn = 0;
                    return true;
                }
                break;
            }
    }
    return QObject::eventFilter(o, e);
}
void GraphComponent::updateDisplayPlugins ()
{
    DBG ("GraphComponent::updateDisplayPlugins");

    jassert (host != 0);

    cleanInternalGraph ();

    // rebuild nodes !
    for (int i = 0; i < host->getPluginsCount (); i++)
    {
        createPluginNode (host->getPluginByIndex (i));
    }

    // update audio / midi connection links !
    ProcessingGraph* audioGraph = host->getAudioGraph ();

    for (int i = 0; i < audioGraph->getNodeCount (); i++)
    {
        ProcessingNode* source = audioGraph->getNode (i);
        BasePlugin* sourceData = (BasePlugin*) source->getData ();
        GraphNodeComponent* sourceNode = findNodeByUserData (sourceData);

        if (sourceNode != 0)
        {
            for (int j = source->getLinksCount (JOST_LINKTYPE_AUDIO); --j >= 0;)
            {
                ProcessingLink* link = source->getLink (JOST_LINKTYPE_AUDIO, j);
                BasePlugin* destData = (BasePlugin*) link->destination->getData ();
                GraphNodeComponent* destNode = findNodeByUserData (destData);

                if (destNode != 0)
                {
                    sourceNode->connectToNode (link->sourcePort,
                                               destNode,
                                               link->destinationPort,
                                               false);
                }
            }
        }
    }

    for (int i = 0; i < audioGraph->getNodeCount (); i++)
    {
        ProcessingNode* source = audioGraph->getNode (i);
        BasePlugin* sourceData = (BasePlugin*) source->getData ();
        GraphNodeComponent* sourceNode = findNodeByUserData (sourceData);

        if (sourceNode != 0)
        {
            for (int j = source->getLinksCount (JOST_LINKTYPE_MIDI); --j >= 0;)
            {
                ProcessingLink* link = source->getLink (JOST_LINKTYPE_MIDI, j);
                BasePlugin* destData = (BasePlugin*) link->destination->getData ();
                GraphNodeComponent* destNode = findNodeByUserData (destData);

                if (destNode != 0)
                {
                    sourceNode->connectToNode (link->sourcePort + sourceNode->getFirstOutputOfType (JOST_LINKTYPE_MIDI),
                                               destNode,
                                               link->destinationPort + destNode->getFirstInputOfType (JOST_LINKTYPE_MIDI),
                                               false);
                }
            }
        }
    }

    // update connectors
    graphChanged ();

    // update fixed node size and position
    resized ();
}
void GraphComponent::nodePopupMenuSelected (GraphNodeComponent* node)
{
    DBG ("GraphComponent::nodePopupMenuSelected");

    jassert (node != 0);

    currentClickedNode = node;

    bool addFirstSeparator = false;
    PopupMenu menu, subMenu;

    BasePlugin* plugin = (BasePlugin*) node->getUserData ();

    if (plugin->hasEditor ()
        || plugin->wantsEditor ()
        || plugin->isEditorInternal ())
    {
        menu.addItem (1, "Open editor");
        addFirstSeparator = true;
    }

    if (node != inputs && node != outputs)
    {
        menu.addItem (2, "Remove " + plugin->getName());
        addFirstSeparator = true;
    }

    if (addFirstSeparator)
        menu.addSeparator ();

    menu.addItem (3, "Lock", true, node->isLocked ());

    // node colour..
    ColourSelector colourSelector;
    colourSelector.setName (T("background"));
    colourSelector.setCurrentColour (node->getNodeColour ());
    colourSelector.addChangeListener (this);

    subMenu.addCustomItem (1234, &colourSelector, 300, 300, false);
    menu.addSubMenu (T("Colour"), subMenu);
    menu.addSeparator ();

    menu.addItem (4, "Mute", true, plugin->isMuted ());
    menu.addItem (5, "Bypass", true, plugin->isBypass ());
    menu.addItem (6, "Solo", false, false);
    menu.addSeparator ();

    int inputLinks = node->getInputLinksCount ();
    int outputLinks = node->getOutputLinksCount ();

    if (inputLinks > 0 && outputLinks > 0)
        menu.addItem (7, "Disconnect all");
    if (inputLinks > 0)
        menu.addItem (8, "Disconnect inputs");
    if (outputLinks > 0)
        menu.addItem (9, "Disconnect outputs");

    const int result = menu.show();
    switch (result)
    {
    case 1: // Open editor
        {
            owner->openPluginEditorWindow (plugin);
            break;
        }

    case 2: // Close
        {
            if (owner->isPluginEditorWindowOpen (plugin))
                owner->closePluginEditorWindow (plugin);

            if (plugin)
            {
                host->closePlugin (plugin);

                selectedNodes.deselect (node);
                deletePluginNode (node);

                graphChanged ();
            }

            break;
        }
    case 3: // Lock / unlock
        {
            bool lockedState = ! node->isLocked ();

            if (plugin)
                plugin->setValue (PROP_GRAPHLOCKED, lockedState);

            node->setLocked (lockedState);
            node->repaint ();
        }
        break;
    case 4: // Mute
        {
            if (plugin)
                plugin->setMuted (! plugin->isMuted());
        }
        break;
    case 5: // Bypass
        {
            if (plugin)
                plugin->setBypass (! plugin->isBypass());
        }
        break;
    case 6: // Solo (TODO)
        break;
    case 7: // Disconnect all
        node->breakAllLinks();
        break;
    case 8: // Disconnect inputs
        node->breakInputLinks();
        break;
    case 9: // Disconnect outputs
        node->breakOutputLinks();
        break;
    default:
        break;
    }
    
    currentClickedNode = 0;
}
void GraphComponent::nodePopupMenuSelected (GraphNodeComponent* node)
{
    DBG ("GraphComponent::nodePopupMenuSelected");

    jassert (node != 0);

    currentClickedNode = node;

    bool addFirstSeparator = false;
    PopupMenu menu, subMenu, synthMidiChanMenu, midiChanMenu;

    BasePlugin* plugin = (BasePlugin*) node->getUserData ();

    if (plugin->hasEditor ()
        || plugin->wantsEditor ()
        || plugin->isEditorInternal ())
    {
        menu.addItem (1, "Open editor");
        menu.addItem (2, "Prefer MIDI binding editor", true, plugin->getBoolValue(PROP_WINDOWPREFERGENERIC, false));
        addFirstSeparator = true;
    }

    if (node != inputs && node != outputs)
    {
        menu.addItem (3, "Remove " + plugin->getName() + String(" \"") + plugin->getInstanceName() + String("\""));
        addFirstSeparator = true;
    }

    if (addFirstSeparator)
        menu.addSeparator ();

    menu.addItem (4, "Lock", true, node->isLocked ());

    // node colour..
    ColourSelector colourSelector;
    colourSelector.setName (T("background"));
    colourSelector.setCurrentColour (node->getNodeColour ());
    colourSelector.addChangeListener (this);

    subMenu.addCustomItem (1234, &colourSelector, 300, 300, false);
    menu.addSubMenu (T("Colour"), subMenu);
    menu.addSeparator ();

    menu.addItem (5, "Mute", true, plugin->isMuted ());
    menu.addItem (6, "Bypass", true, plugin->isBypass ());
    menu.addItem (7, "Solo", false, false);
    menu.addSeparator ();

   synthMidiChanMenu.addItem(2020, "Omni", true, !plugin->getSynthInputChannelFilter() || plugin->getSynthInputChannel() == -1);
   midiChanMenu.addItem(1020, "Omni", true, !plugin->getMidiOutputChannelFilter() || plugin->getMidiOutputChannel() == -1);
   for (int i=1; i<17; i++)
   {
      synthMidiChanMenu.addItem(2000+i, String("Ch ") + String(i), true, plugin->getSynthInputChannelFilter() && plugin->getSynthInputChannel() == i);
      midiChanMenu.addItem(1000+i, String("Ch ") + String(i), true, plugin->getMidiOutputChannelFilter() && plugin->getMidiOutputChannel() == i);
   }
   menu.addSubMenu (T("Filter synth input MIDI channel"), synthMidiChanMenu);
   menu.addSubMenu (T("Filter output MIDI channel"), midiChanMenu);
   menu.addSeparator ();

    int inputLinks = node->getInputLinksCount ();
    int outputLinks = node->getOutputLinksCount ();

    if (inputLinks > 0 && outputLinks > 0)
        menu.addItem (8, "Disconnect all");
    if (inputLinks > 0)
        menu.addItem (9, "Disconnect inputs");
    if (outputLinks > 0)
        menu.addItem (10, "Disconnect outputs");

   menu.addItem (11, String("Rename \"") + plugin->getInstanceName() + String("\""));
   menu.addItem (12, "Render stem", true, plugin->getBoolValue(PROP_RENDERSTEM, false)); // only allow changing this if stems aren't rendering right now (i.e. files aren't opened)
   
    const int result = menu.show();
    switch (result)
    {
    case 1: // Open editor
        {
            owner->openPluginEditorWindow (plugin);
            break;
        }
    case 2: // set preferred editor
      plugin->setValue(PROP_WINDOWPREFERGENERIC, !plugin->getBoolValue(PROP_WINDOWPREFERGENERIC, false));
      break;
    case 12: // set stem render option
      plugin->setValue(PROP_RENDERSTEM, !plugin->getBoolValue(PROP_RENDERSTEM, false));
      break;
    case 3: // Close
        {
            if (owner->isPluginEditorWindowOpen (plugin))
                owner->closePluginEditorWindow (plugin);

            if (plugin)
            {
                host->closePlugin (plugin);

                selectedNodes.deselect (node);
                deletePluginNode (node);

                graphChanged ();
            }

            break;
        }
    case 4: // Lock / unlock
        {
            bool lockedState = ! node->isLocked ();

            if (plugin)
                plugin->setValue (PROP_GRAPHLOCKED, lockedState);

            node->setLocked (lockedState);
            node->repaint ();
        }
        break;
    case 5: // Mute
        {
            if (plugin)
                plugin->setMuted (! plugin->isMuted());
        }
        break;
    case 6: // Bypass
        {
            if (plugin)
                plugin->setBypass (! plugin->isBypass());
        }
        break;
    case 7: // Solo (TODO)
        break;
    case 8: // Disconnect all
        node->breakAllLinks();
        break;
    case 9: // Disconnect inputs
        node->breakInputLinks();
        break;
    case 10: // Disconnect outputs
        node->breakOutputLinks();
        break;
    case 11: // Rename instance
    {
      TextEditor instanceName(String("renamePluginInstance"));
      instanceName.setSize(400, 30);
      instanceName.setText(plugin->getInstanceName());
      DialogWindow::showModalDialog(String("Rename " + plugin->getInstanceName()), &instanceName, node, Colours::yellow, true);
      String newName = instanceName.getText();
      if (newName.isNotEmpty())
         setNodeDisplayName(plugin, node, newName);
    }
      break;
   case 1020:
      plugin->clearMidiOutputFilter();
      break;
   case 2020:
      plugin->clearSynthInputFilter();
      break;
    default:
      if (result >= 1001 && result <= 1016)
         plugin->setMidiOutputChannelFilter(result - 1000);
      if (result >= 2001 && result <= 2016)
         plugin->setSynthInputChannelFilter(result - 2000);
      break;
    }
    
    currentClickedNode = 0;
}