You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
685 lines
23 KiB
C++
685 lines
23 KiB
C++
/*
|
|
* Copyright (c) Contributors to the Open 3D Engine Project.
|
|
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0 OR MIT
|
|
*
|
|
*/
|
|
|
|
// include the required headers
|
|
#include "DialogStack.h"
|
|
#include "AzCore/std/iterator.h"
|
|
#include "AzCore/std/limits.h"
|
|
#include "MysticQtManager.h"
|
|
#include <QPushButton>
|
|
#include <QVBoxLayout>
|
|
#include <QFrame>
|
|
#include <QScrollArea>
|
|
#include <QMouseEvent>
|
|
#include <QResizeEvent>
|
|
#include <QScrollBar>
|
|
#include <QSplitter>
|
|
#include <QApplication>
|
|
|
|
|
|
namespace MysticQt
|
|
{
|
|
// dialog stack splitter
|
|
class DialogStackSplitter
|
|
: public QSplitter
|
|
{
|
|
public:
|
|
|
|
DialogStackSplitter()
|
|
{
|
|
setStyleSheet("QSplitter::handle{ height: 4px; background: transparent; }");
|
|
}
|
|
|
|
void MoveFirstSplitterToMin()
|
|
{
|
|
moveSplitter(0, 1);
|
|
}
|
|
|
|
void MoveFirstSplitterToMax()
|
|
{
|
|
moveSplitter(INT_MAX, 1);
|
|
}
|
|
|
|
void MoveFirstSplitter(int pos)
|
|
{
|
|
moveSplitter(pos, 1);
|
|
}
|
|
};
|
|
|
|
|
|
// the constructor
|
|
DialogStack::DialogStack(QWidget* parent)
|
|
: QScrollArea(parent)
|
|
{
|
|
// set the object name
|
|
setObjectName("DialogStack");
|
|
|
|
// create the root splitter
|
|
m_rootSplitter = new DialogStackSplitter();
|
|
m_rootSplitter->setOrientation(Qt::Vertical);
|
|
m_rootSplitter->setChildrenCollapsible(false);
|
|
|
|
// set the widget resizable to have the scrollarea resizing it
|
|
setWidgetResizable(true);
|
|
|
|
// set the scrollarea widget
|
|
setWidget(m_rootSplitter);
|
|
}
|
|
|
|
|
|
// destructor
|
|
DialogStack::~DialogStack()
|
|
{
|
|
}
|
|
|
|
|
|
// get rid of all dialogs and their allocated memory
|
|
void DialogStack::Clear()
|
|
{
|
|
// destroy the dialogs
|
|
m_dialogs.clear();
|
|
|
|
// update the scroll bars
|
|
UpdateScrollBars();
|
|
}
|
|
|
|
|
|
// add an item to the stack
|
|
void DialogStack::Add(QWidget* widget, const QString& headerTitle, bool closed, bool maximizeSize, bool closable, bool stretchWhenMaximize)
|
|
{
|
|
// create the dialog widget
|
|
QWidget* dialogWidget = new QWidget();
|
|
QVBoxLayout* dialogLayout = new QVBoxLayout();
|
|
dialogLayout->setAlignment(Qt::AlignTop);
|
|
dialogWidget->setLayout(dialogLayout);
|
|
dialogLayout->setSpacing(0);
|
|
dialogLayout->setMargin(0);
|
|
|
|
// add the dialog widget
|
|
// the splitter is hierarchical : {a, {b, c}}
|
|
DialogStackSplitter* dialogSplitter;
|
|
if (m_dialogs.empty())
|
|
{
|
|
// add the dialog widget
|
|
dialogSplitter = m_rootSplitter;
|
|
dialogSplitter->addWidget(dialogWidget);
|
|
|
|
// stretch if needed
|
|
if (maximizeSize && stretchWhenMaximize)
|
|
{
|
|
dialogSplitter->setStretchFactor(0, 1);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// check if one space is free on the last splitter
|
|
if (m_dialogs.back().m_splitter->count() == 1)
|
|
{
|
|
// add the dialog widget
|
|
dialogSplitter = m_dialogs.back().m_splitter;
|
|
dialogSplitter->addWidget(dialogWidget);
|
|
|
|
// stretch if needed
|
|
if (maximizeSize && stretchWhenMaximize)
|
|
{
|
|
dialogSplitter->setStretchFactor(1, 1);
|
|
}
|
|
|
|
// less space used by the splitter when the last dialog is closed
|
|
if (m_dialogs.back().m_frame->isHidden())
|
|
{
|
|
m_dialogs.back().m_splitter->handle(1)->setFixedHeight(1);
|
|
m_dialogs.back().m_splitter->setStyleSheet("QSplitter::handle{ height: 1px; background: transparent; }");
|
|
}
|
|
|
|
// disable the splitter
|
|
if (m_dialogs.back().m_frame->isHidden())
|
|
{
|
|
m_dialogs.back().m_splitter->handle(1)->setDisabled(true);
|
|
}
|
|
}
|
|
else // already two dialogs in the splitter
|
|
{
|
|
// create the new splitter
|
|
dialogSplitter = new DialogStackSplitter();
|
|
dialogSplitter->setOrientation(Qt::Vertical);
|
|
dialogSplitter->setChildrenCollapsible(false);
|
|
|
|
// add the current last dialog and the new dialog after
|
|
dialogSplitter->addWidget(m_dialogs.back().m_dialogWidget);
|
|
dialogSplitter->addWidget(dialogWidget);
|
|
|
|
// stretch if needed
|
|
if (m_dialogs.back().m_maximizeSize && m_dialogs.back().m_stretchWhenMaximize)
|
|
{
|
|
dialogSplitter->setStretchFactor(0, 1);
|
|
}
|
|
|
|
// less space used by the splitter when the last dialog is closed
|
|
if (m_dialogs.back().m_frame->isHidden())
|
|
{
|
|
dialogSplitter->handle(1)->setFixedHeight(1);
|
|
dialogSplitter->setStyleSheet("QSplitter::handle{ height: 1px; background: transparent; }");
|
|
}
|
|
|
|
// disable the splitter
|
|
if (m_dialogs.back().m_frame->isHidden())
|
|
{
|
|
dialogSplitter->handle(1)->setDisabled(true);
|
|
}
|
|
|
|
// stretch if needed
|
|
if (maximizeSize && stretchWhenMaximize)
|
|
{
|
|
dialogSplitter->setStretchFactor(1, 1);
|
|
}
|
|
|
|
// replace the last dialog by the new splitter
|
|
m_dialogs.back().m_splitter->addWidget(dialogSplitter);
|
|
|
|
// disable the splitter
|
|
if (m_dialogs.size() > 1)
|
|
{
|
|
const auto previousDialogIt = m_dialogs.end() - 2;
|
|
if (previousDialogIt->m_frame->isHidden())
|
|
{
|
|
m_dialogs.back().m_splitter->handle(1)->setDisabled(true);
|
|
}
|
|
|
|
// stretch the splitter if needed
|
|
// the correct behavior is found after experimentations
|
|
if ((m_dialogs.back().m_maximizeSize && m_dialogs.back().m_stretchWhenMaximize) || (previousDialogIt->m_maximizeSize && previousDialogIt->m_stretchWhenMaximize == false))
|
|
{
|
|
m_dialogs.back().m_splitter->setStretchFactor(1, 1);
|
|
}
|
|
}
|
|
|
|
// set the new splitter of the last dialog
|
|
m_dialogs.back().m_splitter = dialogSplitter;
|
|
}
|
|
}
|
|
|
|
// create the header button that we can click to open/close this dialog
|
|
QPushButton* headerButton = new QPushButton(headerTitle);
|
|
headerButton->setObjectName("HeaderButton");
|
|
if (closed)
|
|
{
|
|
headerButton->setIcon(GetMysticQt()->FindIcon("Images/Icons/ArrowRightGray.png"));
|
|
}
|
|
else
|
|
{
|
|
headerButton->setIcon(GetMysticQt()->FindIcon("Images/Icons/ArrowDownGray.png"));
|
|
}
|
|
|
|
// add the header button in the layout
|
|
dialogLayout->addWidget(headerButton);
|
|
connect(headerButton, &QPushButton::clicked, this, &MysticQt::DialogStack::OnHeaderButton);
|
|
|
|
// create the frame where the dialog/widget will be inside
|
|
QWidget* frame = new QWidget();
|
|
frame->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
|
|
frame->setObjectName("StackFrame");
|
|
dialogLayout->addWidget(frame);
|
|
|
|
// create the layout thats inside of the frame
|
|
QVBoxLayout* layout = new QVBoxLayout();
|
|
layout->addWidget(widget, Qt::AlignTop | Qt::AlignLeft);
|
|
layout->setSpacing(0);
|
|
layout->setMargin(3);
|
|
|
|
// set the frame layout
|
|
frame->setLayout(layout);
|
|
|
|
// adjust size of the button
|
|
headerButton->adjustSize();
|
|
|
|
// adjust size of the widget
|
|
widget->adjustSize();
|
|
|
|
// set the constraints
|
|
if (maximizeSize)
|
|
{
|
|
// set the layout size constraint
|
|
layout->setSizeConstraint(QLayout::SetMaximumSize);
|
|
}
|
|
else
|
|
{
|
|
// set the layout size constraint
|
|
layout->setSizeConstraint(QLayout::SetMinimumSize);
|
|
|
|
// set the frame height
|
|
frame->setFixedHeight(layout->minimumSize().height());
|
|
|
|
// set the dialog height
|
|
dialogWidget->setFixedHeight(dialogLayout->minimumSize().height());
|
|
}
|
|
|
|
// adjust size of the dialog widget
|
|
dialogWidget->adjustSize();
|
|
|
|
// register it, so that we know which frame is linked to which header button
|
|
m_dialogs.emplace_back(Dialog{
|
|
/*.m_button =*/ headerButton,
|
|
/*.m_frame =*/ frame,
|
|
/*.m_widget =*/ widget,
|
|
/*.m_dialogWidget =*/ dialogWidget,
|
|
/*.m_splitter =*/ dialogSplitter,
|
|
/*.m_closable =*/ closable,
|
|
/*.m_maximizeSize =*/ maximizeSize,
|
|
/*.m_stretchWhenMaximize =*/ stretchWhenMaximize,
|
|
/*.m_minimumHeightBeforeClose =*/ 0,
|
|
/*.m_maximumHeightBeforeClose =*/ 0,
|
|
/*.m_layout =*/ layout,
|
|
/*.m_dialogLayout =*/ dialogLayout,
|
|
});
|
|
|
|
// check if the dialog is closed
|
|
if (closed)
|
|
{
|
|
Close(headerButton);
|
|
}
|
|
|
|
// update the scroll bars
|
|
UpdateScrollBars();
|
|
}
|
|
|
|
|
|
// add an item to the stack
|
|
void DialogStack::Add(QLayout* layout, const QString& headerTitle, bool closed, bool maximizeSize, bool closable, bool stretchWhenMaximize)
|
|
{
|
|
// create the widget
|
|
QWidget* widget = new QWidget();
|
|
|
|
// set the layout on this widget
|
|
widget->setLayout(layout);
|
|
|
|
// add the dialog using the created widget
|
|
Add(widget, headerTitle, closed, maximizeSize, closable, stretchWhenMaximize);
|
|
}
|
|
|
|
|
|
bool DialogStack::Remove(QWidget* widget)
|
|
{
|
|
const auto foundDialog = AZStd::find_if(begin(m_dialogs), end(m_dialogs), [widget](const Dialog& dialog)
|
|
{
|
|
return dialog.m_frame->layout()->indexOf(widget) != -1;
|
|
});
|
|
|
|
if (foundDialog == end(m_dialogs))
|
|
{
|
|
return false;
|
|
}
|
|
|
|
// if the widget is located in the current layout, remove it
|
|
// all next dialogs has to be moved to the previous splitter and delete if the last splitter is empty
|
|
// TODO : shift all dialogs needed as explained on the previous comment
|
|
foundDialog->m_dialogWidget->hide();
|
|
foundDialog->m_dialogWidget->deleteLater();
|
|
m_dialogs.erase(foundDialog);
|
|
|
|
// update the scroll bars
|
|
UpdateScrollBars();
|
|
|
|
return true;
|
|
}
|
|
|
|
|
|
// on header button press
|
|
void DialogStack::OnHeaderButton()
|
|
{
|
|
QPushButton* button = (QPushButton*)sender();
|
|
const size_t dialogIndex = FindDialog(button);
|
|
if (m_dialogs[dialogIndex].m_frame->isHidden())
|
|
{
|
|
Open(button);
|
|
}
|
|
else
|
|
{
|
|
Close(button);
|
|
}
|
|
}
|
|
|
|
|
|
// find the dialog that goes with the given button
|
|
size_t DialogStack::FindDialog(QPushButton* pushButton)
|
|
{
|
|
const auto foundDialog = AZStd::find_if(begin(m_dialogs), end(m_dialogs), [pushButton](const Dialog& dialog)
|
|
{
|
|
return dialog.m_button == pushButton;
|
|
});
|
|
return foundDialog != end(m_dialogs) ? AZStd::distance(begin(m_dialogs), foundDialog) : MCore::InvalidIndex;
|
|
}
|
|
|
|
|
|
// open the dialog
|
|
void DialogStack::Open(QPushButton* button)
|
|
{
|
|
const auto dialog = AZStd::find_if(begin(m_dialogs), end(m_dialogs), [button](const Dialog& dialog)
|
|
{
|
|
return dialog.m_button == button;
|
|
});
|
|
if (dialog == end(m_dialogs))
|
|
{
|
|
return;
|
|
}
|
|
|
|
// show the widget inside the dialog
|
|
dialog->m_frame->show();
|
|
|
|
// set the previous minimum and maximum height before closed
|
|
dialog->m_dialogWidget->setMinimumHeight(dialog->m_minimumHeightBeforeClose);
|
|
dialog->m_dialogWidget->setMaximumHeight(dialog->m_maximumHeightBeforeClose);
|
|
|
|
// change the stylesheet and the icon
|
|
button->setStyleSheet("");
|
|
button->setIcon(GetMysticQt()->FindIcon("Images/Icons/ArrowDownGray.png"));
|
|
|
|
// more space used by the splitter when the dialog is open
|
|
if (dialog != m_dialogs.end() - 1)
|
|
{
|
|
dialog->m_splitter->handle(1)->setFixedHeight(4);
|
|
dialog->m_splitter->setStyleSheet("QSplitter::handle{ height: 4px; background: transparent; }");
|
|
}
|
|
|
|
// enable the splitter
|
|
if (dialog != m_dialogs.end() - 1)
|
|
{
|
|
dialog->m_splitter->handle(1)->setEnabled(true);
|
|
}
|
|
|
|
// maximize the size if it's needed
|
|
if (m_dialogs.size() > 1)
|
|
{
|
|
if (dialog->m_maximizeSize)
|
|
{
|
|
// special case if it's the first dialog
|
|
if (dialog == m_dialogs.begin())
|
|
{
|
|
// if it's the first dialog and stretching is enabled, it expand to the max, all others expand to the min
|
|
if (dialog->m_stretchWhenMaximize == false && (dialog + 1)->m_maximizeSize && (dialog + 1)->m_frame->isHidden() == false)
|
|
{
|
|
static_cast<DialogStackSplitter*>(dialog->m_splitter)->MoveFirstSplitterToMin();
|
|
}
|
|
else
|
|
{
|
|
static_cast<DialogStackSplitter*>(dialog->m_splitter)->MoveFirstSplitterToMax();
|
|
}
|
|
}
|
|
else // not the first dialog
|
|
{
|
|
// set the previous dialog to the min to have this dialog expanded to the top
|
|
if ((dialog - 1)->m_frame->isHidden() || (dialog - 1)->m_maximizeSize == false || ((dialog - 1)->m_maximizeSize && (dialog - 1)->m_stretchWhenMaximize == false))
|
|
{
|
|
static_cast<DialogStackSplitter*>((dialog - 1)->m_splitter)->MoveFirstSplitterToMin();
|
|
}
|
|
|
|
// special case if it's not the last dialog
|
|
if (dialog != m_dialogs.end() - 1)
|
|
{
|
|
// if the next dialog is closed, it's needed to expand to the max too
|
|
if ((dialog + 1)->m_frame->isHidden())
|
|
{
|
|
static_cast<DialogStackSplitter*>(dialog->m_splitter)->MoveFirstSplitterToMax();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
// update the scrollbars
|
|
UpdateScrollBars();
|
|
}
|
|
|
|
|
|
// close the dialog
|
|
void DialogStack::Close(QPushButton* button)
|
|
{
|
|
const auto dialog = AZStd::find_if(begin(m_dialogs), end(m_dialogs), [button](const Dialog& dialog)
|
|
{
|
|
return dialog.m_button == button;
|
|
});
|
|
if (dialog == end(m_dialogs))
|
|
{
|
|
return;
|
|
}
|
|
|
|
// only closable dialog can be closed
|
|
if (dialog->m_closable == false)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// keep the min and max height before close
|
|
dialog->m_minimumHeightBeforeClose = dialog->m_dialogWidget->minimumHeight();
|
|
dialog->m_maximumHeightBeforeClose = dialog->m_dialogWidget->maximumHeight();
|
|
|
|
// hide the widget inside the dialog
|
|
dialog->m_frame->hide();
|
|
|
|
// set the widget to fixed size to not have it possible to resize
|
|
dialog->m_dialogWidget->setMinimumHeight(dialog->m_button->height());
|
|
dialog->m_dialogWidget->setMaximumHeight(dialog->m_button->height());
|
|
|
|
// change the stylesheet and the icon
|
|
button->setStyleSheet("border-bottom-left-radius: 4px; border-bottom-right-radius: 4px; border: 1px solid rgb(40,40,40);"); // TODO: link to the real style sheets
|
|
button->setIcon(GetMysticQt()->FindIcon("Images/Icons/ArrowRightGray.png"));
|
|
|
|
// less space used by the splitter when the dialog is closed
|
|
if (dialog < m_dialogs.end() - 1)
|
|
{
|
|
dialog->m_splitter->handle(1)->setFixedHeight(1);
|
|
dialog->m_splitter->setStyleSheet("QSplitter::handle{ height: 1px; background: transparent; }");
|
|
dialog->m_splitter->handle(1)->setDisabled(true);
|
|
static_cast<DialogStackSplitter*>(dialog->m_splitter)->MoveFirstSplitterToMin();
|
|
}
|
|
|
|
// maximize the first needed to avoid empty space
|
|
bool findPreviousMaximizedDialogNeeded = true;
|
|
for (auto curDialog = dialog + 1; curDialog != m_dialogs.end(); ++curDialog)
|
|
{
|
|
if (curDialog->m_maximizeSize && curDialog->m_frame->isHidden() == false)
|
|
{
|
|
if (curDialog != (m_dialogs.end() - 1) && (curDialog + 1)->m_frame->isHidden())
|
|
{
|
|
static_cast<DialogStackSplitter*>(curDialog->m_splitter)->MoveFirstSplitterToMax();
|
|
}
|
|
else
|
|
{
|
|
static_cast<DialogStackSplitter*>((curDialog - 1)->m_splitter)->MoveFirstSplitterToMin();
|
|
}
|
|
findPreviousMaximizedDialogNeeded = false;
|
|
break;
|
|
}
|
|
}
|
|
if (findPreviousMaximizedDialogNeeded)
|
|
{
|
|
for (auto curDialog = AZStd::make_reverse_iterator(dialog); curDialog != m_dialogs.rend(); ++curDialog)
|
|
{
|
|
if (curDialog->m_maximizeSize && curDialog->m_frame->isHidden() == false)
|
|
{
|
|
static_cast<DialogStackSplitter*>(curDialog->m_splitter)->MoveFirstSplitterToMax();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
// update the scrollbars
|
|
UpdateScrollBars();
|
|
}
|
|
|
|
|
|
// when we press the mouse
|
|
void DialogStack::mousePressEvent(QMouseEvent* event)
|
|
{
|
|
if (event->buttons() & Qt::LeftButton)
|
|
{
|
|
// keep the mouse pos
|
|
m_prevMouseX = event->globalX();
|
|
m_prevMouseY = event->globalY();
|
|
|
|
// set the cursor if the scrollbar is visible
|
|
if ((horizontalScrollBar()->maximum() > 0) || (verticalScrollBar()->maximum() > 0))
|
|
{
|
|
QApplication::setOverrideCursor(Qt::ClosedHandCursor);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// when we double click
|
|
// without this event handled the hand cursor is not set when double click
|
|
void DialogStack::mouseDoubleClickEvent(QMouseEvent* event)
|
|
{
|
|
mousePressEvent(event);
|
|
}
|
|
|
|
|
|
// when the mouse button is released
|
|
void DialogStack::mouseReleaseEvent(QMouseEvent* event)
|
|
{
|
|
// action only for the left button
|
|
if (event->button() != Qt::LeftButton)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// reset the cursor if the scrollbar is visible
|
|
if ((horizontalScrollBar()->maximum() > 0) || (verticalScrollBar()->maximum() > 0))
|
|
{
|
|
QApplication::restoreOverrideCursor();
|
|
}
|
|
}
|
|
|
|
|
|
// when a mouse button was clicked and we're moving the mouse
|
|
void DialogStack::mouseMoveEvent(QMouseEvent* event)
|
|
{
|
|
// action only for the left button
|
|
if ((event->buttons() & Qt::LeftButton) == false)
|
|
{
|
|
return;
|
|
}
|
|
|
|
// calculate the delta mouse movement
|
|
const int32 deltaX = event->globalX() - m_prevMouseX;
|
|
const int32 deltaY = event->globalY() - m_prevMouseY;
|
|
|
|
// now apply this delta movement to the scroller
|
|
int32 newX = horizontalScrollBar()->value() - deltaX;
|
|
int32 newY = verticalScrollBar()->value() - deltaY;
|
|
horizontalScrollBar()->setSliderPosition(newX);
|
|
verticalScrollBar()->setSliderPosition(newY);
|
|
|
|
// store the current value as previous value
|
|
m_prevMouseX = event->globalX();
|
|
m_prevMouseY = event->globalY();
|
|
}
|
|
|
|
|
|
// update the scroll bars ranges
|
|
void DialogStack::UpdateScrollBars()
|
|
{
|
|
// compute the new range
|
|
const QSize areaSize = viewport()->size();
|
|
const QSize widgetSize = widget()->size();
|
|
const int32 rangeX = widgetSize.width() - areaSize.width();
|
|
const int32 rangeY = widgetSize.height() - areaSize.height();
|
|
|
|
// set the new ranges
|
|
horizontalScrollBar()->setRange(0, rangeX);
|
|
verticalScrollBar()->setRange(0, rangeY);
|
|
}
|
|
|
|
|
|
// when resizing
|
|
void DialogStack::resizeEvent(QResizeEvent* event)
|
|
{
|
|
// update the scrollbar ranges
|
|
UpdateScrollBars();
|
|
|
|
// update the scroll area widget
|
|
QScrollArea::resizeEvent(event);
|
|
|
|
// maximize the first dialog needed
|
|
if (m_dialogs.empty() || m_dialogs.size() == 1)
|
|
{
|
|
return;
|
|
}
|
|
for (auto dialog = m_dialogs.rbegin() + 1; dialog != m_dialogs.rend(); ++dialog)
|
|
{
|
|
if (dialog->m_maximizeSize && dialog->m_frame->isHidden() == false)
|
|
{
|
|
static_cast<DialogStackSplitter*>(dialog->m_splitter)->MoveFirstSplitterToMax();
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
// replace an internal widget
|
|
void DialogStack::ReplaceWidget(QWidget* oldWidget, QWidget* newWidget)
|
|
{
|
|
for (auto dialog = m_dialogs.begin(); dialog != m_dialogs.end(); ++dialog)
|
|
{
|
|
// go next if the widget is not the same
|
|
if (dialog->m_widget != oldWidget)
|
|
{
|
|
continue;
|
|
}
|
|
|
|
// replace the widget
|
|
dialog->m_frame->layout()->replaceWidget(oldWidget, newWidget);
|
|
dialog->m_widget = newWidget;
|
|
|
|
// adjust size of the new widget
|
|
newWidget->adjustSize();
|
|
|
|
// set the constraints
|
|
if (dialog->m_maximizeSize == false)
|
|
{
|
|
// get margins
|
|
const QMargins frameMargins = dialog->m_layout->contentsMargins();
|
|
const QMargins dialogMargins = dialog->m_dialogLayout->contentsMargins();
|
|
const int frameMarginTopBottom = frameMargins.top() + frameMargins.bottom();
|
|
const int dialogMarginTopBottom = dialogMargins.top() + dialogMargins.bottom();
|
|
const int allMarginsTopBottom = frameMarginTopBottom + dialogMarginTopBottom;
|
|
|
|
// set the frame height
|
|
dialog->m_frame->setFixedHeight(newWidget->height() + frameMarginTopBottom);
|
|
|
|
// compute the dialog height
|
|
const int dialogHeight = newWidget->height() + allMarginsTopBottom + dialog->m_button->height();
|
|
|
|
// set the maximum height in case the dialog is not closed, if it's closed update the stored height
|
|
if (dialog->m_frame->isHidden() == false)
|
|
{
|
|
// set the dialog height
|
|
dialog->m_dialogWidget->setFixedHeight(dialogHeight);
|
|
|
|
// set the first splitter to the min if needed
|
|
if (dialog != m_dialogs.end() - 1)
|
|
{
|
|
static_cast<DialogStackSplitter*>(dialog->m_splitter)->MoveFirstSplitterToMin();
|
|
}
|
|
}
|
|
else // dialog closed
|
|
{
|
|
// update the minimum and maximum stored height
|
|
dialog->m_minimumHeightBeforeClose = dialogHeight;
|
|
dialog->m_maximumHeightBeforeClose = dialogHeight;
|
|
}
|
|
}
|
|
|
|
// stop here
|
|
return;
|
|
}
|
|
}
|
|
} // namespace MysticQt
|
|
|
|
#include <MysticQt/Source/moc_DialogStack.cpp>
|