fw4spl
SlideBar.cpp
1 /* ***** BEGIN LICENSE BLOCK *****
2  * FW4SPL - Copyright (C) IRCAD, 2016-2018.
3  * Distributed under the terms of the GNU Lesser General Public License (LGPL) as
4  * published by the Free Software Foundation.
5  * ****** END LICENSE BLOCK ****** */
6 
7 #include "fwGuiQt/widget/SlideBar.hpp"
8 
9 #include "fwGuiQt/QtMainFrame.hpp"
10 
11 #include <fwCore/spyLog.hpp>
12 
13 #include <QHBoxLayout>
14 #include <QParallelAnimationGroup>
15 #include <QPropertyAnimation>
16 #include <QPushButton>
17 #include <QVBoxLayout>
18 
19 namespace fwGuiQt
20 {
21 
22 namespace widget
23 {
24 
25 //-----------------------------------------------------------------------------
26 
27 SlideBar::SlideBar(QWidget* parent, Aligment align, int buttonSize, double opacity) :
28  QGroupBox(),
29  m_buttonSize(buttonSize),
30  m_opacity(opacity),
31  m_isShown(false),
32  m_align(align)
33 {
34  this->setParent(parent);
35  this->init();
36 }
37 
38 //-----------------------------------------------------------------------------
39 
40 void SlideBar::init()
41 {
42  this->setObjectName("SlideBar");
43 
44  // Set the widget position
45  this->updatePosition();
46  this->setGeometry(m_hiddenPosition);
47 
48  // window flags to have a frameless dialog that can be displayed over an openGL widget
49  this->setWindowFlags(Qt::Tool
50  | Qt::FramelessWindowHint
51  | Qt::NoDropShadowWindowHint
52  );
53 
54  // Set the transparent background
55  this->setAttribute(Qt::WA_TranslucentBackground);
56 
57  // Listen parent and activeWindow 'Resize' and 'Move' event to update widget position
58  // (just listening parent event is not enough because the Move event is only send on activeWindow).
59  this->parent()->installEventFilter(this);
60 
61  auto activeWindow = qApp->activeWindow();
62  if(activeWindow)
63  {
64  activeWindow->installEventFilter(this);
65  }
66 }
67 
68 //-----------------------------------------------------------------------------
69 
71 {
72 }
73 
74 //-----------------------------------------------------------------------------
75 
77 {
78  int height = this->parentWidget()->height();
79  int width = this->parentWidget()->width();
80 
81  switch (m_align)
82  {
83  case LEFT:
84  case RIGHT:
85  width = std::min(width, m_buttonSize);
86  this->setFixedWidth(width);
87  this->setFixedHeight(height);
88  break;
89  case TOP:
90  case BOTTOM:
91  height = std::min(height, m_buttonSize);
92  this->setFixedHeight(height);
93  this->setFixedWidth(width);
94  break;
95  }
96 
97  if (m_align == LEFT)
98  {
99  QPoint pos = this->parentWidget()->rect().topLeft();
100  pos = this->parentWidget()->mapToGlobal(pos);
101 
102  m_shownPosition = QRect(pos.x(), pos.y(), width, height);
103  m_hiddenPosition = QRect(pos.x()-width, pos.y(), 0, height);
104  }
105  else if (m_align == RIGHT)
106  {
107  QPoint pos = this->parentWidget()->rect().topRight();
108  pos = this->parentWidget()->mapToGlobal(pos);
109 
110  m_shownPosition = QRect(pos.x()-width, pos.y(), width, height);
111  m_hiddenPosition = QRect(pos.x(), pos.y(), 0, height);
112  }
113  else if (m_align == TOP)
114  {
115  QPoint pos = this->parentWidget()->rect().topLeft();
116  pos = this->parentWidget()->mapToGlobal(pos);
117 
118  m_shownPosition = QRect(pos.x(), pos.y(), width, height);
119  m_hiddenPosition = QRect(pos.x(), pos.y()-height, width, 0);
120  }
121  else // m_align == BOTTOM
122  {
123  QPoint pos = this->parentWidget()->rect().bottomLeft();
124  pos = this->parentWidget()->mapToGlobal(pos);
125 
126  m_shownPosition = QRect(pos.x(), pos.y()-height, width, height);
127  m_hiddenPosition = QRect(pos.x(), pos.y(), width, 0);
128  }
129 
130  if (m_isShown)
131  {
132  this->setGeometry(m_shownPosition);
133  }
134  else
135  {
136  this->setGeometry(m_hiddenPosition);
137  }
138 }
139 
140 //-----------------------------------------------------------------------------
141 
142 void SlideBar::setSide(Aligment align)
143 {
144  m_align = align;
145  this->updatePosition();
146 }
147 //-----------------------------------------------------------------------------
148 
149 void SlideBar::setVisible(bool visible)
150 {
151  this->slide(visible);
152 }
153 
154 //-----------------------------------------------------------------------------
155 
156 void SlideBar::forceHide()
157 {
158  this->QGroupBox::setVisible(false);
159 }
160 
161 //-----------------------------------------------------------------------------
162 
163 void SlideBar::forceShow()
164 {
165  this->QGroupBox::setVisible(true);
166 }
167 
168 //-----------------------------------------------------------------------------
169 
170 void SlideBar::slide(bool visible)
171 {
172  // Show the widget with the previous opacity. It must be hidden after the slide(false) because if opacity == 0, the
173  // widget is still clickable.
174  this->forceShow();
175  this->setWindowOpacity(m_isShown ? m_opacity : 0);
176 
177  // Set animation to slide the widget and update the opacity
178  QParallelAnimationGroup* animations = new QParallelAnimationGroup();
179 
180  // slide animation
181  QPropertyAnimation* geomAnimation = new QPropertyAnimation(this, "geometry");
182  geomAnimation->setDuration(500);
183  geomAnimation->setEasingCurve(QEasingCurve::InBack);
184  geomAnimation->setStartValue(this->geometry());
185 
186  if(visible == true)
187  {
188  geomAnimation->setEndValue(m_shownPosition);
189  }
190  else
191  {
192  geomAnimation->setEndValue(m_hiddenPosition);
193 
194  // hide the widget when the animation is finished (if opacity == 0, widget is still clickable)
195  QObject::connect(animations, &QAbstractAnimation::finished, this, &SlideBar::forceHide);
196  }
197 
198  // opacity animation
199  QPropertyAnimation* opacityAnimation = new QPropertyAnimation(this, "windowOpacity");
200  opacityAnimation->setDuration(500);
201  opacityAnimation->setEndValue(visible ? m_opacity : 0);
202 
203  animations->addAnimation(geomAnimation);
204  animations->addAnimation(opacityAnimation);
205 
206  animations->start(QPropertyAnimation::DeleteWhenStopped);
207  m_isShown = visible;
208 }
209 
210 //-----------------------------------------------------------------------------
211 
212 bool SlideBar::eventFilter(QObject* obj, QEvent* event)
213 {
214  // Update the widget position when the parent is moved or resized
215  if (event->type() == QEvent::Resize
216  || event->type() == QEvent::Move)
217  {
218  this->updatePosition();
219  }
220  else if (event->type() == QEvent::WindowActivate)
221  {
222  auto activeWindow = qApp->activeWindow();
223  SLM_ASSERT("No active window", activeWindow);
224  activeWindow->installEventFilter(this);
225  this->updatePosition();
226  }
227  else if (event->type() == QEvent::WindowDeactivate)
228  {
229  auto mainFrame = dynamic_cast< ::fwGuiQt::QtMainFrame*>(obj);
230  if(mainFrame)
231  {
232  mainFrame->removeEventFilter(this);
233  }
234  }
235  return QObject::eventFilter(obj, event);
236 }
237 
238 //-----------------------------------------------------------------------------
239 
240 } // namespace widget
241 } // namespace fwGuiQt
virtual FWGUIQT_API ~SlideBar()
Destructor.
Definition: SlideBar.cpp:70
FWGUIQT_API void updatePosition()
Update the shown/hide positions.
Definition: SlideBar.cpp:76
FWGUIQT_API void setSide(Aligment align)
Set the widget align.
Definition: SlideBar.cpp:142
The namespace fwGuiQt contains classes which provide the implementation of the Gui using Qt library...
Definition: WindowLevel.hpp:32
FWGUIQT_API SlideBar(QWidget *parent, Aligment align=LEFT, int buttonWidth=200, double opacity=0.8)
SlideBar constructor.
Definition: SlideBar.cpp:27
A qt panel used to control a VTK 2D Negatoscope view.
Definition: QtMainFrame.hpp:24
#define SLM_ASSERT(message, cond)
work like &#39;assert&#39; from &#39;cassert&#39;, with in addition a message logged by spylog (with FATAL loglevel) ...
Definition: spyLog.hpp:308
bool eventFilter(QObject *obj, QEvent *event) override
Filter &#39;Resize&#39; and &#39;Move&#39; events to update the widget position.
Definition: SlideBar.cpp:212
This file defines SpyLog macros. These macros are used to log messages to a file or to the console du...
virtual FWGUIQT_API void setVisible(bool visible) override
Show/hide the slide widget. The widget is animated.
Definition: SlideBar.cpp:149