OSDN Git Service

cf4196e8ab3d1aea5d6f75c1e5c1bf5c09ac9dbb
[qt-creator-jp/qt-creator-jp.git] / src / plugins / coreplugin / fancyactionbar.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 "fancyactionbar.h"
35 #include "coreconstants.h"
36
37 #include <utils/stylehelper.h>
38
39 #include <coreplugin/icore.h>
40 #include <coreplugin/imode.h>
41
42 #include <QtGui/QHBoxLayout>
43 #include <QtGui/QPainter>
44 #include <QtGui/QPicture>
45 #include <QtGui/QVBoxLayout>
46 #include <QtGui/QAction>
47 #include <QtGui/QStatusBar>
48 #include <QtGui/QStyle>
49 #include <QtGui/QStyleOption>
50 #include <QtGui/QMouseEvent>
51 #include <QtGui/QApplication>
52 #include <QtCore/QEvent>
53 #include <QtCore/QAnimationGroup>
54 #include <QtCore/QPropertyAnimation>
55 #include <QtCore/QDebug>
56
57 using namespace Core;
58 using namespace Internal;
59
60 FancyToolButton::FancyToolButton(QWidget *parent)
61     : QToolButton(parent), m_fader(0)
62 {
63     m_hasForceVisible = false;
64     setAttribute(Qt::WA_Hover, true);
65     setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
66 }
67
68 void FancyToolButton::forceVisible(bool visible)
69 {
70     m_hasForceVisible = true;
71     setVisible(visible);
72 }
73
74 bool FancyToolButton::event(QEvent *e)
75 {
76     switch(e->type()) {
77     case QEvent::Enter:
78         {
79             QPropertyAnimation *animation = new QPropertyAnimation(this, "fader");
80             animation->setDuration(125);
81             animation->setEndValue(1.0);
82             animation->start(QAbstractAnimation::DeleteWhenStopped);
83         }
84         break;
85     case QEvent::Leave:
86         {
87             QPropertyAnimation *animation = new QPropertyAnimation(this, "fader");
88             animation->setDuration(125);
89             animation->setEndValue(0.0);
90             animation->start(QAbstractAnimation::DeleteWhenStopped);
91         }
92         break;
93     default:
94         return QToolButton::event(e);
95     }
96     return false;
97 }
98
99 void FancyToolButton::paintEvent(QPaintEvent *event)
100 {
101     Q_UNUSED(event)
102     QPainter painter(this);
103
104     // draw borders
105     bool isTitledAction = defaultAction()->property("titledAction").toBool();
106
107 #ifndef Q_WS_MAC // Mac UIs usually don't hover
108     if (m_fader > 0 && isEnabled() && !isDown() && !isChecked()) {
109         painter.save();
110         int fader = int(40 * m_fader);
111         QLinearGradient grad(rect().topLeft(), rect().topRight());
112         grad.setColorAt(0, Qt::transparent);
113         grad.setColorAt(0.5, QColor(255, 255, 255, fader));
114         grad.setColorAt(1, Qt::transparent);
115         painter.fillRect(rect(), grad);
116         painter.setPen(QPen(grad, 1.0));
117         painter.drawLine(rect().topLeft(), rect().topRight());
118         painter.drawLine(rect().bottomLeft(), rect().bottomRight());
119         painter.restore();
120     } else
121 #endif
122     if (isDown() || isChecked()) {
123         painter.save();
124         QLinearGradient grad(rect().topLeft(), rect().topRight());
125         grad.setColorAt(0, Qt::transparent);
126         grad.setColorAt(0.5, QColor(0, 0, 0, 50));
127         grad.setColorAt(1, Qt::transparent);
128         painter.fillRect(rect(), grad);
129         painter.setPen(QPen(grad, 1.0));
130         painter.drawLine(rect().topLeft(), rect().topRight());
131         painter.drawLine(rect().topLeft(), rect().topRight());
132         painter.drawLine(rect().topLeft() + QPoint(0,1), rect().topRight() + QPoint(0,1));
133         painter.drawLine(rect().bottomLeft(), rect().bottomRight());
134         painter.drawLine(rect().bottomLeft(), rect().bottomRight());
135         painter.drawLine(rect().topLeft() - QPoint(0,1), rect().topRight() - QPoint(0,1));
136         painter.restore();
137     }
138     QPixmap borderPixmap;
139     QMargins margins;
140
141     QRect iconRect(0, 0, Core::Constants::TARGET_ICON_SIZE, Core::Constants::TARGET_ICON_SIZE);
142     // draw popup texts
143     if (isTitledAction) {
144
145         QFont normalFont(painter.font());
146         QRect centerRect = rect();
147         normalFont.setPointSizeF(Utils::StyleHelper::sidebarFontSize());
148         QFont boldFont(normalFont);
149         boldFont.setBold(true);
150         QFontMetrics fm(normalFont);
151         QFontMetrics boldFm(boldFont);
152         int lineHeight = boldFm.height();
153         int textFlags = Qt::AlignVCenter|Qt::AlignHCenter;
154
155         const QString projectName = defaultAction()->property("heading").toString();
156         if (!projectName.isNull())
157             centerRect.adjust(0, lineHeight + 4, 0, 0);
158
159         const QString buildConfiguration = defaultAction()->property("subtitle").toString();
160         if (!buildConfiguration.isNull())
161             centerRect.adjust(0, 0, 0, -lineHeight - 4);
162
163         iconRect.moveCenter(centerRect.center());
164         Utils::StyleHelper::drawIconWithShadow(icon(), iconRect, &painter, isEnabled() ? QIcon::Normal : QIcon::Disabled);
165         painter.setFont(normalFont);
166
167         QPoint textOffset = centerRect.center() - QPoint(iconRect.width()/2, iconRect.height()/2);
168         textOffset = textOffset - QPoint(0, lineHeight + 4);
169         QRectF r(0, textOffset.y(), rect().width(), lineHeight);
170         QColor penColor;
171         if (isEnabled())
172             penColor = Qt::white;
173         else
174             penColor = Qt::gray;
175         painter.setPen(penColor);
176
177         const int margin = 6;
178         QString ellidedProjectName = fm.elidedText(projectName, Qt::ElideMiddle, r.width() - margin);
179         if (isEnabled()) {
180             const QRectF shadowR = r.translated(0, 1);
181             painter.setPen(QColor(30, 30, 30, 80));
182             painter.drawText(shadowR, textFlags, ellidedProjectName);
183             painter.setPen(penColor);
184         }
185         painter.drawText(r, textFlags, ellidedProjectName);
186         textOffset = iconRect.center() + QPoint(iconRect.width()/2, iconRect.height()/2);
187         r = QRectF(0, textOffset.y()+5, rect().width(), lineHeight);
188         painter.setFont(boldFont);
189         QString ellidedBuildConfiguration = boldFm.elidedText(buildConfiguration, Qt::ElideMiddle, r.width() - margin);
190         if (isEnabled()) {
191             const QRectF shadowR = r.translated(0, 1);
192             painter.setPen(QColor(30, 30, 30, 80));
193             painter.drawText(shadowR, textFlags, ellidedBuildConfiguration);
194             painter.setPen(penColor);
195         }
196         if (!icon().isNull()) {
197             painter.drawText(r, textFlags, ellidedBuildConfiguration);
198             QStyleOption opt;
199             opt.initFrom(this);
200             opt.rect = rect().adjusted(rect().width() - 16, 0, -8, 0);
201             Utils::StyleHelper::drawArrow(QStyle::PE_IndicatorArrowRight, &painter, &opt);
202         }
203     } else {
204         iconRect.moveCenter(rect().center());
205         Utils::StyleHelper::drawIconWithShadow(icon(), iconRect, &painter, isEnabled() ? QIcon::Normal : QIcon::Disabled);
206     }
207 }
208
209 void FancyActionBar::paintEvent(QPaintEvent *event)
210 {
211     QPainter painter(this);
212     Q_UNUSED(event)
213     QColor light = Utils::StyleHelper::sidebarHighlight();
214     QColor dark = Utils::StyleHelper::sidebarShadow();
215     painter.setPen(dark);
216     painter.drawLine(rect().topLeft(), rect().topRight());
217     painter.setPen(light);
218     painter.drawLine(rect().topLeft() + QPoint(1,1), rect().topRight() + QPoint(0,1));
219 }
220
221 QSize FancyToolButton::sizeHint() const
222 {
223     QSizeF buttonSize = iconSize().expandedTo(QSize(64, 38));
224     if (defaultAction()->property("titledAction").toBool()) {
225         QFont boldFont(font());
226         boldFont.setPointSizeF(Utils::StyleHelper::sidebarFontSize());
227         boldFont.setBold(true);
228         QFontMetrics fm(boldFont);
229         qreal lineHeight = fm.height();
230         const QString projectName = defaultAction()->property("heading").toString();
231         buttonSize += QSizeF(0, 10);
232         if (!projectName.isEmpty())
233             buttonSize += QSizeF(0, lineHeight + 2);
234
235         const QString buildConfiguration = defaultAction()->property("subtitle").toString();
236         if (!buildConfiguration.isEmpty())
237             buttonSize += QSizeF(0, lineHeight + 2);
238     }
239     return buttonSize.toSize();
240 }
241
242 QSize FancyToolButton::minimumSizeHint() const
243 {
244     return QSize(8, 8);
245 }
246
247 void FancyToolButton::actionChanged()
248 {
249     // the default action changed in some way, e.g. it might got hidden
250     // since we inherit a tool button we won't get invisible, so do this here
251     if (!m_hasForceVisible) {
252         if (QAction* action = defaultAction())
253             setVisible(action->isVisible());
254     }
255 }
256
257 FancyActionBar::FancyActionBar(QWidget *parent)
258     : QWidget(parent)
259 {
260     setObjectName(QString::fromUtf8("actionbar"));
261     m_actionsLayout = new QVBoxLayout;
262     QVBoxLayout *spacerLayout = new QVBoxLayout;
263     spacerLayout->addLayout(m_actionsLayout);
264     int sbh = 8;
265     spacerLayout->addSpacing(sbh);
266     spacerLayout->setMargin(0);
267     spacerLayout->setSpacing(0);
268     setLayout(spacerLayout);
269     setContentsMargins(0,2,0,0);
270 }
271
272 void FancyActionBar::addProjectSelector(QAction *action)
273 {
274     FancyToolButton* toolButton = new FancyToolButton(this);
275     toolButton->setDefaultAction(action);
276     connect(action, SIGNAL(changed()), toolButton, SLOT(actionChanged()));
277     m_actionsLayout->insertWidget(0, toolButton);
278
279 }
280 void FancyActionBar::insertAction(int index, QAction *action)
281 {
282     FancyToolButton *toolButton = new FancyToolButton(this);
283     toolButton->setDefaultAction(action);
284     connect(action, SIGNAL(changed()), toolButton, SLOT(actionChanged()));
285     m_actionsLayout->insertWidget(index, toolButton);
286 }
287
288 QLayout *FancyActionBar::actionsLayout() const
289 {
290     return m_actionsLayout;
291 }
292
293 QSize FancyActionBar::minimumSizeHint() const
294 {
295     return sizeHint();
296 }
297