-
Notifications
You must be signed in to change notification settings - Fork 31
/
Copy pathcollapsible.cpp
72 lines (61 loc) · 2.18 KB
/
collapsible.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include "collapsible.h"
#include <QFontMetrics>
#include <QPainter>
#include <QPushButton>
#include <QVBoxLayout>
const QString Collapsible::s_downArrow = QString::fromUtf8(" \xE2\x96\xBC ");
const QString Collapsible::s_upArrow = QString::fromUtf8(" \xE2\x96\xB2 ");
const int Collapsible::s_maxWidth = 400;
Collapsible::Collapsible(QWidget *parent)
: QFrame(parent)
, m_mainLayout(new QVBoxLayout(this))
, m_displayWidget(nullptr)
, m_titleButton(new QPushButton(this))
, m_title(QString())
{
setFrameShape(QFrame::NoFrame);
setMaximumWidth(s_maxWidth);
setStyleSheet("Collapsible { border: 1px solid #808080; border-radius: 2px; }");
m_titleButton->setFlat(true);
m_titleButton->setStatusTip("Click to collapse / expand the section.");
connect(m_titleButton, SIGNAL(clicked()), this, SLOT(toggleCollapse()));
m_mainLayout->setMargin(0);
m_mainLayout->setSpacing(0);
m_mainLayout->addWidget(m_titleButton);
setLayout(m_mainLayout);
}
void Collapsible::setWidget(QWidget* displayWidget)
{
// remove any existing widget
if(m_displayWidget){
m_mainLayout->removeWidget(m_displayWidget);
m_displayWidget->deleteLater();
m_displayWidget = nullptr;
}
// take possession of the widget
if(displayWidget->parent() != this){
displayWidget->setParent(this);
}
m_displayWidget = displayWidget;
m_mainLayout->addWidget(m_displayWidget);
}
void Collapsible::toggleCollapse()
{
m_displayWidget->setHidden(!m_displayWidget->isHidden());
updateTitle();
}
void Collapsible::updateTitle(const QString& title)
{
QFontMetrics fontMetrics = QFontMetrics(m_titleButton->font());
qreal arrowWidth = fontMetrics.boundingRect(s_downArrow).width();
if(!title.isEmpty()){
m_title = fontMetrics.elidedText(title, Qt::ElideMiddle, s_maxWidth - arrowWidth);
}
// display the correct arrow
// ... or if there is no display widget yet, always the up arrow, because display widgets are opened by default
if(m_displayWidget && m_displayWidget->isHidden()){
m_titleButton->setText(s_downArrow + m_title);
} else {
m_titleButton->setText(s_upArrow + m_title);
}
}