LayoutWnd.cpp 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include "EditorDefs.h"
  9. #include "LayoutWnd.h"
  10. // Qt
  11. #include <QMessageBox>
  12. #include <QToolBar>
  13. #include <QComboBox>
  14. #include <QLabel>
  15. #include <QLineEdit>
  16. #include <QTextDocumentFragment>
  17. #include <AzCore/Interface/Interface.h>
  18. #include <AzQtComponents/Components/Style.h> // for AzQtComponents::Style
  19. // Editor
  20. #include "MainWindow.h"
  21. #include "ViewPane.h"
  22. #include "QtViewPaneManager.h"
  23. #include "ViewManager.h"
  24. #include <AzQtComponents/Components/Style.h>
  25. class CLayoutSplitterHandle
  26. : public QSplitterHandle
  27. {
  28. public:
  29. CLayoutSplitterHandle(Qt::Orientation orientation, CLayoutSplitter* parent)
  30. : QSplitterHandle(orientation, parent)
  31. {
  32. }
  33. protected:
  34. void paintEvent(QPaintEvent*) override
  35. {
  36. // draw nothing for flat look
  37. }
  38. };
  39. /////////////////////////////////////////////////////////////////////////////
  40. // CLayoutSplitter
  41. //////////////////////////////////////////////////////////////////////////
  42. CLayoutSplitter::CLayoutSplitter(QWidget* parent)
  43. : QSplitter(parent)
  44. {
  45. }
  46. CLayoutSplitter::~CLayoutSplitter()
  47. {
  48. }
  49. QSplitterHandle* CLayoutSplitter::createHandle()
  50. {
  51. return new CLayoutSplitterHandle(orientation(), this);
  52. }
  53. //////////////////////////////////////////////////////////////////////////
  54. void CLayoutSplitter::resizeEvent(QResizeEvent* event)
  55. {
  56. QSplitter::resizeEvent(event);
  57. // only the top level splitter should trigger resetting the layout when being resized
  58. if (qobject_cast<CLayoutSplitter*>(parentWidget()) == nullptr)
  59. {
  60. for (CLayoutSplitter* s : findChildren<CLayoutSplitter*>())
  61. {
  62. s->setSizes(QList<int>::fromVector(QVector<int>(s->count(), (s->orientation() == Qt::Horizontal ? s->width() : s->height()) / s->count())));
  63. }
  64. setSizes(QList<int>::fromVector(QVector<int>(count(), (orientation() == Qt::Horizontal ? width() : height()) / count())));
  65. }
  66. }
  67. //////////////////////////////////////////////////////////////////////////
  68. void CLayoutSplitter::CreateLayoutView(int row, int col, int id)
  69. {
  70. assert(row >= 0 && row < 3);
  71. assert(col >= 0 && col < 3);
  72. CLayoutViewPane* viewPane = new CLayoutViewPane(this);
  73. viewPane->setWindowFlags(Qt::Widget);
  74. insertWidget(orientation() == Qt::Horizontal ? col : row, viewPane);
  75. viewPane->SetId(id);
  76. }
  77. //////////////////////////////////////////////////////////////////////////
  78. // CLayoutWnd
  79. //////////////////////////////////////////////////////////////////////////
  80. CLayoutWnd::CLayoutWnd(QSettings* settings, QWidget* parent)
  81. : AzQtComponents::ToolBarArea(parent)
  82. , m_settings(settings)
  83. {
  84. m_bMaximized = false;
  85. m_maximizedView = nullptr;
  86. m_layout = (EViewLayout) - 1;
  87. m_maximizedViewId = 0;
  88. m_infoBarSize = QSize(0, 0);
  89. connect(qApp, &QApplication::focusChanged, this, &CLayoutWnd::OnFocusChanged);
  90. setContextMenuPolicy(Qt::NoContextMenu);
  91. }
  92. //////////////////////////////////////////////////////////////////////////
  93. CLayoutWnd::~CLayoutWnd()
  94. {
  95. delete m_splitWnd;
  96. delete m_splitWnd2;
  97. delete m_splitWnd3;
  98. OnDestroy();
  99. }
  100. //////////////////////////////////////////////////////////////////////////
  101. void CLayoutWnd::UnbindViewports()
  102. {
  103. // First unbind all views.
  104. for (int i = 0; i < MAX_VIEWPORTS; i++)
  105. {
  106. CLayoutViewPane* pViewPane = GetViewPane(i);
  107. if (pViewPane)
  108. {
  109. pViewPane->ReleaseViewport();
  110. }
  111. }
  112. if (m_maximizedView)
  113. {
  114. m_maximizedView->ReleaseViewport();
  115. }
  116. }
  117. //////////////////////////////////////////////////////////////////////////
  118. void CLayoutWnd::BindViewports()
  119. {
  120. // First unbind all views.
  121. UnbindViewports();
  122. for (int i = 0; i < MAX_VIEWPORTS; i++)
  123. {
  124. CLayoutViewPane* pViewPane = GetViewPane(i);
  125. if (pViewPane)
  126. {
  127. BindViewport(pViewPane, m_viewType[pViewPane->GetId()]);
  128. }
  129. }
  130. FocusFirstLayoutViewPane(m_splitWnd);
  131. }
  132. //////////////////////////////////////////////////////////////////////////
  133. void CLayoutWnd::BindViewport(CLayoutViewPane* vp, const QString& viewClassName, QWidget* pViewport)
  134. {
  135. assert(vp);
  136. if (!pViewport)
  137. {
  138. vp->SetViewClass(viewClassName);
  139. }
  140. else
  141. {
  142. vp->AttachViewport(pViewport);
  143. }
  144. vp->setVisible(true);
  145. m_viewType[vp->GetId()] = viewClassName;
  146. }
  147. //////////////////////////////////////////////////////////////////////////
  148. void CLayoutWnd::MaximizeViewport(int paneId)
  149. {
  150. // Ignore with full screen layout.
  151. if (m_layout == ET_Layout0 && m_bMaximized)
  152. {
  153. return;
  154. }
  155. QString viewClass = m_viewType[paneId];
  156. if (!m_bMaximized)
  157. {
  158. CLayoutViewPane* pViewPane = GetViewPane(paneId);
  159. m_maximizedViewId = paneId;
  160. m_bMaximized = true;
  161. if (m_maximizedView)
  162. {
  163. if (m_splitWnd)
  164. {
  165. m_splitWnd->setVisible(false);
  166. }
  167. if (pViewPane)
  168. {
  169. MoveViewport(pViewPane, m_maximizedView, viewClass);
  170. }
  171. else
  172. {
  173. BindViewport(m_maximizedView, viewClass);
  174. }
  175. m_maximizedView->setFocus();
  176. SetMainWidget(m_maximizedView);
  177. m_maximizedView->setVisible(true);
  178. MainWindow::instance()->SetActiveView(m_maximizedView);
  179. }
  180. }
  181. else
  182. {
  183. CLayoutViewPane* pViewPane = GetViewPane(m_maximizedViewId);
  184. m_bMaximized = false;
  185. m_maximizedViewId = 0;
  186. if (pViewPane && m_maximizedView)
  187. {
  188. MoveViewport(m_maximizedView, pViewPane, viewClass);
  189. }
  190. if (m_maximizedView)
  191. {
  192. m_maximizedView->setVisible(false);
  193. }
  194. if (m_splitWnd)
  195. {
  196. m_splitWnd->setVisible(true);
  197. SetMainWidget(m_splitWnd);
  198. FocusFirstLayoutViewPane(m_splitWnd);
  199. }
  200. }
  201. }
  202. QString CLayoutWnd::ViewportTypeToClassName(EViewportType viewType)
  203. {
  204. QtViewPane* pane = QtViewPaneManager::instance()->GetViewportPane(viewType);
  205. return pane ? pane->m_name : QString();
  206. }
  207. void CLayoutWnd::CreateLayoutView(CLayoutSplitter* wndSplitter, int row, int col, int id, EViewportType viewType)
  208. {
  209. QString viewClassName = ViewportTypeToClassName(viewType);
  210. wndSplitter->CreateLayoutView(row, col, id);
  211. m_viewType[id] = viewClassName;
  212. }
  213. //////////////////////////////////////////////////////////////////////////
  214. void CLayoutWnd::CreateLayout(EViewLayout layout, bool bBindViewports, EViewportType defaultView)
  215. {
  216. UnbindViewports();
  217. m_layout = layout;
  218. m_bMaximized = false;
  219. if (m_splitWnd)
  220. {
  221. m_splitWnd->setVisible(false);
  222. delete m_splitWnd;
  223. }
  224. delete m_splitWnd2;
  225. delete m_splitWnd3;
  226. if (m_maximizedView)
  227. {
  228. m_maximizedView->setVisible(false);
  229. }
  230. QRect rcView = rect();
  231. // Ensure we delete our old view immediately so it can relinquish its backing ViewportContext
  232. if (m_maximizedView)
  233. {
  234. delete m_maximizedView;
  235. }
  236. m_maximizedView = new CLayoutViewPane(this);
  237. m_maximizedView->SetId(0);
  238. m_maximizedView->setGeometry(rcView);
  239. m_maximizedView->setVisible(false);
  240. m_maximizedView->SetFullscren(true);
  241. if (!CViewManager::IsMultiViewportEnabled())
  242. {
  243. m_viewType[0] = ViewportTypeToClassName(defaultView);
  244. if (bBindViewports)
  245. {
  246. MaximizeViewport(0);
  247. }
  248. }
  249. else
  250. {
  251. switch (layout)
  252. {
  253. case ET_Layout0:
  254. m_viewType[0] = ViewportTypeToClassName(defaultView);
  255. if (bBindViewports)
  256. {
  257. MaximizeViewport(0);
  258. }
  259. break;
  260. case ET_Layout1:
  261. m_splitWnd = new CLayoutSplitter(this);
  262. m_splitWnd->setOrientation(Qt::Horizontal);
  263. CreateLayoutView(m_splitWnd, 0, 0, 2, ET_ViewportCamera);
  264. CreateLayoutView(m_splitWnd, 0, 1, 1, defaultView);
  265. break;
  266. case ET_Layout2:
  267. m_splitWnd = new CLayoutSplitter(this);
  268. m_splitWnd->setOrientation(Qt::Vertical);
  269. CreateLayoutView(m_splitWnd, 0, 0, 2, ET_ViewportCamera);
  270. CreateLayoutView(m_splitWnd, 1, 0, 1, defaultView);
  271. break;
  272. case ET_Layout3:
  273. m_splitWnd = new CLayoutSplitter(this);
  274. m_splitWnd->setOrientation(Qt::Horizontal);
  275. CreateLayoutView(m_splitWnd, 0, 1, 1, defaultView);
  276. m_splitWnd2 = new CLayoutSplitter;
  277. m_splitWnd2->setOrientation(Qt::Vertical);
  278. m_splitWnd->insertWidget(0, m_splitWnd2);
  279. CreateLayoutView(m_splitWnd2, 0, 0, 2, ET_ViewportCamera);
  280. CreateLayoutView(m_splitWnd2, 1, 0, 3, ET_ViewportCamera);
  281. break;
  282. case ET_Layout4:
  283. m_splitWnd = new CLayoutSplitter(this);
  284. m_splitWnd->setOrientation(Qt::Horizontal);
  285. CreateLayoutView(m_splitWnd, 0, 0, 1, defaultView);
  286. m_splitWnd2 = new CLayoutSplitter;
  287. m_splitWnd2->setOrientation(Qt::Vertical);
  288. m_splitWnd->insertWidget(1, m_splitWnd2);
  289. CreateLayoutView(m_splitWnd2, 0, 0, 2, ET_ViewportCamera);
  290. CreateLayoutView(m_splitWnd2, 1, 0, 3, ET_ViewportCamera);
  291. break;
  292. case ET_Layout5:
  293. m_splitWnd = new CLayoutSplitter(this);
  294. m_splitWnd->setOrientation(Qt::Vertical);
  295. CreateLayoutView(m_splitWnd, 1, 0, 1, defaultView);
  296. m_splitWnd2 = new CLayoutSplitter;
  297. m_splitWnd2->setOrientation(Qt::Horizontal);
  298. m_splitWnd->insertWidget(0, m_splitWnd2);
  299. CreateLayoutView(m_splitWnd2, 0, 0, 2, ET_ViewportCamera);
  300. CreateLayoutView(m_splitWnd2, 0, 1, 3, ET_ViewportCamera);
  301. break;
  302. case ET_Layout6:
  303. m_splitWnd = new CLayoutSplitter(this);
  304. m_splitWnd->setOrientation(Qt::Vertical);
  305. CreateLayoutView(m_splitWnd, 0, 0, 1, defaultView);
  306. m_splitWnd2 = new CLayoutSplitter;
  307. m_splitWnd->insertWidget(1, m_splitWnd2);
  308. CreateLayoutView(m_splitWnd2, 0, 0, 2, ET_ViewportCamera);
  309. CreateLayoutView(m_splitWnd2, 0, 1, 3, ET_ViewportCamera);
  310. break;
  311. case ET_Layout7:
  312. m_splitWnd = new CLayoutSplitter(this);
  313. m_splitWnd->setOrientation(Qt::Horizontal);
  314. m_splitWnd2 = new CLayoutSplitter;
  315. m_splitWnd2->setOrientation(Qt::Vertical);
  316. m_splitWnd3 = new CLayoutSplitter;
  317. m_splitWnd3->setOrientation(Qt::Vertical);
  318. m_splitWnd->addWidget(m_splitWnd2);
  319. m_splitWnd->addWidget(m_splitWnd3);
  320. CreateLayoutView(m_splitWnd2, 0, 0, 2, ET_ViewportCamera);
  321. CreateLayoutView(m_splitWnd3, 0, 1, 3, ET_ViewportCamera);
  322. CreateLayoutView(m_splitWnd2, 1, 0, 4, ET_ViewportCamera);
  323. CreateLayoutView(m_splitWnd3, 1, 1, 1, defaultView);
  324. connect(m_splitWnd2, &QSplitter::splitterMoved, m_splitWnd3, &CLayoutSplitter::otherSplitterMoved);
  325. connect(m_splitWnd3, &QSplitter::splitterMoved, m_splitWnd2, &CLayoutSplitter::otherSplitterMoved);
  326. break;
  327. case ET_Layout8:
  328. m_splitWnd = new CLayoutSplitter(this);
  329. m_splitWnd->setOrientation(Qt::Vertical);
  330. CreateLayoutView(m_splitWnd, 1, 0, 1, defaultView);
  331. m_splitWnd2 = new CLayoutSplitter;
  332. m_splitWnd2->setOrientation(Qt::Horizontal);
  333. m_splitWnd->insertWidget(0, m_splitWnd2);
  334. CreateLayoutView(m_splitWnd2, 0, 0, 2, ET_ViewportCamera);
  335. CreateLayoutView(m_splitWnd2, 0, 1, 3, ET_ViewportCamera);
  336. CreateLayoutView(m_splitWnd2, 0, 2, 4, ET_ViewportCamera);
  337. break;
  338. default:
  339. CLogFile::FormatLine("Trying to Create Unknown Layout %d", (int)layout);
  340. QMessageBox::critical(this, QString(), tr("Trying to Create Unknown Layout"));
  341. break;
  342. }
  343. ;
  344. }
  345. if (m_splitWnd)
  346. {
  347. m_splitWnd->setGeometry(rcView);
  348. m_splitWnd->setVisible(true);
  349. FocusFirstLayoutViewPane(m_splitWnd);
  350. SetMainWidget(m_splitWnd);
  351. }
  352. if (bBindViewports && !m_bMaximized)
  353. {
  354. BindViewports();
  355. }
  356. }
  357. //////////////////////////////////////////////////////////////////////////
  358. void CLayoutWnd::SaveConfig()
  359. {
  360. QSettings settings;
  361. settings.beginGroup(GetConfigGroupName());
  362. settings.setValue("Layout", static_cast<int>(m_layout));
  363. settings.setValue("Maximized", m_maximizedViewId);
  364. QString str;
  365. for (int i = 1; i < MAX_VIEWPORTS; i++)
  366. {
  367. str += QString::fromLatin1("%1,").arg(m_viewType[i]);
  368. }
  369. settings.setValue("Viewports", str);
  370. }
  371. //////////////////////////////////////////////////////////////////////////
  372. bool CLayoutWnd::LoadConfig()
  373. {
  374. QSettings settings;
  375. settings.beginGroup(GetConfigGroupName());
  376. int layout = settings.value("Layout", -1).toInt();
  377. int maximizedView = settings.value("Maximized", 0).toInt();
  378. if (layout < 0)
  379. {
  380. return false;
  381. }
  382. CreateLayout((EViewLayout)layout, false);
  383. if (m_splitWnd)
  384. {
  385. const QString str = settings.value("Viewports").toString();
  386. int nIndex = 1;
  387. for (auto resToken : str.split(","))
  388. {
  389. if (nIndex >= MAX_VIEWPORTS)
  390. {
  391. break;
  392. }
  393. if (!resToken.isEmpty())
  394. {
  395. m_viewType[nIndex] = resToken;
  396. }
  397. nIndex++;
  398. }
  399. }
  400. BindViewports();
  401. if (maximizedView || layout == ET_Layout0)
  402. {
  403. MaximizeViewport(maximizedView);
  404. }
  405. return true;
  406. }
  407. //////////////////////////////////////////////////////////////////////////
  408. const char* CLayoutWnd::GetConfigGroupName()
  409. {
  410. return "ViewportLayout";
  411. }
  412. unsigned int CLayoutWnd::GetViewPaneCount()
  413. {
  414. // If there's a maximized viewport, then exactly 1 is visible.
  415. if (m_bMaximized)
  416. {
  417. return 1;
  418. }
  419. unsigned int numPanes = 0;
  420. // Otherwise, go searching through and count how many are visible.
  421. for (QSplitter* splitter : { m_splitWnd, m_splitWnd2, m_splitWnd3 })
  422. {
  423. if (splitter)
  424. {
  425. for (int i = 0; i < splitter->count(); ++i)
  426. {
  427. if (qobject_cast<CLayoutViewPane*>(splitter->widget(i)))
  428. {
  429. numPanes++;
  430. }
  431. }
  432. }
  433. }
  434. return numPanes;
  435. }
  436. CLayoutViewPane* CLayoutWnd::GetViewPaneByIndex(unsigned int index)
  437. {
  438. // If there's a maximized viewport, return it if index 0 is requested.
  439. // (All other index values are invalid in this state)
  440. if (m_bMaximized)
  441. {
  442. if (index == 0)
  443. {
  444. return m_maximizedView;
  445. }
  446. return nullptr;
  447. }
  448. unsigned int curIndex = 0;
  449. // Otherwise, go searching through until we've found the proper number of panes
  450. // and return the one at the correct index.
  451. for (QSplitter* splitter : { m_splitWnd, m_splitWnd2, m_splitWnd3 })
  452. {
  453. if (splitter)
  454. {
  455. for (int i = 0; i < splitter->count(); ++i)
  456. {
  457. if (QWidget* widget = splitter->widget(i))
  458. {
  459. if (CLayoutViewPane* pane = qobject_cast<CLayoutViewPane*>(widget))
  460. {
  461. if (curIndex == index)
  462. {
  463. return pane;
  464. }
  465. curIndex++;
  466. }
  467. }
  468. }
  469. }
  470. }
  471. return nullptr;
  472. }
  473. //////////////////////////////////////////////////////////////////////////
  474. CLayoutViewPane* CLayoutWnd::GetViewPane(int id)
  475. {
  476. QList<QSplitter*> splitters({ m_splitWnd, m_splitWnd2, m_splitWnd3 });
  477. for (QSplitter* splitter : splitters)
  478. {
  479. if (!splitter)
  480. {
  481. continue;
  482. }
  483. for (int i = 0; i < splitter->count(); ++i)
  484. {
  485. QWidget* widget = splitter->widget(i);
  486. if (widget == nullptr)
  487. {
  488. continue;
  489. }
  490. if (CLayoutViewPane* pane = qobject_cast<CLayoutViewPane*>(widget))
  491. {
  492. if (pane && pane->GetId() == id)
  493. {
  494. return pane;
  495. }
  496. }
  497. }
  498. }
  499. return nullptr;
  500. }
  501. //////////////////////////////////////////////////////////////////////////
  502. CLayoutViewPane* CLayoutWnd::FindViewByClass(const QString& viewClassName)
  503. {
  504. if (m_viewType[0] == viewClassName)
  505. {
  506. return m_maximizedView;
  507. }
  508. // Starts from 1, 0 is the maximized view.
  509. for (int i = 1; i < MAX_VIEWPORTS; i++)
  510. {
  511. if (m_viewType[i] == viewClassName)
  512. {
  513. return GetViewPane(i);
  514. }
  515. }
  516. return nullptr;
  517. }
  518. //////////////////////////////////////////////////////////////////////////
  519. bool CLayoutWnd::CycleViewport(EViewportType from, EViewportType to)
  520. {
  521. const QString viewClassName = ViewportTypeToClassName(from);
  522. CLayoutViewPane* vp = FindViewByClass(viewClassName);
  523. if (m_layout == ET_Layout0 && !vp)
  524. {
  525. if (m_maximizedView)
  526. {
  527. if (m_maximizedView->GetViewClass() == viewClassName)
  528. {
  529. vp = m_maximizedView;
  530. }
  531. }
  532. }
  533. if (vp)
  534. {
  535. BindViewport(vp, ViewportTypeToClassName(to));
  536. return true;
  537. }
  538. return false;
  539. }
  540. //////////////////////////////////////////////////////////////////////////
  541. void CLayoutWnd::ResetLayout()
  542. {
  543. // reset the layout settings. Mfc doesn't have a mechanism to delete settings, that I can find, so we use Qt.
  544. m_settings->beginGroup("Editor");
  545. m_settings->remove(GetConfigGroupName());
  546. m_settings->endGroup();
  547. // restore the default layout
  548. CreateLayout(ET_Layout0);
  549. }
  550. //////////////////////////////////////////////////////////////////////////
  551. void CLayoutWnd::Cycle2DViewport()
  552. {
  553. // Cycle between 3 2D viewports.
  554. switch (m_layout)
  555. {
  556. case ET_Layout0:
  557. if (CycleViewport(ET_ViewportCamera, ET_ViewportXY))
  558. {
  559. return;
  560. }
  561. if (CycleViewport(ET_ViewportXY, ET_ViewportXZ))
  562. {
  563. return;
  564. }
  565. if (CycleViewport(ET_ViewportXZ, ET_ViewportYZ))
  566. {
  567. return;
  568. }
  569. if (CycleViewport(ET_ViewportYZ, ET_ViewportCamera))
  570. {
  571. return;
  572. }
  573. break;
  574. default:
  575. if (CycleViewport(ET_ViewportXY, ET_ViewportXZ))
  576. {
  577. return;
  578. }
  579. if (CycleViewport(ET_ViewportXZ, ET_ViewportYZ))
  580. {
  581. return;
  582. }
  583. if (CycleViewport(ET_ViewportYZ, ET_ViewportXY))
  584. {
  585. return;
  586. }
  587. break;
  588. }
  589. }
  590. //////////////////////////////////////////////////////////////////////////
  591. void CLayoutWnd::OnDestroy()
  592. {
  593. if (m_maximizedView)
  594. {
  595. delete m_maximizedView;
  596. m_maximizedView = nullptr;
  597. }
  598. }
  599. void CLayoutWnd::FocusFirstLayoutViewPane(CLayoutSplitter* splitter)
  600. {
  601. // When starting in multi-layout mode we focus the first CLayoutViewPane
  602. // Note that splitter->widget(0) might be another splitter, not a CLayoutViewPane
  603. if (splitter)
  604. {
  605. if (auto view = splitter->findChild<CLayoutViewPane*>())
  606. {
  607. view->setFocus();
  608. MainWindow::instance()->SetActiveView(view);
  609. }
  610. }
  611. }
  612. void CLayoutWnd::MoveViewport(CLayoutViewPane* from, CLayoutViewPane* to, const QString& viewClassName)
  613. {
  614. // First detach from old pane, allowing the viewport to be disconnected from the event bus
  615. // This must be done before re-binding the viewport and connecting to the bus with a new id
  616. auto viewport = from->GetViewport();
  617. from->DetachViewport();
  618. BindViewport(to, viewClassName, viewport);
  619. }
  620. static CLayoutViewPane* layoutViewPaneForChild(QObject* child)
  621. {
  622. CLayoutViewPane* result = nullptr;
  623. while (child)
  624. {
  625. result = qobject_cast<CLayoutViewPane*>(child);
  626. if (result)
  627. {
  628. break;
  629. }
  630. child = child->parent();
  631. }
  632. return result;
  633. }
  634. void CLayoutWnd::OnFocusChanged(QWidget* /* oldWidget */, QWidget* newWidget)
  635. {
  636. if (CLayoutViewPane* layoutViewPane = layoutViewPaneForChild(newWidget))
  637. {
  638. MainWindow::instance()->SetActiveView(layoutViewPane);
  639. }
  640. }
  641. #include <moc_LayoutWnd.cpp>