OSDN Git Service

It's 2011 now.
[qt-creator-jp/qt-creator-jp.git] / src / libs / utils / detailswidget.cpp
1 /**************************************************************************
2 **
3 ** This file is part of Qt Creator
4 **
5 ** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies).
6 **
7 ** Contact: Nokia Corporation (qt-info@nokia.com)
8 **
9 ** No Commercial Usage
10 **
11 ** This file contains pre-release code and may not be distributed.
12 ** You may use this file in accordance with the terms and conditions
13 ** contained in the Technology Preview License Agreement accompanying
14 ** this package.
15 **
16 ** GNU Lesser General Public License Usage
17 **
18 ** Alternatively, this file may be used under the terms of the GNU Lesser
19 ** General Public License version 2.1 as published by the Free Software
20 ** Foundation and appearing in the file LICENSE.LGPL included in the
21 ** packaging of this file.  Please review the following information to
22 ** ensure the GNU Lesser General Public License version 2.1 requirements
23 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
24 **
25 ** In addition, as a special exception, Nokia gives you certain additional
26 ** rights.  These rights are described in the Nokia Qt LGPL Exception
27 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
28 **
29 ** If you have questions regarding the use of this file, please contact
30 ** Nokia at qt-info@nokia.com.
31 **
32 **************************************************************************/
33
34 #include "detailswidget.h"
35 #include "detailsbutton.h"
36
37 #include <QtCore/QStack>
38 #include <QtCore/QPropertyAnimation>
39
40 #include <QtGui/QGridLayout>
41 #include <QtGui/QLabel>
42 #include <QtGui/QPainter>
43 #include <QtGui/QScrollArea>
44 #include <QtGui/QApplication>
45
46 namespace Utils {
47
48     static const int MARGIN=8;
49
50     // This widget is using a grid layout and places the items
51     // in the following way:
52     //
53     // +------------+-------------------------+---------------+
54     // +summaryLabel|              toolwidget | detailsButton |
55     // +------------+-------------------------+---------------+
56     // |                  widget                              |
57     // +------------+-------------------------+---------------+
58
59     struct DetailsWidgetPrivate {
60         DetailsWidgetPrivate();
61
62         DetailsButton *m_detailsButton;
63         QGridLayout *m_grid;
64         QLabel *m_summaryLabel;
65         Utils::FadingPanel *m_toolWidget;
66         QWidget *m_widget;
67
68         QPixmap m_collapsedPixmap;
69         QPixmap m_expandedPixmap;
70
71         DetailsWidget::State m_state;
72         bool m_hovered;
73     };
74
75     DetailsWidgetPrivate::DetailsWidgetPrivate() :
76             m_detailsButton(new DetailsButton),
77             m_grid(new QGridLayout),
78             m_summaryLabel(new QLabel),
79             m_toolWidget(0),
80             m_widget(0),
81             m_state(DetailsWidget::Collapsed),
82             m_hovered(false)
83     {
84     }
85
86     DetailsWidget::DetailsWidget(QWidget *parent) :
87             QWidget(parent),
88             d(new DetailsWidgetPrivate)
89     {
90         d->m_summaryLabel->setTextInteractionFlags(Qt::TextSelectableByMouse);
91         d->m_summaryLabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
92         d->m_summaryLabel->setContentsMargins(MARGIN, MARGIN, MARGIN, MARGIN);
93
94         d->m_grid->setContentsMargins(0, 0, 0, 0);
95         d->m_grid->setSpacing(0);
96         d->m_grid->addWidget(d->m_summaryLabel, 0, 0);
97         d->m_grid->addWidget(d->m_detailsButton, 0, 2);
98         setLayout(d->m_grid);
99
100         connect(d->m_detailsButton, SIGNAL(toggled(bool)),
101                 this, SLOT(setExpanded(bool)));
102         updateControls();
103     }
104
105     DetailsWidget::~DetailsWidget()
106     {
107         delete d;
108     }
109
110     void DetailsWidget::paintEvent(QPaintEvent *paintEvent)
111     {
112         QWidget::paintEvent(paintEvent);
113
114         QPainter p(this);
115
116         QPoint topLeft(d->m_summaryLabel->geometry().left(), contentsRect().top());
117         const QRect paintArea(topLeft, contentsRect().bottomRight());
118
119         if (d->m_state != Expanded) {
120             if (d->m_collapsedPixmap.isNull() ||
121                 d->m_collapsedPixmap.size() != size())
122                 d->m_collapsedPixmap = cacheBackground(paintArea.size(), false);
123             p.drawPixmap(paintArea, d->m_collapsedPixmap);
124         } else {
125             if (d->m_expandedPixmap.isNull() ||
126                 d->m_expandedPixmap.size() != size())
127                 d->m_expandedPixmap = cacheBackground(paintArea.size(), true);
128             p.drawPixmap(paintArea, d->m_expandedPixmap);
129         }
130     }
131
132     void DetailsWidget::enterEvent(QEvent * event)
133     {
134         QWidget::enterEvent(event);
135         changeHoverState(true);
136     }
137
138     void DetailsWidget::leaveEvent(QEvent * event)
139     {
140         QWidget::leaveEvent(event);
141         changeHoverState(false);
142     }
143
144     void DetailsWidget::setSummaryText(const QString &text)
145     {
146         d->m_summaryLabel->setText(text);
147     }
148
149     QString DetailsWidget::summaryText() const
150     {
151         return d->m_summaryLabel->text();
152     }
153
154     DetailsWidget::State DetailsWidget::state() const
155     {
156         return d->m_state;
157     }
158
159     void DetailsWidget::setState(State state)
160     {
161         if (state == d->m_state)
162             return;
163         d->m_state = state;
164         updateControls();
165     }
166
167     void DetailsWidget::setExpanded(bool expanded)
168     {
169         setState(expanded ? Expanded : Collapsed);
170     }
171
172     void DetailsWidget::updateControls()
173     {
174         if (d->m_widget)
175             d->m_widget->setVisible(d->m_state == Expanded || d->m_state == NoSummary);
176         d->m_detailsButton->setChecked(d->m_state == Expanded && d->m_widget);
177         //d->m_summaryLabel->setEnabled(d->m_state == Collapsed && d->m_widget);
178         d->m_detailsButton->setVisible(d->m_state != NoSummary);
179         d->m_summaryLabel->setVisible(d->m_state != NoSummary);
180         {
181             QWidget *w = this;
182             while (w) {
183                 if (w->layout())
184                     w->layout()->activate();
185                 if (QScrollArea *area = qobject_cast<QScrollArea*>(w)) {
186                     QEvent e(QEvent::LayoutRequest);
187                     QCoreApplication::sendEvent(area, &e);
188                 }
189                 w = w->parentWidget();
190             }
191         }
192     }
193
194     QWidget *DetailsWidget::widget() const
195     {
196         return d->m_widget;
197     }
198
199     void DetailsWidget::setWidget(QWidget *widget)
200     {
201         if (d->m_widget == widget)
202             return;
203
204         if (d->m_widget) {
205             d->m_grid->removeWidget(d->m_widget);
206             delete d->m_widget;
207         }
208
209         d->m_widget = widget;
210
211         if (d->m_widget) {
212             d->m_widget->setContentsMargins(MARGIN, MARGIN, MARGIN, MARGIN);
213             d->m_grid->addWidget(d->m_widget, 1, 0, 1, 3);
214         }
215         updateControls();
216     }
217
218     void DetailsWidget::setToolWidget(Utils::FadingPanel *widget)
219     {
220         if (d->m_toolWidget == widget)
221             return;
222
223         d->m_toolWidget = widget;
224
225         if (!d->m_toolWidget)
226             return;
227
228         d->m_toolWidget->adjustSize();
229         d->m_grid->addWidget(d->m_toolWidget, 0, 1, 1, 1, Qt::AlignRight);
230
231 #ifdef Q_WS_MAC
232         d->m_toolWidget->setOpacity(1.0);
233 #endif
234         changeHoverState(d->m_hovered);
235     }
236
237     QWidget *DetailsWidget::toolWidget() const
238     {
239         return d->m_toolWidget;
240     }
241
242     QPixmap DetailsWidget::cacheBackground(const QSize &size, bool expanded)
243     {
244         QPixmap pixmap(size);
245         pixmap.fill(Qt::transparent);
246         QPainter p(&pixmap);
247
248         QRect topRect(0, 0, size.width(), d->m_summaryLabel->height());
249         QRect fullRect(0, 0, size.width(), size.height());
250         p.fillRect(fullRect, QColor(255, 255, 255, 40));
251
252         QColor highlight = palette().highlight().color();
253         highlight.setAlpha(0.5);
254         if (expanded) {
255             p.fillRect(topRect, highlight);
256         }
257
258         QLinearGradient lg(topRect.topLeft(), topRect.bottomLeft());
259         lg.setColorAt(0, QColor(255, 255, 255, 130));
260         lg.setColorAt(1, QColor(255, 255, 255, 0));
261         p.fillRect(topRect, lg);
262         p.setRenderHint(QPainter::Antialiasing, true);
263         p.translate(0.5, 0.5);
264         p.setPen(QColor(0, 0, 0, 40));
265         p.setBrush(Qt::NoBrush);
266         p.drawRoundedRect(fullRect.adjusted(0, 0, -1, -1), 2, 2);
267         p.setBrush(Qt::NoBrush);
268         p.setPen(QColor(255,255,255,140));
269         p.drawRoundedRect(fullRect.adjusted(1, 1, -2, -2), 2, 2);
270         p.setPen(QPen(palette().color(QPalette::Mid)));
271
272         return pixmap;
273     }
274
275     void DetailsWidget::changeHoverState(bool hovered)
276     {
277         if (!d->m_toolWidget)
278             return;
279 #ifdef Q_OS_MAC
280         d->m_toolWidget->setVisible(hovered);
281 #else
282         d->m_toolWidget->fadeTo(hovered ? 1.0 : 0);
283 #endif
284         d->m_hovered = hovered;
285     }
286
287 } // namespace Utils