void TabWidget::floatPane(QPoint* position){ QMutexLocker l(&_tabWidgetStateMutex); _isFloating = true; FloatingWidget* floatingW = new FloatingWidget(_gui); setVisible(false); setParent(0); floatingW->setWidget(size(),this); if (position) { floatingW->move(*position); } }
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