1
/***************************************************************************
2
* Project TUPI: Magia 2D *
3
* Project Contact: info@maefloresta.com *
4
* Project Website: http://www.maefloresta.com *
5
* Project Leader: Gustav Gonzalez <info@maefloresta.com> *
9
* Gustavo Gonzalez / xtingray *
20
* Copyright (C) 2010 Gustav Gonzalez - http://www.maefloresta.com *
22
* This program is free software; you can redistribute it and/or modify *
23
* it under the terms of the GNU General Public License as published by *
24
* the Free Software Foundation; either version 3 of the License, or *
25
* (at your option) any later version. *
27
* This program is distributed in the hope that it will be useful, *
28
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
29
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
30
* GNU General Public License for more details. *
32
* You should have received a copy of the GNU General Public License *
33
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
34
***************************************************************************/
36
#include <QTextDocument>
39
#include <QMouseEvent>
40
#include <QDragEnterEvent>
41
#include <QVBoxLayout>
42
#include <QApplication>
43
#include <QGridLayout>
44
#include <QPushButton>
45
#include <QPainterPath>
46
#include <QStyleOption>
48
#include <QFontMetrics>
50
#include "kcollapsiblewidget.h"
53
/******************************************************************
55
*****************************************************************/
57
class CollapsibleMimeData : public QMimeData
60
CollapsibleMimeData();
61
~CollapsibleMimeData();
63
void setCollapsibleWidget(KCollapsibleWidget *w);
64
KCollapsibleWidget *collapsibleWidget() const;
67
KCollapsibleWidget *m_cw;
70
CollapsibleMimeData::CollapsibleMimeData() : QMimeData(), m_cw(0)
74
CollapsibleMimeData::~CollapsibleMimeData()
78
void CollapsibleMimeData::setCollapsibleWidget(KCollapsibleWidget *w)
83
KCollapsibleWidget *CollapsibleMimeData::collapsibleWidget() const
88
KClickableLabel::KClickableLabel(QWidget* parent)
89
: QWidget( parent ), m_isEnter(false), m_isDragging(false), m_checked(false)
91
setMouseTracking(false);
93
m_text = new QTextDocument(this);
96
KClickableLabel::~KClickableLabel()
100
QSize KClickableLabel::sizeHint() const
102
return m_text->size().toSize();
105
void KClickableLabel::setText(const QString &text)
107
m_text->setHtml(text);
110
QString KClickableLabel::text() const
112
return m_text->toPlainText();
115
void KClickableLabel::setChecked(bool c)
120
bool KClickableLabel::isChecked() const
125
void KClickableLabel::mousePressEvent(QMouseEvent *e)
127
m_isDragging = false;
129
m_position = e->pos();
130
QWidget::mousePressEvent(e);
133
void KClickableLabel::mouseReleaseEvent(QMouseEvent *e)
135
if (! m_isDragging) {
136
m_checked = !m_checked;
141
void KClickableLabel::mouseMoveEvent(QMouseEvent* e)
143
QWidget::mouseMoveEvent(e);
145
if ((e->pos() - m_position).manhattanLength() < QApplication::startDragDistance())
148
QDrag *drag = new QDrag(this);
149
CollapsibleMimeData *mimeData = new CollapsibleMimeData;
150
KCollapsibleWidget *parent = dynamic_cast<KCollapsibleWidget *>(parentWidget());
155
QWidget *inner = parent->innerWidget();
160
mimeData->setCollapsibleWidget(parent);
162
QPixmap wpx = QPixmap::grabWidget(parent);
165
p.drawRoundRect(wpx.rect(), 10, 10);
167
drag->setPixmap(wpx);
168
drag->setMimeData(mimeData);
173
void KClickableLabel::paintEvent(QPaintEvent *e)
175
QPainter painter(this);
182
double h = r.height();
183
double h2 = r.height() / 2.0;
185
path.addRect(r.x() + h2, r.y() + 0, r.width() - h2 * 2, r.height());
186
path.addEllipse(r.x(), r.y(), h, h);
187
path.addEllipse(r.x() + r.width() - h, r.y(), h, h);
188
path.setFillRule(Qt::WindingFill);
189
painter.setPen(Qt::NoPen);
190
painter.setBrush( palette().brush(QPalette::Highlight) );
191
painter.setRenderHint(QPainter::Antialiasing);
192
painter.drawPath(path);
198
r.setX((int) (r.x() + m_text->textWidth())/2);
200
m_text->drawContents(&painter, r);
203
QWidget::paintEvent(e);
206
void KClickableLabel::enterEvent(QEvent * e)
210
QWidget::enterEvent(e);
213
void KClickableLabel::leaveEvent(QEvent *e)
217
QWidget::leaveEvent(e);
220
/******************************************************************
222
*****************************************************************/
224
class KCollapsibleWidget::Private
227
QGridLayout *cwlayout;
228
QWidget *innerWidget;
229
KClickableLabel *label;
232
class KSettingsContainer::Private
236
QList<KCollapsibleWidget *> collapsibles;
239
/******************************************************************
241
*****************************************************************/
243
KSettingsContainer::KSettingsContainer(QWidget *parent)
244
: QScrollArea(parent), k(new KSettingsContainer::Private)
246
QWidget *w = new QWidget;
247
QVBoxLayout *helperLay = new QVBoxLayout(w);
248
k->layout = new QVBoxLayout;
249
helperLay->addLayout(k->layout);
250
helperLay->addStretch(2);
252
setWidgetResizable(true);
254
setAcceptDrops(true);
257
KSettingsContainer::~KSettingsContainer()
262
KCollapsibleWidget* KSettingsContainer::insertWidget(QWidget *w, const QString& name)
264
if (w && w->layout()) {
265
QLayout *lay = w->layout();
270
KCollapsibleWidget *cw = new KCollapsibleWidget(name);
272
k->layout->addWidget(cw);
273
cw->setInnerWidget(w);
275
k->collapsibles << cw;
282
void KSettingsContainer::removeWidget(QWidget *w)
284
foreach (KCollapsibleWidget *cw, k->collapsibles) {
285
if (cw->innerWidget() == w) {
286
k->collapsibles.removeAll(cw );
287
k->layout->removeWidget(cw);
294
void KSettingsContainer::dragEnterEvent(QDragEnterEvent * event)
298
if (dynamic_cast<const CollapsibleMimeData *>(event->mimeData())) {
299
if (event->source() == this) {
300
event->setDropAction(Qt::MoveAction);
303
event->acceptProposedAction();
310
void KSettingsContainer::dragMoveEvent(QDragMoveEvent* event)
312
if (dynamic_cast<const CollapsibleMimeData *>(event->mimeData()))
313
event->acceptProposedAction();
318
void KSettingsContainer::dropEvent(QDropEvent* event)
320
if (const CollapsibleMimeData *mimeData = dynamic_cast<const CollapsibleMimeData *>(event->mimeData())) {
321
k->layout->removeWidget( mimeData->collapsibleWidget());
323
QWidget *child = childAt(event->pos());
326
if (KCollapsibleWidget *prev = dynamic_cast< KCollapsibleWidget *>(child)) {
327
k->layout->insertWidget( k->layout->indexOf(prev)+1, mimeData->collapsibleWidget());
328
} else if (KCollapsibleWidget *prev = dynamic_cast< KCollapsibleWidget *>(child->parentWidget())) {
329
k->layout->insertWidget( k->layout->indexOf(prev)+1, mimeData->collapsibleWidget());
331
k->layout->addWidget(mimeData->collapsibleWidget());
334
k->layout->addWidget(mimeData->collapsibleWidget());
337
if (event->source() == this) {
338
event->setDropAction(Qt::MoveAction);
341
event->acceptProposedAction();
348
KCollapsibleWidget::KCollapsibleWidget(QWidget *parent)
349
: QWidget(parent), k(new KCollapsibleWidget::Private)
354
KCollapsibleWidget::KCollapsibleWidget(const QString& caption, QWidget *parent)
355
: QWidget(parent), k(new KCollapsibleWidget::Private)
361
void KCollapsibleWidget::init()
364
k->cwlayout = new QGridLayout(this);
365
k->cwlayout->setMargin(0);
367
k->label = new KClickableLabel;
368
k->label->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Preferred);
370
k->cwlayout->addWidget(k->label, 1, 1);
372
connect(k->label, SIGNAL(clicked()), this, SLOT(toggleExpanded()));
378
KCollapsibleWidget::~KCollapsibleWidget()
383
QWidget* KCollapsibleWidget::innerWidget() const
385
return k->innerWidget;
388
void KCollapsibleWidget::setInnerWidget(QWidget *w)
393
QGroupBox *container = new QGroupBox(this);
394
w->setParent(container);
396
QVBoxLayout *containerLayout = new QVBoxLayout(container);
399
containerLayout->addWidget(w);
401
k->cwlayout->addWidget(container, 2, 1);
402
k->cwlayout->setRowStretch(2, 1);
405
setExpanded(isExpanded());
408
void KCollapsibleWidget::setCaption(const QString& caption)
410
k->label->setText(QString("<b>%1</b>").arg(caption));
413
QString KCollapsibleWidget::caption() const
415
return k->label->text();
418
void KCollapsibleWidget::setExpanded(bool expanded)
420
if (k->innerWidget) {
422
setUpdatesEnabled(false);
424
k->innerWidget->parentWidget()->setVisible(expanded);
425
k->innerWidget->setVisible(expanded);
426
k->label->setChecked(expanded);
428
setUpdatesEnabled(true);
432
bool KCollapsibleWidget::isExpanded() const
434
return k->label->isChecked();
437
void KCollapsibleWidget::toggleExpanded()
439
setExpanded(k->label->isChecked());