DialogStack.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676
  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 the required headers
  9. #include "DialogStack.h"
  10. #include "AzCore/std/iterator.h"
  11. #include "AzCore/std/limits.h"
  12. #include "AzQtComponents/Components/Widgets/CardHeader.h"
  13. #include "MysticQtManager.h"
  14. #include <QVBoxLayout>
  15. #include <QFrame>
  16. #include <QScrollArea>
  17. #include <QMouseEvent>
  18. #include <QResizeEvent>
  19. #include <QScrollBar>
  20. #include <QSplitter>
  21. #include <QApplication>
  22. namespace MysticQt
  23. {
  24. // dialog stack splitter
  25. class DialogStackSplitter
  26. : public QSplitter
  27. {
  28. public:
  29. DialogStackSplitter()
  30. {
  31. setStyleSheet("QSplitter::handle{ height: 4px; background: transparent; }");
  32. }
  33. void MoveFirstSplitterToMin()
  34. {
  35. moveSplitter(0, 1);
  36. }
  37. void MoveFirstSplitterToMax()
  38. {
  39. moveSplitter(INT_MAX, 1);
  40. }
  41. void MoveFirstSplitter(int pos)
  42. {
  43. moveSplitter(pos, 1);
  44. }
  45. };
  46. // the constructor
  47. DialogStack::DialogStack(QWidget* parent)
  48. : QScrollArea(parent)
  49. {
  50. // set the object name
  51. setObjectName("DialogStack");
  52. // create the root splitter
  53. m_rootSplitter = new DialogStackSplitter();
  54. m_rootSplitter->setOrientation(Qt::Vertical);
  55. m_rootSplitter->setChildrenCollapsible(false);
  56. // set the widget resizable to have the scrollarea resizing it
  57. setWidgetResizable(true);
  58. // We don't want the default 1px frame, headers should fully span the
  59. // widget
  60. setFrameStyle(QFrame::Shape::NoFrame);
  61. // set the scrollarea widget
  62. setWidget(m_rootSplitter);
  63. }
  64. DialogStack::~DialogStack()
  65. {
  66. }
  67. // get rid of all dialogs and their allocated memory
  68. void DialogStack::Clear()
  69. {
  70. for (Dialog& dialog : m_dialogs)
  71. {
  72. if (dialog.m_dialogWidget)
  73. {
  74. dialog.m_dialogWidget->deleteLater();
  75. }
  76. }
  77. // destroy the dialogs
  78. m_dialogs.clear();
  79. // update the scroll bars
  80. UpdateScrollBars();
  81. }
  82. // add an item to the stack
  83. void DialogStack::Add(QWidget* widget, const QString& headerTitle, bool closed, bool maximizeSize, bool closable, bool stretchWhenMaximize)
  84. {
  85. // create the dialog widget
  86. QWidget* dialogWidget = new QWidget();
  87. QVBoxLayout* dialogLayout = new QVBoxLayout();
  88. dialogLayout->setAlignment(Qt::AlignTop);
  89. dialogWidget->setLayout(dialogLayout);
  90. dialogLayout->setSpacing(0);
  91. dialogLayout->setMargin(0);
  92. // add the dialog widget
  93. // the splitter is hierarchical : {a, {b, c}}
  94. DialogStackSplitter* dialogSplitter;
  95. if (m_dialogs.empty())
  96. {
  97. // add the dialog widget
  98. dialogSplitter = m_rootSplitter;
  99. dialogSplitter->addWidget(dialogWidget);
  100. // stretch if needed
  101. if (maximizeSize && stretchWhenMaximize)
  102. {
  103. dialogSplitter->setStretchFactor(0, 1);
  104. }
  105. }
  106. else
  107. {
  108. // check if one space is free on the last splitter
  109. if (m_dialogs.back().m_splitter->count() == 1)
  110. {
  111. // add the dialog widget
  112. dialogSplitter = m_dialogs.back().m_splitter;
  113. dialogSplitter->addWidget(dialogWidget);
  114. // stretch if needed
  115. if (maximizeSize && stretchWhenMaximize)
  116. {
  117. dialogSplitter->setStretchFactor(1, 1);
  118. }
  119. // less space used by the splitter when the last dialog is closed
  120. if (m_dialogs.back().m_frame->isHidden())
  121. {
  122. m_dialogs.back().m_splitter->handle(1)->setFixedHeight(1);
  123. m_dialogs.back().m_splitter->setStyleSheet("QSplitter::handle{ height: 1px; background: transparent; }");
  124. }
  125. // disable the splitter
  126. if (m_dialogs.back().m_frame->isHidden())
  127. {
  128. m_dialogs.back().m_splitter->handle(1)->setDisabled(true);
  129. }
  130. }
  131. else // already two dialogs in the splitter
  132. {
  133. // create the new splitter
  134. dialogSplitter = new DialogStackSplitter();
  135. dialogSplitter->setOrientation(Qt::Vertical);
  136. dialogSplitter->setChildrenCollapsible(false);
  137. // add the current last dialog and the new dialog after
  138. dialogSplitter->addWidget(m_dialogs.back().m_dialogWidget);
  139. dialogSplitter->addWidget(dialogWidget);
  140. // stretch if needed
  141. if (m_dialogs.back().m_maximizeSize && m_dialogs.back().m_stretchWhenMaximize)
  142. {
  143. dialogSplitter->setStretchFactor(0, 1);
  144. }
  145. // less space used by the splitter when the last dialog is closed
  146. if (m_dialogs.back().m_frame->isHidden())
  147. {
  148. dialogSplitter->handle(1)->setFixedHeight(1);
  149. dialogSplitter->setStyleSheet("QSplitter::handle{ height: 1px; background: transparent; }");
  150. }
  151. // disable the splitter
  152. if (m_dialogs.back().m_frame->isHidden())
  153. {
  154. dialogSplitter->handle(1)->setDisabled(true);
  155. }
  156. // stretch if needed
  157. if (maximizeSize && stretchWhenMaximize)
  158. {
  159. dialogSplitter->setStretchFactor(1, 1);
  160. }
  161. // replace the last dialog by the new splitter
  162. m_dialogs.back().m_splitter->addWidget(dialogSplitter);
  163. // disable the splitter
  164. if (m_dialogs.size() > 1)
  165. {
  166. const auto previousDialogIt = m_dialogs.end() - 2;
  167. if (previousDialogIt->m_frame->isHidden())
  168. {
  169. m_dialogs.back().m_splitter->handle(1)->setDisabled(true);
  170. }
  171. // stretch the splitter if needed
  172. // the correct behavior is found after experimentations
  173. if ((m_dialogs.back().m_maximizeSize && m_dialogs.back().m_stretchWhenMaximize) || (previousDialogIt->m_maximizeSize && previousDialogIt->m_stretchWhenMaximize == false))
  174. {
  175. m_dialogs.back().m_splitter->setStretchFactor(1, 1);
  176. }
  177. }
  178. // set the new splitter of the last dialog
  179. m_dialogs.back().m_splitter = dialogSplitter;
  180. }
  181. }
  182. // create the container card header that we can click to open/close this dialog
  183. auto* header = new AzQtComponents::CardHeader();
  184. AzQtComponents::CardHeader::applyContainerStyle(header);
  185. header->setTitle(headerTitle);
  186. header->setObjectName("CardHeader");
  187. // add the separator card header in the layout
  188. dialogLayout->addWidget(header);
  189. connect(header, &AzQtComponents::CardHeader::expanderChanged, this, &MysticQt::DialogStack::OnExpandedChanged);
  190. // create the frame where the dialog/widget will be inside
  191. QWidget* frame = new QWidget();
  192. frame->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
  193. frame->setObjectName("StackFrame");
  194. dialogLayout->addWidget(frame);
  195. // create the layout thats inside of the frame
  196. QVBoxLayout* layout = new QVBoxLayout();
  197. layout->addWidget(widget, Qt::AlignTop | Qt::AlignLeft);
  198. layout->setSpacing(0);
  199. layout->setMargin(3);
  200. // set the frame layout
  201. frame->setLayout(layout);
  202. // adjust size of the header
  203. header->adjustSize();
  204. // adjust size of the widget
  205. widget->adjustSize();
  206. // set the constraints
  207. if (maximizeSize)
  208. {
  209. // set the layout size constraint
  210. layout->setSizeConstraint(QLayout::SetMaximumSize);
  211. }
  212. else
  213. {
  214. // set the layout size constraint
  215. layout->setSizeConstraint(QLayout::SetMinimumSize);
  216. // set the frame height
  217. frame->setFixedHeight(layout->minimumSize().height());
  218. // set the dialog height
  219. dialogWidget->setFixedHeight(dialogLayout->minimumSize().height());
  220. }
  221. // adjust size of the dialog widget
  222. dialogWidget->adjustSize();
  223. // register it, so that we know which frame is linked to which header
  224. m_dialogs.emplace_back(Dialog{
  225. /*.m_header =*/header,
  226. /*.m_frame =*/ frame,
  227. /*.m_widget =*/ widget,
  228. /*.m_dialogWidget =*/ dialogWidget,
  229. /*.m_splitter =*/ dialogSplitter,
  230. /*.m_closable =*/ closable,
  231. /*.m_maximizeSize =*/ maximizeSize,
  232. /*.m_stretchWhenMaximize =*/ stretchWhenMaximize,
  233. /*.m_minimumHeightBeforeClose =*/ 0,
  234. /*.m_maximumHeightBeforeClose =*/ 0,
  235. /*.m_layout =*/ layout,
  236. /*.m_dialogLayout =*/ dialogLayout,
  237. });
  238. // check if the dialog is closed
  239. if (closed)
  240. {
  241. Close(header);
  242. }
  243. // update the scroll bars
  244. UpdateScrollBars();
  245. }
  246. // add an item to the stack
  247. void DialogStack::Add(QLayout* layout, const QString& headerTitle, bool closed, bool maximizeSize, bool closable, bool stretchWhenMaximize)
  248. {
  249. // create the widget
  250. QWidget* widget = new QWidget();
  251. // set the layout on this widget
  252. widget->setLayout(layout);
  253. // add the dialog using the created widget
  254. Add(widget, headerTitle, closed, maximizeSize, closable, stretchWhenMaximize);
  255. }
  256. bool DialogStack::Remove(QWidget* widget)
  257. {
  258. const auto foundDialog = AZStd::find_if(begin(m_dialogs), end(m_dialogs), [widget](const Dialog& dialog)
  259. {
  260. return dialog.m_frame->layout()->indexOf(widget) != -1;
  261. });
  262. if (foundDialog == end(m_dialogs))
  263. {
  264. return false;
  265. }
  266. // if the widget is located in the current layout, remove it
  267. // all next dialogs has to be moved to the previous splitter and delete if the last splitter is empty
  268. // TODO : shift all dialogs needed as explained on the previous comment
  269. foundDialog->m_dialogWidget->hide();
  270. foundDialog->m_dialogWidget->deleteLater();
  271. m_dialogs.erase(foundDialog);
  272. // update the scroll bars
  273. UpdateScrollBars();
  274. return true;
  275. }
  276. // on header card expansions
  277. void DialogStack::OnExpandedChanged(bool expanded)
  278. {
  279. auto* header = qobject_cast<AzQtComponents::CardHeader*>(sender());
  280. if (expanded)
  281. {
  282. Open(header);
  283. }
  284. else
  285. {
  286. Close(header);
  287. }
  288. }
  289. // find the dialog that goes with the given header
  290. size_t DialogStack::FindDialog(AzQtComponents::CardHeader* header)
  291. {
  292. const auto foundDialog = AZStd::find_if(begin(m_dialogs), end(m_dialogs), [header](const Dialog& dialog)
  293. {
  294. return dialog.m_header == header;
  295. });
  296. return foundDialog != end(m_dialogs) ? AZStd::distance(begin(m_dialogs), foundDialog) : MCore::InvalidIndex;
  297. }
  298. // open the dialog
  299. void DialogStack::Open(AzQtComponents::CardHeader* header)
  300. {
  301. const auto dialog = AZStd::find_if(begin(m_dialogs), end(m_dialogs), [header](const Dialog& dialog)
  302. {
  303. return dialog.m_header == header;
  304. });
  305. if (dialog == end(m_dialogs))
  306. {
  307. return;
  308. }
  309. // show the widget inside the dialog
  310. dialog->m_frame->show();
  311. // set the previous minimum and maximum height before closed
  312. dialog->m_dialogWidget->setMinimumHeight(dialog->m_minimumHeightBeforeClose);
  313. dialog->m_dialogWidget->setMaximumHeight(dialog->m_maximumHeightBeforeClose);
  314. // more space used by the splitter when the dialog is open
  315. if (dialog != m_dialogs.end() - 1)
  316. {
  317. dialog->m_splitter->handle(1)->setFixedHeight(4);
  318. dialog->m_splitter->setStyleSheet("QSplitter::handle{ height: 4px; background: transparent; }");
  319. }
  320. // enable the splitter
  321. if (dialog != m_dialogs.end() - 1)
  322. {
  323. dialog->m_splitter->handle(1)->setEnabled(true);
  324. }
  325. // maximize the size if it's needed
  326. if (m_dialogs.size() > 1)
  327. {
  328. if (dialog->m_maximizeSize)
  329. {
  330. // special case if it's the first dialog
  331. if (dialog == m_dialogs.begin())
  332. {
  333. // if it's the first dialog and stretching is enabled, it expands to the max, all others expand to the min
  334. if (dialog->m_stretchWhenMaximize == false && (dialog + 1)->m_maximizeSize && (dialog + 1)->m_frame->isHidden() == false)
  335. {
  336. static_cast<DialogStackSplitter*>(dialog->m_splitter)->MoveFirstSplitterToMin();
  337. }
  338. else
  339. {
  340. static_cast<DialogStackSplitter*>(dialog->m_splitter)->MoveFirstSplitterToMax();
  341. }
  342. }
  343. else // not the first dialog
  344. {
  345. // set the previous dialog to the min to have this dialog expanded to the top
  346. if ((dialog - 1)->m_frame->isHidden() || (dialog - 1)->m_maximizeSize == false || ((dialog - 1)->m_maximizeSize && (dialog - 1)->m_stretchWhenMaximize == false))
  347. {
  348. static_cast<DialogStackSplitter*>((dialog - 1)->m_splitter)->MoveFirstSplitterToMin();
  349. }
  350. // special case if it's not the last dialog
  351. if (dialog != m_dialogs.end() - 1)
  352. {
  353. // if the next dialog is closed, it's needed to expand to the max too
  354. if ((dialog + 1)->m_frame->isHidden())
  355. {
  356. static_cast<DialogStackSplitter*>(dialog->m_splitter)->MoveFirstSplitterToMax();
  357. }
  358. }
  359. }
  360. }
  361. }
  362. // update the scrollbars
  363. UpdateScrollBars();
  364. }
  365. // close the dialog
  366. void DialogStack::Close(AzQtComponents::CardHeader* header)
  367. {
  368. const auto dialog = AZStd::find_if(begin(m_dialogs), end(m_dialogs), [header](const Dialog& dialog)
  369. {
  370. return dialog.m_header == header;
  371. });
  372. if (dialog == end(m_dialogs))
  373. {
  374. return;
  375. }
  376. // only closable dialog can be closed
  377. if (dialog->m_closable == false)
  378. {
  379. return;
  380. }
  381. // keep the min and max height before close
  382. dialog->m_minimumHeightBeforeClose = dialog->m_dialogWidget->minimumHeight();
  383. dialog->m_maximumHeightBeforeClose = dialog->m_dialogWidget->maximumHeight();
  384. // hide the widget inside the dialog
  385. dialog->m_frame->hide();
  386. // set the widget to fixed size to not have it possible to resize
  387. dialog->m_dialogWidget->setMinimumHeight(dialog->m_header->height());
  388. dialog->m_dialogWidget->setMaximumHeight(dialog->m_header->height());
  389. // less space used by the splitter when the dialog is closed
  390. if (dialog < m_dialogs.end() - 1)
  391. {
  392. dialog->m_splitter->handle(1)->setFixedHeight(1);
  393. dialog->m_splitter->setStyleSheet("QSplitter::handle{ height: 1px; background: transparent; }");
  394. dialog->m_splitter->handle(1)->setDisabled(true);
  395. static_cast<DialogStackSplitter*>(dialog->m_splitter)->MoveFirstSplitterToMin();
  396. }
  397. // maximize the first needed to avoid empty space
  398. bool findPreviousMaximizedDialogNeeded = true;
  399. for (auto curDialog = dialog + 1; curDialog != m_dialogs.end(); ++curDialog)
  400. {
  401. if (curDialog->m_maximizeSize && curDialog->m_frame->isHidden() == false)
  402. {
  403. if (curDialog != (m_dialogs.end() - 1) && (curDialog + 1)->m_frame->isHidden())
  404. {
  405. static_cast<DialogStackSplitter*>(curDialog->m_splitter)->MoveFirstSplitterToMax();
  406. }
  407. else
  408. {
  409. static_cast<DialogStackSplitter*>((curDialog - 1)->m_splitter)->MoveFirstSplitterToMin();
  410. }
  411. findPreviousMaximizedDialogNeeded = false;
  412. break;
  413. }
  414. }
  415. if (findPreviousMaximizedDialogNeeded)
  416. {
  417. for (auto curDialog = AZStd::make_reverse_iterator(dialog); curDialog != m_dialogs.rend(); ++curDialog)
  418. {
  419. if (curDialog->m_maximizeSize && curDialog->m_frame->isHidden() == false)
  420. {
  421. static_cast<DialogStackSplitter*>(curDialog->m_splitter)->MoveFirstSplitterToMax();
  422. break;
  423. }
  424. }
  425. }
  426. // update the scrollbars
  427. UpdateScrollBars();
  428. }
  429. // when we press the mouse
  430. void DialogStack::mousePressEvent(QMouseEvent* event)
  431. {
  432. if (event->buttons() & Qt::LeftButton)
  433. {
  434. // keep the mouse pos
  435. m_prevMouseX = event->globalX();
  436. m_prevMouseY = event->globalY();
  437. // set the cursor if the scrollbar is visible
  438. if ((horizontalScrollBar()->maximum() > 0) || (verticalScrollBar()->maximum() > 0))
  439. {
  440. QApplication::setOverrideCursor(Qt::ClosedHandCursor);
  441. }
  442. }
  443. }
  444. // when we double click
  445. // without this event handled the hand cursor is not set when double click
  446. void DialogStack::mouseDoubleClickEvent(QMouseEvent* event)
  447. {
  448. mousePressEvent(event);
  449. }
  450. // when the mouse button is released
  451. void DialogStack::mouseReleaseEvent(QMouseEvent* event)
  452. {
  453. // action only for the left button
  454. if (event->button() != Qt::LeftButton)
  455. {
  456. return;
  457. }
  458. // reset the cursor if the scrollbar is visible
  459. if ((horizontalScrollBar()->maximum() > 0) || (verticalScrollBar()->maximum() > 0))
  460. {
  461. QApplication::restoreOverrideCursor();
  462. }
  463. }
  464. // when a mouse button was clicked and we're moving the mouse
  465. void DialogStack::mouseMoveEvent(QMouseEvent* event)
  466. {
  467. // action only for the left button
  468. if ((event->buttons() & Qt::LeftButton) == false)
  469. {
  470. return;
  471. }
  472. // calculate the delta mouse movement
  473. const int32 deltaX = event->globalX() - m_prevMouseX;
  474. const int32 deltaY = event->globalY() - m_prevMouseY;
  475. // now apply this delta movement to the scroller
  476. int32 newX = horizontalScrollBar()->value() - deltaX;
  477. int32 newY = verticalScrollBar()->value() - deltaY;
  478. horizontalScrollBar()->setSliderPosition(newX);
  479. verticalScrollBar()->setSliderPosition(newY);
  480. // store the current value as previous value
  481. m_prevMouseX = event->globalX();
  482. m_prevMouseY = event->globalY();
  483. }
  484. // update the scroll bars ranges
  485. void DialogStack::UpdateScrollBars()
  486. {
  487. // compute the new range
  488. const QSize areaSize = viewport()->size();
  489. const QSize widgetSize = widget()->size();
  490. const int32 rangeX = widgetSize.width() - areaSize.width();
  491. const int32 rangeY = widgetSize.height() - areaSize.height();
  492. // set the new ranges
  493. horizontalScrollBar()->setRange(0, rangeX);
  494. verticalScrollBar()->setRange(0, rangeY);
  495. }
  496. // when resizing
  497. void DialogStack::resizeEvent(QResizeEvent* event)
  498. {
  499. // update the scrollbar ranges
  500. UpdateScrollBars();
  501. // update the scroll area widget
  502. QScrollArea::resizeEvent(event);
  503. // maximize the first dialog needed
  504. if (m_dialogs.empty() || m_dialogs.size() == 1)
  505. {
  506. return;
  507. }
  508. for (auto dialog = m_dialogs.rbegin() + 1; dialog != m_dialogs.rend(); ++dialog)
  509. {
  510. if (dialog->m_maximizeSize && dialog->m_frame->isHidden() == false)
  511. {
  512. static_cast<DialogStackSplitter*>(dialog->m_splitter)->MoveFirstSplitterToMax();
  513. break;
  514. }
  515. }
  516. }
  517. // replace an internal widget
  518. void DialogStack::ReplaceWidget(QWidget* oldWidget, QWidget* newWidget)
  519. {
  520. for (auto dialog = m_dialogs.begin(); dialog != m_dialogs.end(); ++dialog)
  521. {
  522. // go next if the widget is not the same
  523. if (dialog->m_widget != oldWidget)
  524. {
  525. continue;
  526. }
  527. // replace the widget
  528. dialog->m_frame->layout()->replaceWidget(oldWidget, newWidget);
  529. dialog->m_widget = newWidget;
  530. // adjust size of the new widget
  531. newWidget->adjustSize();
  532. // set the constraints
  533. if (dialog->m_maximizeSize == false)
  534. {
  535. // get margins
  536. const QMargins frameMargins = dialog->m_layout->contentsMargins();
  537. const QMargins dialogMargins = dialog->m_dialogLayout->contentsMargins();
  538. const int frameMarginTopBottom = frameMargins.top() + frameMargins.bottom();
  539. const int dialogMarginTopBottom = dialogMargins.top() + dialogMargins.bottom();
  540. const int allMarginsTopBottom = frameMarginTopBottom + dialogMarginTopBottom;
  541. // set the frame height
  542. dialog->m_frame->setFixedHeight(newWidget->height() + frameMarginTopBottom);
  543. // compute the dialog height
  544. const int dialogHeight = newWidget->height() + allMarginsTopBottom + dialog->m_header->height();
  545. // set the maximum height in case the dialog is not closed, if it's closed update the stored height
  546. if (dialog->m_frame->isHidden() == false)
  547. {
  548. // set the dialog height
  549. dialog->m_dialogWidget->setFixedHeight(dialogHeight);
  550. // set the first splitter to the min if needed
  551. if (dialog != m_dialogs.end() - 1)
  552. {
  553. static_cast<DialogStackSplitter*>(dialog->m_splitter)->MoveFirstSplitterToMin();
  554. }
  555. }
  556. else // dialog closed
  557. {
  558. // update the minimum and maximum stored height
  559. dialog->m_minimumHeightBeforeClose = dialogHeight;
  560. dialog->m_maximumHeightBeforeClose = dialogHeight;
  561. }
  562. }
  563. // stop here
  564. return;
  565. }
  566. }
  567. } // namespace MysticQt