void Gui::restoreLayout(bool wipePrevious, bool enableOldProjectCompatibility, const GuiLayoutSerialization & layoutSerialization) { ///Wipe the current layout if (wipePrevious) { wipeLayout(); } ///For older projects prior to the layout change, just set default layout. if (enableOldProjectCompatibility) { createDefaultLayout1(); } else { std::list<ApplicationWindowSerialization*> floatingDockablePanels; QDesktopWidget* desktop = QApplication::desktop(); QRect screen = desktop->screenGeometry(); ///now restore the gui layout for (std::list<ApplicationWindowSerialization*>::const_iterator it = layoutSerialization._windows.begin(); it != layoutSerialization._windows.end(); ++it) { QWidget* mainWidget = 0; ///The window contains only a pane (for the main window it also contains the toolbar) if ( (*it)->child_asPane ) { TabWidget* centralWidget = new TabWidget(this); registerPane(centralWidget); restoreTabWidget(centralWidget, *(*it)->child_asPane); mainWidget = centralWidget; } ///The window contains a splitter as central widget else if ( (*it)->child_asSplitter ) { Splitter* centralWidget = new Splitter(this); restoreSplitterRecursive(this, centralWidget, *(*it)->child_asSplitter); mainWidget = centralWidget; } ///The child is a dockable panel, restore it later else if ( !(*it)->child_asDockablePanel.empty() ) { assert(!(*it)->isMainWindow); floatingDockablePanels.push_back(*it); continue; } assert(mainWidget); if (!mainWidget) { continue; } QWidget* window; if ( (*it)->isMainWindow ) { // mainWidget->setParent(_imp->_leftRightSplitter); _imp->_leftRightSplitter->addWidget_mt_safe(mainWidget); window = this; } else { FloatingWidget* floatingWindow = new FloatingWidget(this, this); floatingWindow->setWidget(mainWidget); registerFloatingWindow(floatingWindow); window = floatingWindow; } ///Restore geometry int w = std::min( (*it)->w, screen.width() ); int h = std::min( (*it)->h, screen.height() ); window->resize(w, h); // If the screen size changed, make sure at least 50x50 pixels of the window are visible int x = boost::algorithm::clamp( (*it)->x, screen.left(), screen.right() - 50 ); int y = boost::algorithm::clamp( (*it)->y, screen.top(), screen.bottom() - 50 ); window->move( QPoint(x, y) ); } for (std::list<ApplicationWindowSerialization*>::iterator it = floatingDockablePanels.begin(); it != floatingDockablePanels.end(); ++it) { ///Find the node associated to the floating panel if any and float it assert( !(*it)->child_asDockablePanel.empty() ); if ( (*it)->child_asDockablePanel == kNatronProjectSettingsPanelSerializationName ) { _imp->_projectGui->getPanel()->floatPanel(); } else { ///Find a node with the dockable panel name const NodesGuiList & nodes = getNodeGraph()->getAllActiveNodes(); DockablePanel* panel = 0; for (NodesGuiList::const_iterator it2 = nodes.begin(); it2 != nodes.end(); ++it2) { if ( (*it2)->getNode()->getScriptName() == (*it)->child_asDockablePanel ) { (*it2)->ensurePanelCreated(); NodeSettingsPanel* nodeSettings = (*it2)->getSettingPanel(); if (nodeSettings) { nodeSettings->floatPanel(); panel = nodeSettings; } break; } } if (panel) { FloatingWidget* fWindow = 0; QWidget* w = panel->parentWidget(); while (!fWindow && w) { fWindow = dynamic_cast<FloatingWidget*>(w); w = w->parentWidget(); } assert(fWindow); fWindow->move( QPoint( (*it)->x, (*it)->y ) ); fWindow->resize( std::min( (*it)->w, screen.width() ), std::min( (*it)->h, screen.height() ) ); } } } } } // restoreLayout
void Gui::removeViewerTab(ViewerTab* tab, bool initiatedFromNode, bool deleteData) { assert(tab); unregisterTab(tab); if (tab == _imp->_activeViewer) { _imp->_activeViewer = 0; } NodeGraph* graph = 0; NodeGroupPtr isGrp; NodeCollectionPtr collection; if ( tab->getInternalNode() && tab->getInternalNode()->getNode() ) { NodeCollectionPtr collection = tab->getInternalNode()->getNode()->getGroup(); isGrp = toNodeGroup(collection); } if (isGrp) { NodeGraphI* graph_i = isGrp->getNodeGraph(); assert(graph_i); graph = dynamic_cast<NodeGraph*>(graph_i); } else { graph = getNodeGraph(); } assert(graph); if (!graph) { throw std::logic_error(""); } ViewerTab* lastSelectedViewer = graph->getLastSelectedViewer(); if (lastSelectedViewer == tab) { bool foundOne = false; NodesList nodes; if (collection) { nodes = collection->getNodes(); } for (NodesList::iterator it = nodes.begin(); it != nodes.end(); ++it) { ViewerNodePtr isViewer = (*it)->isEffectViewerNode(); if ( !isViewer || ( isViewer == tab->getInternalNode() ) || !(*it)->isActivated() ) { continue; } OpenGLViewerI* viewerI = isViewer->getUiContext(); assert(viewerI); ViewerGL* glViewer = dynamic_cast<ViewerGL*>(viewerI); assert(glViewer); if (glViewer) { graph->setLastSelectedViewer( glViewer->getViewerTab() ); } foundOne = true; break; } if (!foundOne) { graph->setLastSelectedViewer(0); } } ViewerNodePtr viewerNode = tab->getInternalNode(); ViewerInstancePtr internalViewer; if (viewerNode) { internalViewer = viewerNode->getInternalViewerNode(); } if (internalViewer) { internalViewer->abortAnyEvaluation(); if (getApp()->getLastViewerUsingTimeline() == internalViewer) { getApp()->discardLastViewerUsingTimeline(); } } if (!initiatedFromNode) { assert(_imp->_nodeGraphArea); ///call the deleteNode which will call this function again when the node will be deactivated. NodePtr internalNode = tab->getInternalNode()->getNode(); NodeGuiIPtr guiI = internalNode->getNodeGui(); NodeGuiPtr gui = boost::dynamic_pointer_cast<NodeGui>(guiI); assert(gui); NodeGraphI* graph_i = internalNode->getGroup()->getNodeGraph(); assert(graph_i); NodeGraph* graph = dynamic_cast<NodeGraph*>(graph_i); assert(graph); if (graph) { graph->removeNode(gui); } } else { tab->hide(); TabWidget* container = dynamic_cast<TabWidget*>( tab->parentWidget() ); if (container) { container->removeTab(tab, false); } if (deleteData) { QMutexLocker l(&_imp->_viewerTabsMutex); std::list<ViewerTab*>::iterator it = std::find(_imp->_viewerTabs.begin(), _imp->_viewerTabs.end(), tab); if ( it != _imp->_viewerTabs.end() ) { _imp->_viewerTabs.erase(it); } tab->notifyGuiClosingPublic(); tab->deleteLater(); } } Q_EMIT viewersChanged(); } // Gui::removeViewerTab