BornAgain  1.19.0
Simulate and fit neutron and x-ray scattering at grazing incidence
detailsbutton.cpp
Go to the documentation of this file.
1 /****************************************************************************
2 **
3 ** Copyright (C) 2016 The Qt Company Ltd.
4 ** Contact: https://www.qt.io/licensing/
5 **
6 ** This file is part of Qt Creator.
7 **
8 ** Commercial License Usage
9 ** Licensees holding valid commercial Qt licenses may use this file in
10 ** accordance with the commercial license agreement provided with the
11 ** Software or, alternatively, in accordance with the terms contained in
12 ** a written agreement between you and The Qt Company. For licensing terms
13 ** and conditions see https://www.qt.io/terms-conditions. For further
14 ** information use the contact form at https://www.qt.io/contact-us.
15 **
16 ** GNU General Public License Usage
17 ** Alternatively, this file may be used under the terms of the GNU
18 ** General Public License version 3 as published by the Free Software
19 ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
20 ** included in the packaging of this file. Please review the following
21 ** information to ensure the GNU General Public License requirements will
22 ** be met: https://www.gnu.org/licenses/gpl-3.0.html.
23 **
24 ****************************************************************************/
25 
28 
29 #include <QGraphicsOpacityEffect>
30 #include <QGuiApplication>
31 #include <QPaintEvent>
32 #include <QPainter>
33 #include <QPropertyAnimation>
34 #include <QStyleOption>
35 
36 using namespace Utils;
37 
38 namespace {
39 const bool FlatProjectsMode(false);
40 const QColor DetailsButtonBackgroundColorHover("#eff0f1");
41 } // namespace
42 
44  : FadingPanel(parent), m_opacityEffect(new QGraphicsOpacityEffect)
45 {
46  m_opacityEffect->setOpacity(0);
47  setGraphicsEffect(m_opacityEffect);
48 
49  // Workaround for issue with QGraphicsEffect. GraphicsEffect
50  // currently clears with Window color. Remove if flickering
51  // no longer occurs on fade-in
52  QPalette pal;
53  pal.setBrush(QPalette::All, QPalette::Window, Qt::transparent);
54  setPalette(pal);
55 }
56 
57 void FadingWidget::setOpacity(qreal value)
58 {
59  m_opacityEffect->setOpacity(value);
60 }
61 
62 void FadingWidget::fadeTo(qreal value)
63 {
64  QPropertyAnimation* animation = new QPropertyAnimation(m_opacityEffect, "opacity");
65  animation->setDuration(200);
66  animation->setEndValue(value);
67  animation->start(QAbstractAnimation::DeleteWhenStopped);
68 }
69 
71 {
72  return m_opacityEffect->opacity();
73 }
74 
75 DetailsButton::DetailsButton(QWidget* parent) : QAbstractButton(parent), m_fader(0)
76 {
77  setCheckable(true);
78  setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Minimum);
79  setText(tr("Details"));
80 }
81 
83 {
84  // TODO: Adjust this when icons become available!
85 
86 #if QT_VERSION >= QT_VERSION_CHECK(5, 11, 0)
87  const int w = fontMetrics().horizontalAdvance(text()) + 32;
88 #else
89  const int w = fontMetrics().width(text()) + 32;
90 #endif
92  return QSize(w, 34);
93  return QSize(w, 22);
94 }
95 
96 bool DetailsButton::event(QEvent* e)
97 {
98  switch (e->type()) {
99  case QEvent::Enter: {
100  QPropertyAnimation* animation = new QPropertyAnimation(this, "fader");
101  animation->setDuration(200);
102  animation->setEndValue(1.0);
103  animation->start(QAbstractAnimation::DeleteWhenStopped);
104  } break;
105  case QEvent::Leave: {
106  QPropertyAnimation* animation = new QPropertyAnimation(this, "fader");
107  animation->setDuration(200);
108  animation->setEndValue(0.0);
109  animation->start(QAbstractAnimation::DeleteWhenStopped);
110  } break;
111  default:
112  return QAbstractButton::event(e);
113  }
114  return false;
115 }
116 
117 void DetailsButton::paintEvent(QPaintEvent* e)
118 {
119  QWidget::paintEvent(e);
120 
121  QPainter p(this);
122 
123  // draw hover animation
124  if (!GUI_OS_Utils::HostOsInfo::isMacHost() && !isDown() && m_fader > 0) {
125  QColor c = DetailsButtonBackgroundColorHover;
126  c.setAlpha(int(m_fader * c.alpha()));
127 
128  QRect r = rect();
129  if (!FlatProjectsMode)
130  r.adjust(1, 1, -2, -2);
131  p.fillRect(r, c);
132  }
133 
134  if (isChecked()) {
135  if (m_checkedPixmap.isNull()
136  || m_checkedPixmap.size() / m_checkedPixmap.devicePixelRatio() != contentsRect().size())
137  m_checkedPixmap = cacheRendering(contentsRect().size(), true);
138  p.drawPixmap(contentsRect(), m_checkedPixmap);
139  } else {
140  if (m_uncheckedPixmap.isNull()
141  || m_uncheckedPixmap.size() / m_uncheckedPixmap.devicePixelRatio()
142  != contentsRect().size())
143  m_uncheckedPixmap = cacheRendering(contentsRect().size(), false);
144  p.drawPixmap(contentsRect(), m_uncheckedPixmap);
145  }
146  if (isDown()) {
147  p.setPen(Qt::NoPen);
148  p.setBrush(QColor(0, 0, 0, 20));
149  p.drawRoundedRect(rect().adjusted(1, 1, -1, -1), 1, 1);
150  }
151  if (hasFocus()) {
152  QStyleOptionFocusRect option;
153  option.initFrom(this);
154  style()->drawPrimitive(QStyle::PE_FrameFocusRect, &option, &p, this);
155  }
156 }
157 
158 QPixmap DetailsButton::cacheRendering(const QSize& size, bool checked)
159 {
160  const qreal pixelRatio = devicePixelRatio();
161  QPixmap pixmap(size * pixelRatio);
162  pixmap.setDevicePixelRatio(pixelRatio);
163  pixmap.fill(Qt::transparent);
164  QPainter p(&pixmap);
165  p.setRenderHint(QPainter::Antialiasing, true);
166  p.translate(0.5, 0.5);
167 
168  if (!FlatProjectsMode) {
169  QLinearGradient lg;
170  lg.setCoordinateMode(QGradient::ObjectBoundingMode);
171  lg.setFinalStop(0, 1);
172  if (!checked) {
173  lg.setColorAt(0, QColor(0, 0, 0, 10));
174  lg.setColorAt(1, QColor(0, 0, 0, 16));
175  } else {
176  lg.setColorAt(0, QColor(255, 255, 255, 0));
177  lg.setColorAt(1, QColor(255, 255, 255, 50));
178  }
179  p.setBrush(lg);
180  p.setPen(QColor(255, 255, 255, 140));
181  p.drawRoundedRect(1, 1, size.width() - 3, size.height() - 3, 1, 1);
182  p.setPen(QPen(QColor(0, 0, 0, 40)));
183  p.drawLine(0, 1, 0, size.height() - 2);
184  if (checked)
185  p.drawLine(1, size.height() - 1, size.width() - 1, size.height() - 1);
186  } else {
187  p.setPen(Qt::NoPen);
188  p.drawRoundedRect(0, 0, size.width(), size.height(), 1, 1);
189  }
190 
191  p.setPen(palette().color(QPalette::Text));
192 
193  QRect textRect = p.fontMetrics().boundingRect(text());
194  textRect.setWidth(textRect.width() + 15);
195  textRect.setHeight(textRect.height() + 4);
196  textRect.moveCenter(rect().center());
197 
198  p.drawText(textRect, Qt::AlignLeft | Qt::AlignVCenter, text());
199 
200  int arrowsize = 15;
201  QStyleOption arrowOpt;
202  arrowOpt.initFrom(this);
203  QPalette pal = arrowOpt.palette;
204  pal.setBrush(QPalette::All, QPalette::Text, QColor(0, 0, 0));
205  arrowOpt.rect =
206  QRect(size.width() - arrowsize - 6, height() / 2 - arrowsize / 2, arrowsize, arrowsize);
207  arrowOpt.palette = pal;
208  style()->drawPrimitive(checked ? QStyle::PE_IndicatorArrowUp : QStyle::PE_IndicatorArrowDown,
209  &arrowOpt, &p, this);
210  return pixmap;
211 }
static bool isMacHost()
Definition: hostosinfo.h:69
bool event(QEvent *e)
void paintEvent(QPaintEvent *e)
DetailsButton(QWidget *parent=0)
QPixmap cacheRendering(const QSize &size, bool checked)
QSize sizeHint() const
QGraphicsOpacityEffect * m_opacityEffect
Definition: detailsbutton.h:52
void fadeTo(qreal value)
void setOpacity(qreal value)
FadingWidget(QWidget *parent=0)
Defines Utils namespace.