ViewerTab::~ViewerTab() { _imp->cachedFramesThread->quitThread(); Gui* gui = getGui(); if (gui) { NodeGraph* graph = 0; ViewerNodePtr internalNode = getInternalNode(); if (internalNode) { NodeCollectionPtr collection = internalNode->getNode()->getGroup(); if (collection) { NodeGroupPtr isGrp = toNodeGroup(collection); if (isGrp) { NodeGraphI* graph_i = isGrp->getNodeGraph(); if (graph_i) { graph = dynamic_cast<NodeGraph*>(graph_i); assert(graph); } } else { graph = gui->getNodeGraph(); } } internalNode->invalidateUiContext(); } else { graph = gui->getNodeGraph(); } assert(graph); GuiAppInstancePtr app = gui->getApp(); if ( app && !app->isClosing() && graph && (graph->getLastSelectedViewer() == this) ) { graph->setLastSelectedViewer(0); } } _imp->nodesContext.clear(); }
bool ViewerTab::eventFilter(QObject *target, QEvent* e) { if (e->type() == QEvent::MouseButtonPress) { Gui* gui = getGui(); if (gui) { GuiAppInstancePtr app = gui->getApp(); if (app) { ViewerNodePtr viewerNode = _imp->viewerNode.lock(); if (viewerNode) { NodeGuiIPtr nodegui_i = viewerNode->getNode()->getNodeGui(); assert(nodegui_i); NodeGuiPtr nodegui = boost::dynamic_pointer_cast<NodeGui>(nodegui_i); gui->selectNode(nodegui); } } } } return QWidget::eventFilter(target, e); }
void ViewerTab::keyPressEvent(QKeyEvent* e) { ViewerNodePtr internalNode = getInternalNode(); if (!internalNode || !internalNode->getNode()) { return; } //qDebug() << "ViewerTab::keyPressed:" << e->text() << "modifiers:" << e->modifiers(); Gui* gui = getGui(); if (gui) { gui->setActiveViewer(this); } bool accept = true; Qt::KeyboardModifiers modifiers = e->modifiers(); Qt::Key key = (Qt::Key)Gui::handleNativeKeys( e->key(), e->nativeScanCode(), e->nativeVirtualKey() ); double scale = 1. / ( 1 << _imp->viewer->getCurrentRenderScale() ); if ( e->isAutoRepeat() && notifyOverlaysKeyRepeat(RenderScale(scale), e) ) { update(); } else if ( notifyOverlaysKeyDown(RenderScale(scale), e) ) { update(); } else if ( isKeybind(kShortcutGroupGlobal, kShortcutIDActionConnectViewerToInput1, modifiers, key) ) { connectToAInput(0); } else if ( isKeybind(kShortcutGroupGlobal, kShortcutIDActionConnectViewerToInput2, modifiers, key) ) { connectToAInput(1); } else if ( isKeybind(kShortcutGroupGlobal, kShortcutIDActionConnectViewerToInput3, modifiers, key) ) { connectToAInput(2); } else if ( isKeybind(kShortcutGroupGlobal, kShortcutIDActionConnectViewerToInput4, modifiers, key) ) { connectToAInput(3); } else if ( isKeybind(kShortcutGroupGlobal, kShortcutIDActionConnectViewerToInput5, modifiers, key) ) { connectToAInput(4); } else if ( isKeybind(kShortcutGroupGlobal, kShortcutIDActionConnectViewerToInput6, modifiers, key) ) { connectToAInput(5); } else if ( isKeybind(kShortcutGroupGlobal, kShortcutIDActionConnectViewerToInput7, modifiers, key) ) { connectToAInput(6); } else if ( isKeybind(kShortcutGroupGlobal, kShortcutIDActionConnectViewerToInput8, modifiers, key) ) { connectToAInput(7); } else if ( isKeybind(kShortcutGroupGlobal, kShortcutIDActionConnectViewerToInput9, modifiers, key) ) { connectToAInput(8); } else if ( isKeybind(kShortcutGroupGlobal, kShortcutIDActionConnectViewerToInput10, modifiers, key) ) { connectToAInput(9); } else if ( isKeybind(kShortcutGroupGlobal, kShortcutIDActionConnectViewerBToInput1, modifiers, key) ) { connectToBInput(0); } else if ( isKeybind(kShortcutGroupGlobal, kShortcutIDActionConnectViewerBToInput2, modifiers, key) ) { connectToBInput(1); } else if ( isKeybind(kShortcutGroupGlobal, kShortcutIDActionConnectViewerBToInput3, modifiers, key) ) { connectToBInput(2); } else if ( isKeybind(kShortcutGroupGlobal, kShortcutIDActionConnectViewerBToInput4, modifiers, key) ) { connectToBInput(3); } else if ( isKeybind(kShortcutGroupGlobal, kShortcutIDActionConnectViewerBToInput5, modifiers, key) ) { connectToBInput(4); } else if ( isKeybind(kShortcutGroupGlobal, kShortcutIDActionConnectViewerBToInput6, modifiers, key) ) { connectToBInput(5); } else if ( isKeybind(kShortcutGroupGlobal, kShortcutIDActionConnectViewerBToInput7, modifiers, key) ) { connectToBInput(6); } else if ( isKeybind(kShortcutGroupGlobal, kShortcutIDActionConnectViewerBToInput8, modifiers, key) ) { connectToBInput(7); } else if ( isKeybind(kShortcutGroupGlobal, kShortcutIDActionConnectViewerBToInput9, modifiers, key) ) { connectToBInput(8); } else if ( isKeybind(kShortcutGroupGlobal, kShortcutIDActionConnectViewerBToInput10, modifiers, key) ) { connectToBInput(9); } else if (key == Qt::Key_Escape) { _imp->viewer->s_selectionCleared(); update(); } else { accept = false; } if (accept) { takeClickFocus(); e->accept(); } else { handleUnCaughtKeyPressEvent(e); QWidget::keyPressEvent(e); } } // keyPressEvent
NATRON_NAMESPACE_ENTER ViewerTab::ViewerTab(const std::string& scriptName, const std::list<NodeGuiPtr> & existingNodesContext, const std::list<NodeGuiPtr>& activePluginsContext, Gui* gui, const NodeGuiPtr& node_ui, QWidget* parent) : QWidget(parent) , PanelWidget(scriptName, this, gui) , _imp( new ViewerTabPrivate(this, node_ui) ) { ViewerNodePtr node = node_ui->getNode()->isEffectViewerNode(); installEventFilter(this); setMouseTracking(true); NodePtr internalNode = node->getNode(); QObject::connect( internalNode.get(), SIGNAL(scriptNameChanged(QString)), this, SLOT(onInternalNodeScriptNameChanged(QString)) ); QObject::connect( internalNode.get(), SIGNAL(labelChanged(QString,QString)), this, SLOT(onInternalNodeLabelChanged(QString,QString)) ); QObject::connect( node.get(), SIGNAL(internalViewerCreated()), this, SLOT(onInternalViewerCreated())); _imp->mainLayout = new QVBoxLayout(this); setLayout(_imp->mainLayout); _imp->mainLayout->setSpacing(0); _imp->mainLayout->setContentsMargins(0, 0, 0, 0); QFontMetrics fm(font(), 0); _imp->viewerContainer = new QWidget(this); _imp->viewerLayout = new QHBoxLayout(_imp->viewerContainer); _imp->viewerLayout->setContentsMargins(0, 0, 0, 0); _imp->viewerLayout->setSpacing(0); _imp->viewerSubContainer = new QWidget(_imp->viewerContainer); _imp->viewerSubContainerLayout = new QVBoxLayout(_imp->viewerSubContainer); _imp->viewerSubContainerLayout->setContentsMargins(0, 0, 0, 0); _imp->viewerSubContainerLayout->setSpacing(1); // Info bars QString inputNames[2] = { QString::fromUtf8("A:"), QString::fromUtf8("B:") }; bool infobarvisible = node->isInfoBarVisible(); for (int i = 0; i < 2; ++i) { _imp->infoWidget[i] = new InfoViewerWidget(inputNames[i], this); } // Viewer _imp->viewer = new ViewerGL(this); GuiAppInstancePtr app = gui->getApp(); // Init viewer to project format { Format projectFormat; app->getProject()->getProjectDefaultFormat(&projectFormat); RectD canonicalFormat = projectFormat.toCanonicalFormat(); for (int i = 0; i < 2; ++i) { _imp->viewer->setInfoViewer(_imp->infoWidget[i], i); _imp->viewer->setRegionOfDefinition(canonicalFormat, projectFormat.getPixelAspectRatio(), i); setInfoBarAndViewerResolution(projectFormat, canonicalFormat, projectFormat.getPixelAspectRatio(), i); } _imp->viewer->resetWipeControls(); } _imp->viewerSubContainerLayout->addWidget(_imp->viewer); for (int i = 0; i < 2; ++i) { _imp->viewerSubContainerLayout->addWidget(_imp->infoWidget[i]); _imp->viewer->setInfoViewer(_imp->infoWidget[i], i); if (i == 1 || !infobarvisible) { _imp->infoWidget[i]->hide(); } } manageSlotsForInfoWidget(0, true); _imp->viewerLayout->addWidget(_imp->viewerSubContainer); _imp->mainLayout->addWidget(_imp->viewerContainer); TimeLinePtr timeline = app->getTimeLine(); _imp->timeLineGui = new TimeLineGui(node, timeline, getGui(), this); QObject::connect( _imp->timeLineGui, SIGNAL(boundariesChanged(SequenceTime,SequenceTime)), this, SLOT(onTimelineBoundariesChanged(SequenceTime,SequenceTime)) ); QObject::connect( app->getProject().get(), SIGNAL(frameRangeChanged(int,int)), _imp->timeLineGui, SLOT(onProjectFrameRangeChanged(int,int)) ); _imp->timeLineGui->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Minimum); if (!node->isTimelineVisible()) { _imp->timeLineGui->hide(); } //Add some spacing because the timeline might be black as the info _imp->mainLayout->addSpacing( TO_DPIY(5) ); _imp->mainLayout->addWidget(_imp->timeLineGui); double leftBound, rightBound; leftBound = node->getPlaybackInPointKnob()->getValue(); rightBound = node->getPlaybackOutPointKnob()->getValue(); TimeValue projectLeft, projectRight; app->getProject()->getFrameRange(&projectLeft, &projectRight); _imp->timeLineGui->setBoundaries(leftBound, rightBound); onTimelineBoundariesChanged(leftBound, rightBound); _imp->timeLineGui->setFrameRangeEdited(projectLeft != leftBound || projectRight != rightBound);; manageTimelineSlot(false, timeline); QObject::connect( node.get(), SIGNAL(renderStatsAvailable(int,double,RenderStatsMap)), this, SLOT(onRenderStatsAvailable(int,double,RenderStatsMap)) ); QObject::connect( _imp->viewer, SIGNAL(zoomChanged(int)), this, SLOT(updateZoomComboBox(int)) ); QObject::connect( node.get(), SIGNAL(viewerDisconnected()), this, SLOT(disconnectViewer()) ); createNodeViewerInterface(node_ui); setPluginViewerInterface(node_ui); for (std::list<NodeGuiPtr>::const_iterator it = existingNodesContext.begin(); it != existingNodesContext.end(); ++it) { ViewerNodePtr isViewerNode = (*it)->getNode()->isEffectViewerNode(); // For viewers, create the viewer interface separately if (!isViewerNode) { createNodeViewerInterface(*it); } } for (std::list<NodeGuiPtr>::const_iterator it = activePluginsContext.begin(); it != activePluginsContext.end(); ++it) { ViewerNodePtr isViewerNode = (*it)->getNode()->isEffectViewerNode(); // For viewers, create the viewer interface separately if (!isViewerNode) { setPluginViewerInterface(*it); } } setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Preferred); _imp->viewerNode.lock()->setUiContext( getViewer() ); QTimer::singleShot( 25, _imp->timeLineGui, SLOT(recenterOnBounds()) ); //Refresh the viewport lock state const std::list<ViewerTab*>& viewers = getGui()->getViewersList(); if ( !viewers.empty() ) { ViewerTab* other = viewers.front(); if ( other->getInternalNode()->isViewersSynchroEnabled() ) { double left, bottom, factor, par; other->getViewer()->getProjection(&left, &bottom, &factor, &par); _imp->viewer->setProjection(left, bottom, factor, par); node->setViewersSynchroEnabled(true); } } _imp->cachedFramesThread.reset(new CachedFramesThread(this)); _imp->cachedFramesThread->start(); }
ViewerTab* Gui::addNewViewerTab(const NodeGuiPtr& node, TabWidget* where) { if (!node) { return 0; } ViewerNodePtr viewer = node->getNode()->isEffectViewerNode(); NodesGuiList activeNodeViewerUi, nodeViewerUi; //Don't create tracker & roto interface for file dialog preview viewer NodeCollectionPtr group = viewer->getNode()->getGroup(); if (group) { if ( !_imp->_viewerTabs.empty() ) { ( *_imp->_viewerTabs.begin() )->getNodesViewerInterface(&nodeViewerUi, &activeNodeViewerUi); } else { NodeGraph* graph = dynamic_cast<NodeGraph*>( group->getNodeGraph() ); if (!graph) { graph = _imp->_nodeGraphArea; } if (graph) { const NodesGuiList & allNodes = graph->getAllActiveNodes(); std::set<std::string> activeNodesPluginID; for (NodesGuiList::const_iterator it = allNodes.begin(); it != allNodes.end(); ++it) { nodeViewerUi.push_back( *it ); std::string pluginID = (*it)->getNode()->getPluginID(); std::set<std::string>::iterator found = activeNodesPluginID.find(pluginID); if ( found == activeNodesPluginID.end() ) { activeNodesPluginID.insert(pluginID); activeNodeViewerUi.push_back(*it); } } } } } std::string nodeName = node->getNode()->getFullyQualifiedName(); for (std::size_t i = 0; i < nodeName.size(); ++i) { if (nodeName[i] == '.') { nodeName[i] = '_'; } } std::string label; NodeGraph::makeFullyQualifiedLabel(node->getNode(), &label); ViewerTab* tab = new ViewerTab(nodeName, nodeViewerUi, activeNodeViewerUi, this, node, where); tab->setLabel(label); QObject::connect( tab->getViewer(), SIGNAL(imageChanged(int,bool)), this, SLOT(onViewerImageChanged(int,bool)) ); { QMutexLocker l(&_imp->_viewerTabsMutex); _imp->_viewerTabs.push_back(tab); if (!_imp->_activeViewer) { _imp->_activeViewer = tab; } } where->appendTab(tab, tab); Q_EMIT viewersChanged(); return tab; } // Gui::addNewViewerTab