void GraphComponent::nodeSelected (GraphNodeComponent* node) { DBG ("GraphComponent::nodeSelected"); jassert (node != 0) switch (selectedNodes.getNumSelected ()) { case 0: // no items selected { BasePlugin* plugin = (BasePlugin*) node->getUserData (); if (plugin) plugin->setValue (PROP_GRAPHSELECTED, 1); selectedNodes.addToSelection (node); node->repaint (); } break; default: // one or more items selected { if (! selectedNodes.isSelected (node)) { for (int i = 0; i < selectedNodes.getNumSelected (); i++) { GraphNodeComponent* selected = selectedNodes.getSelectedItem (i); BasePlugin* plugin = (BasePlugin*) selected->getUserData (); if (plugin) plugin->setValue (PROP_GRAPHSELECTED, 0); selected->repaint (); } selectedNodes.deselectAll (); BasePlugin* plugin = (BasePlugin*) node->getUserData (); if (plugin) plugin->setValue (PROP_GRAPHSELECTED, 1); selectedNodes.addToSelection (node); node->repaint (); } } break; } }
bool GraphComponent::loadAndAppendPlugin (const File& file, int mouseX, int mouseY) { DBG ("GraphComponent::loadAndAppendPlugin"); jassert (host != 0); BasePlugin* plugin = host->loadPlugin (file); if (plugin) { Config::getInstance ()->addRecentPlugin (file); plugin->setValue(PROP_GRAPHXPOS, mouseX); plugin->setValue(PROP_GRAPHYPOS, mouseY); host->addPlugin (plugin); createPluginNode (plugin); return true; } return false; }
void GraphComponent::mouseUp (const MouseEvent& e) { if (e.mods.isLeftButtonDown()) { lassoComponent->endLasso (); } else if (e.mods.isMiddleButtonDown ()) { } else if (e.mods.isRightButtonDown ()) { // try to open internal plugins BasePlugin* newPlugin = PluginLoader::handlePopupMenu (false, 0, owner->getFilter()); // now open plugin if (host && newPlugin) { host->openPlugin (newPlugin); host->addPlugin (newPlugin); newPlugin->setValue (PROP_GRAPHXPOS, e.x); newPlugin->setValue (PROP_GRAPHYPOS, e.y); createPluginNode (newPlugin); } } lassoComponent->endLasso (); setMouseCursor (MouseCursor::NormalCursor); }
void GraphComponent::nodeMoved (GraphNodeComponent* node, const int deltaX, const int deltaY) { // DBG ("GraphComponent::nodeMoved " + String (deltaX) + " " + String (deltaY)); jassert (node != 0); for (int i = 0; i < selectedNodes.getNumSelected (); i++) { GraphNodeComponent* selected = selectedNodes.getSelectedItem (i); if (selected && selected != node && ! selected->isLocked ()) { BasePlugin* plugin = (BasePlugin*) selected->getUserData (); if (plugin) { int x = selected->getX() + deltaX; int y = selected->getY() + deltaY; x = jmax (0, jmin (getWidth () - selected->getWidth(), x)); y = jmax (0, jmin (getHeight () - selected->getHeight(), y)); plugin->setValue (PROP_GRAPHXPOS, x); plugin->setValue (PROP_GRAPHYPOS, y); selected->setTopLeftPosition (x, y); } } } BasePlugin* plugin = (BasePlugin*) node->getUserData (); if (plugin) { plugin->setValue (PROP_GRAPHXPOS, node->getX()); plugin->setValue (PROP_GRAPHYPOS, node->getY()); } Viewport* parent = findParentComponentOfClass ((Viewport*) 0); if (parent) { parent->notifyComponentChanged (); } }
//============================================================================== void GraphComponent::changeListenerCallback (void* source) { ColourSelector* cs = (ColourSelector*) source; if (currentClickedNode) { Colour currentColour = cs->getCurrentColour(); BasePlugin* plugin = (BasePlugin*) currentClickedNode->getUserData (); if (plugin) plugin->setValue (PROP_GRAPHCOLOUR, currentColour.toString ()); currentClickedNode->setNodeColour (currentColour); currentClickedNode->repaint (); Viewport* parent = findParentComponentOfClass ((Viewport*) 0); if (parent) { parent->notifyComponentChanged (); } } }
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; }