• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • workspace API Reference
  • KDE Home
  • Contact Us
 

liblancelot

  • sources
  • kde-4.14
  • workspace
  • kdeplasma-addons
  • libs
  • lancelot
  • widgets
ExtenderButton.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2007, 2008, 2009, 2010 Ivan Cukic <ivan.cukic(at)kde.org>
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU Lesser/Library General Public License version 2,
6  * or (at your option) any later version, as published by the Free
7  * Software Foundation
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU Lesser/Library General Public License for more details
13  *
14  * You should have received a copy of the GNU Lesser/Library General Public
15  * License along with this program; if not, write to the
16  * Free Software Foundation, Inc.,
17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18  */
19 
20 #include "ExtenderButton.h"
21 
22 #include <QAction>
23 #include <QGraphicsScene>
24 #include <QGraphicsView>
25 #include <QIcon>
26 #include <QRectF>
27 #include <QTimer>
28 #include <QPointer>
29 
30 #include <KDebug>
31 
32 #define ACTIVATION_TIME 300
33 #define EXTENDER_Z_VALUE 100000.0
34 
35 namespace Lancelot {
36 
37 // Inner class ExtenderObject
38 class ExtenderObject : public BasicWidget {
39 public:
40  ExtenderObject(const Plasma::Svg & icon,
41  ExtenderButton * parent)
42  : BasicWidget(icon, "", "")
43  {
44  iconInSvg().setUsingRenderingCache(true);
45 
46  iconInSvg().setContainsMultipleImages(true);
47 
48  frameCount = 0;
49  while (iconInSvg().hasElement("frame" + QString::number(frameCount))) {
50  frameCount++;
51  }
52  frameCount--;
53 
54  setParentItem(parent);
55  setInnerOrientation(Qt::Vertical);
56  setAlignment(Qt::AlignCenter);
57  setZValue(EXTENDER_Z_VALUE);
58 
59  animate = !Global::self()->config("Animation", "disableAnimations", false)
60  && Global::self()->config("Animation", "extenderActivationFeedback", true);
61  }
62 
63  L_Override void hoverEnterEvent(QGraphicsSceneHoverEvent * event)
64  {
65  timer.start(ACTIVATION_TIME / frameCount, this);
66 
67  BasicWidget::hoverEnterEvent(event);
68  }
69 
70  L_Override void hoverLeaveEvent(QGraphicsSceneHoverEvent * event)
71  {
72  timer.stop();
73  frame = 0;
74 
75  BasicWidget::hoverLeaveEvent(event);
76  }
77 
78  void paint(QPainter * painter,
79  const QStyleOptionGraphicsItem * option, QWidget * widget)
80  {
81  Q_UNUSED(option);
82  Q_UNUSED(widget);
83 
84  // BasicWidget::paint(painter, option, widget);
85  if (iconInSvg().isValid()) {
86  QRectF iconRect = QRectF(QPointF(), iconSize());
87  QSizeF sizeDiff = size() - iconRect.size();
88 
89  iconRect.setTopLeft(QPointF(sizeDiff.width() / 2, sizeDiff.height() / 2));
90  if (animate) {
91  iconInSvg().paint(painter,
92  iconRect.left(),
93  iconRect.top(),
94  "frame" + QString::number(frame));
95  } else {
96  iconInSvg().paint(painter,
97  iconRect.left(),
98  iconRect.top(),
99  "frame" + QString::number(
100  (frame > 0) ? frameCount : 0
101  ));
102 
103  }
104  }
105  }
106 
107  L_Override void showEvent(QShowEvent * event)
108  {
109  frame = 0;
110  }
111 
112  L_Override void timerEvent(QTimerEvent * event)
113  {
114  if (event->timerId() == timer.timerId()) {
115  frame ++;
116 
117  if (frame > frameCount) {
118  timer.stop();
119  frame = 0;
120 
121  emit clicked();
122 
123  } else {
124  if (animate || frame == 1) {
125  update();
126  }
127  }
128  }
129 
130  BasicWidget::timerEvent(event);
131  }
132 
133  int frameCount;
134  bool animate;
135 
136 public:
137  // Plasma::FrameSvg::EnabledBorders borders;
138 
139  QBasicTimer timer;
140  int frame;
141 
142  friend class ExtenderButton;
143 };
144 
145 // ExtenderButton
146 class ExtenderButton::Private {
147 public:
148  Private(ExtenderButton * parent)
149  : q(parent),
150  shortcut(NULL),
151  extenderPosition(NoExtender),
152  activationMethod(ClickActivate),
153  checkable(false),
154  checked(false)
155  {
156  if (!extenderIconSvg.isValid()) {
157  extenderIconSvg.setImagePath("lancelot/extender-button-icon");
158  }
159 
160  if (!timer) {
161  timer = new QTimer();
162  timer->setInterval(ACTIVATION_TIME);
163  timer->setSingleShot(true);
164  }
165 
166  }
167 
168  void releaseExtender() {
169  ExtenderObject * ext = extender(false);
170  if (ext) {
171  ext->setVisible(false);
172  ext->hoverLeaveEvent(NULL);
173  ext->setParentItem(NULL);
174  }
175 
176  disconnectTimer();
177  }
178 
179  void disconnectTimer() {
180  timer->stop();
181  disconnect(timer, SIGNAL(timeout()), 0, 0);
182  }
183 
184  void connectTimer() {
185  disconnectTimer();
186 
187  connect(
188  timer, SIGNAL(timeout()),
189  q, SLOT(activate())
190  );
191  }
192 
193  ExtenderObject * extender(bool take = true) {
194  ExtenderObject * result = 0;
195 
196  if (!m_extenders.contains(q->scene()) ||
197  !m_extenders[q->scene()]) {
198  result = new ExtenderObject(extenderIconSvg, NULL);
199 
200  result->setVisible(false);
201  result->setIconSize(QSize(16, 16));
202 
203  m_extenders[q->scene()] = result;
204  } else {
205  result = m_extenders[q->scene()];
206  }
207 
208  if (result->parentItem() != q) {
209  if (!take) {
210  return NULL;
211  }
212 
213  result->setParentItem(q);
214  result->setGroupByName(
215  q->group()->name() + "-Extender"
216  );
217 
218  connectTimer();
219 
220  disconnect(result, SIGNAL(clicked()), 0, 0);
221  connect(result, SIGNAL(clicked()),
222  q, SLOT(activate()));
223  relayoutExtender();
224  }
225 
226  return result;
227  }
228 
229  ~Private()
230  {
231  }
232 
233  void relayoutExtender()
234  {
235  if (!m_extenders.contains(q->scene())
236  || !m_extenders[q->scene()]
237  || q != m_extenders[q->scene()]->parentItem()) return;
238  QRectF geometry = QRectF(QPointF(0, 0), q->size());
239 
240  // extender()->borders = Plasma::FrameSvg::AllBorders;
241  borders = Plasma::FrameSvg::AllBorders;
242 
243  switch (extenderPosition) {
244  case TopExtender:
245  geometry.setHeight(EXTENDER_SIZE);
246  geometry.moveTop(- EXTENDER_SIZE);
247  // borders &= ~ Plasma::FrameSvg::TopBorder;
248  // extender()->borders &= ~ Plasma::FrameSvg::BottomBorder;
249  break;
250  case BottomExtender:
251  geometry.moveTop(geometry.bottom());
252  geometry.setHeight(EXTENDER_SIZE);
253  // borders &= ~ Plasma::FrameSvg::BottomBorder;
254  // extender()->borders &= ~ Plasma::FrameSvg::TopBorder;
255  break;
256  case LeftExtender:
257  geometry.setWidth(EXTENDER_SIZE);
258  geometry.moveLeft(- EXTENDER_SIZE);
259  // borders &= ~ Plasma::FrameSvg::LeftBorder;
260  // extender()->borders &= ~ Plasma::FrameSvg::RightBorder;
261  break;
262  case RightExtender:
263  geometry.moveLeft(geometry.right());
264  geometry.setWidth(EXTENDER_SIZE);
265  // borders &= ~ Plasma::FrameSvg::RightBorder;
266  // extender()->borders &= ~ Plasma::FrameSvg::LeftBorder;
267  break;
268  case NoExtender:
269  break;
270  }
271  extender()->setGeometry(geometry);
272  extender()->setPreferredSize(geometry.size());
273 
274  // qreal left, top, right, bottom;
275  // q->getContentsMargins(&left, &top, &right, &bottom);
276  }
277 
278  ExtenderButton * q;
279  QAction * shortcut;
280 
281  ExtenderPosition extenderPosition;
282  ActivationMethod activationMethod;
283 
284  Plasma::FrameSvg::EnabledBorders borders;
285 
286  static Plasma::Svg extenderIconSvg;
287  static QHash < QGraphicsScene *, QPointer < ExtenderObject > > m_extenders;
288  static QTimer * timer;
289 
290  bool checkable : 1;
291  bool checked : 1;
292 
293 };
294 
295 Plasma::Svg ExtenderButton::Private::extenderIconSvg;
296 QHash < QGraphicsScene *, QPointer < ExtenderObject > > ExtenderButton::Private::m_extenders;
297 QTimer * ExtenderButton::Private::timer = 0;
298 
299 ExtenderButton::ExtenderButton(QGraphicsItem * parent)
300  : BasicWidget(parent),
301  d(new Private(this))
302 {
303  setGroupByName("ExtenderButton");
304  connect(this, SIGNAL(clicked()), this, SLOT(activate()));
305 }
306 
307 ExtenderButton::ExtenderButton(QString title,
308  QString description, QGraphicsItem * parent)
309  : BasicWidget(title, description, parent),
310  d(new Private(this))
311 {
312  setGroupByName("ExtenderButton");
313  connect(this, SIGNAL(clicked()), this, SLOT(activate()));
314 
315  setTitle(title);
316 }
317 
318 ExtenderButton::ExtenderButton(QIcon icon, QString title,
319  QString description, QGraphicsItem * parent)
320  : BasicWidget(icon, title, description, parent),
321  d(new Private(this))
322 {
323  setGroupByName("ExtenderButton");
324  connect(this, SIGNAL(clicked()), this, SLOT(activate()));
325 
326  setTitle(title);
327 }
328 
329 ExtenderButton::ExtenderButton(const Plasma::Svg & icon, QString title,
330  QString description, QGraphicsItem * parent)
331  : BasicWidget(icon, title, description, parent),
332  d(new Private(this))
333 {
334  setGroupByName("ExtenderButton");
335  connect(this, SIGNAL(clicked()), this, SLOT(activate()));
336 
337  setTitle(title);
338 }
339 
340 void ExtenderButton::setGroup(Group * g)
341 {
342  BasicWidget::setGroup(g);
343 }
344 
345 ExtenderButton::~ExtenderButton()
346 {
347  if (Private::m_extenders.contains(scene())
348  && Private::m_extenders[scene()]->parentItem() == this) {
349  Private::m_extenders[scene()]->setParentItem(0);
350  }
351 
352  delete d;
353 }
354 
355 QRectF ExtenderButton::boundingRect() const
356 {
357  return QRectF(0, 0, size().width(), size().height());
358 }
359 
360 void ExtenderButton::hoverEnterEvent(QGraphicsSceneHoverEvent * event)
361 {
362  if (d->extenderPosition != NoExtender) {
363  d->extender()->setVisible(true);
364  } else if (d->activationMethod == HoverActivate) {
365  d->connectTimer();
366  d->timer->start();
367  }
368  BasicWidget::hoverEnterEvent(event);
369 }
370 
371 void ExtenderButton::hideEvent(QHideEvent * event)
372 {
373  BasicWidget::hideEvent(event);
374  d->releaseExtender();
375 }
376 
377 void ExtenderButton::hoverLeaveEvent(QGraphicsSceneHoverEvent * event)
378 {
379  BasicWidget::hoverLeaveEvent(event);
380  d->releaseExtender();
381 }
382 
383 void ExtenderButton::setExtenderPosition(int position)
384 {
385  if (d->extenderPosition == position)
386  return;
387  d->extenderPosition = (ExtenderPosition) position;
388  d->relayoutExtender();
389 }
390 
391 int ExtenderButton::extenderPosition() const
392 {
393  return d->extenderPosition;
394 }
395 
396 void ExtenderButton::setActivationMethod(int method)
397 {
398  if (d->activationMethod == method)
399  return;
400  d->activationMethod = (ActivationMethod) method;
401  if (d->activationMethod != ExtenderActivate)
402  setExtenderPosition(NoExtender);
403 }
404 
405 int ExtenderButton::activationMethod() const
406 {
407  return d->activationMethod;
408 }
409 
410 void ExtenderButton::activate()
411 {
412  toggle();
413 
414  hoverLeaveEvent(0);
415  d->releaseExtender();
416 
417  update();
418 
419  emit activated();
420 }
421 
422 void ExtenderButton::resizeEvent(QGraphicsSceneResizeEvent * event)
423 {
424  BasicWidget::resizeEvent(event);
425  d->relayoutExtender();
426 }
427 
428 void ExtenderButton::paint(QPainter * painter,
429  const QStyleOptionGraphicsItem * option, QWidget * widget)
430 {
431  Q_UNUSED(option);
432  Q_UNUSED(widget);
433 
434  // if (Plasma::FrameSvg * svg = group()->backgroundSvg()) {
435  // if (isHovered() && (d->extenderPosition != NoExtender)) {
436  // svg->setEnabledBorders(d->borders);
437  // } else {
438  // svg->setEnabledBorders(Plasma::FrameSvg::AllBorders);
439  // }
440  // }
441 
442  if (d->checked && !isDown()) {
443  paintBackground(painter, "checked");
444  } else {
445  paintBackground(painter);
446  }
447  paintForeground(painter);
448 }
449 
450 void ExtenderButton::setChecked(bool checked)
451 {
452  if (!d->checkable) return;
453  if (d->checked == checked) return;
454  d->checked = checked;
455  update();
456  emit toggled(d->checked);
457 }
458 
459 bool ExtenderButton::isChecked() const
460 {
461  return d->checked;
462 }
463 
464 void ExtenderButton::toggle()
465 {
466  if (!d->checkable) return;
467  d->checked = !d->checked;
468  update();
469  emit toggled(d->checked);
470 }
471 
472 void ExtenderButton::setCheckable(bool checkable)
473 {
474  if (d->checkable == checkable) return;
475  d->checkable = checkable;
476  if (!checkable) {
477  d->checked = false;
478  }
479  update();
480 }
481 
482 bool ExtenderButton::isCheckable() const
483 {
484  return d->checkable;
485 }
486 
487 void ExtenderButton::setShortcutKey(const QString & key)
488 {
489  kDebug() << title() << " set the key:" << key;
490 
491  if (key.isEmpty()) {
492  delete d->shortcut;
493  d->shortcut = NULL;
494  } else if (scene() && scene()->views().size()) {
495  if (!d->shortcut) {
496  d->shortcut = new QAction(this);
497  scene()->views().at(0)->addAction(d->shortcut);
498  }
499 
500  d->shortcut->setShortcut(QString(QLatin1String("Alt+")+ key));
501  connect(d->shortcut, SIGNAL(triggered()),
502  this, SIGNAL(activated()));
503  }
504 }
505 
506 } // namespace Lancelot
507 
QHideEvent
Lancelot::Widget::setGroupByName
virtual void setGroupByName(const QString &groupName)
Sets this widget's group by group name.
Definition: Widget.cpp:134
Lancelot::ExtenderButton::paint
L_Override void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget=0)
Definition: ExtenderButton.cpp:428
Lancelot::BasicWidget
Provides a common appearance with an icon, title and a description.
Definition: BasicWidget.h:44
Lancelot::NoExtender
Definition: lancelot.h:32
QWidget
Lancelot::ExtenderButton::isChecked
bool isChecked() const
Definition: ExtenderButton.cpp:459
Lancelot::ExtenderActivate
Definition: lancelot.h:42
Lancelot::ExtenderButton::hoverLeaveEvent
L_Override void hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
Definition: ExtenderButton.cpp:377
Lancelot::BasicWidget::title
QString title() const
Lancelot::Widget::clicked
void clicked()
Emitted when the button is clicked.
Lancelot::BasicWidget::setTitle
void setTitle(const QString &title)
Sets title of this Lancelot::BasicWidget.
Definition: BasicWidget.cpp:449
QBasicTimer
Lancelot::ExtenderButton::ExtenderObject
friend class ExtenderObject
Definition: ExtenderButton.h:180
Lancelot::ExtenderButton::activationMethod
int activationMethod() const
QGraphicsLayoutItem::geometry
QRectF geometry() const
Lancelot::ExtenderButton::setCheckable
void setCheckable(bool checkable)
Makes the button checkable when set to true.
Definition: ExtenderButton.cpp:472
Lancelot::ExtenderButton::toggled
void toggled(bool checked)
Emitted when the state of a checkable button is changed.
Lancelot::Global::self
static Global * self()
Definition: Global.cpp:307
EXTENDER_Z_VALUE
#define EXTENDER_Z_VALUE
Definition: ExtenderButton.cpp:33
Lancelot::ExtenderButton::ExtenderButton
ExtenderButton(QGraphicsItem *parent=0)
Creates a new Lancelot::ExtenderButton.
Definition: ExtenderButton.cpp:299
Lancelot::ExtenderButton::~ExtenderButton
virtual ~ExtenderButton()
Destroys Lancelot::ExtenderButton.
Definition: ExtenderButton.cpp:345
QRectF::size
QSizeF size() const
Lancelot::Widget::setGroup
virtual void setGroup(Group *group=NULL)
Sets this widget's group.
Definition: Widget.cpp:139
QRectF::top
qreal top() const
QGraphicsItem
Lancelot::ExtenderButton::toggle
void toggle()
Toggles the checked state.
Definition: ExtenderButton.cpp:464
EXTENDER_SIZE
#define EXTENDER_SIZE
Definition: ExtenderButton.h:28
QGraphicsItem::scene
QGraphicsScene * scene() const
QObject::timerEvent
virtual void timerEvent(QTimerEvent *event)
QObject::disconnect
bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
QRectF::left
qreal left() const
L_Override
#define L_Override
Definition: lancelot_export.h:41
QGraphicsItem::update
void update(const QRectF &rect)
QRectF::setHeight
void setHeight(qreal height)
QPointF
QGraphicsWidget::size
QSizeF size() const
QRectF::bottom
qreal bottom() const
QTimerEvent
QString::number
QString number(int n, int base)
Lancelot::BasicWidget::paintForeground
void paintForeground(QPainter *painter)
Common implementation of icon/text/description rendering.
Definition: BasicWidget.cpp:177
Lancelot::BottomExtender
Definition: lancelot.h:36
QTimer
QHash
QShowEvent
QGraphicsScene::views
QList< QGraphicsView * > views() const
QPainter
Lancelot::Group
Represents a group of object.
Definition: Global.h:63
QString::isEmpty
bool isEmpty() const
Lancelot::TopExtender
Definition: lancelot.h:35
Lancelot::Widget::paintBackground
void paintBackground(QPainter *painter)
Paints the widget background using the widget's SVG.
Definition: Widget.cpp:158
Lancelot::Global::config
KConfig * config()
Definition: Global.cpp:425
QRectF::moveLeft
void moveLeft(qreal x)
Lancelot::ExtenderButton::setExtenderPosition
void setExtenderPosition(int position)
Sets the position of the extender.
Definition: ExtenderButton.cpp:383
ACTIVATION_TIME
#define ACTIVATION_TIME
Definition: ExtenderButton.cpp:32
QString
QGraphicsSceneResizeEvent
QGraphicsSceneHoverEvent
QRectF::right
qreal right() const
QSize
Lancelot::LeftExtender
Definition: lancelot.h:34
Lancelot::ExtenderButton::extenderPosition
int extenderPosition() const
QRectF::setTopLeft
void setTopLeft(const QPointF &position)
Lancelot::ExtenderButton::setGroup
L_Override void setGroup(Group *group=NULL)
Sets this widget's group.
Definition: ExtenderButton.cpp:340
Lancelot::ExtenderButton::activate
void activate()
Definition: ExtenderButton.cpp:410
Lancelot::ExtenderButton::activated
void activated()
Emitted when the button is activated.
Lancelot::ExtenderButton::setChecked
void setChecked(bool checked)
Sets whether the button is checked.
Definition: ExtenderButton.cpp:450
Lancelot::Widget::hideEvent
L_Override void hideEvent(QHideEvent *event)
Definition: Widget.cpp:256
QSizeF
Lancelot::ExtenderButton::boundingRect
L_Override QRectF boundingRect() const
Definition: ExtenderButton.cpp:355
QLatin1String
Lancelot::ExtenderButton::checkable
bool checkable
Definition: ExtenderButton.h:47
QRectF
QRectF::setWidth
void setWidth(qreal width)
Lancelot::Widget::hoverEnterEvent
L_Override void hoverEnterEvent(QGraphicsSceneHoverEvent *event)
Definition: Widget.cpp:59
Lancelot::Widget::isDown
bool isDown() const
Definition: Widget.cpp:251
ExtenderButton.h
QAction
Lancelot::Widget::hoverLeaveEvent
L_Override void hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
Definition: Widget.cpp:71
Lancelot::ExtenderButton::hideEvent
L_Override void hideEvent(QHideEvent *event)
Definition: ExtenderButton.cpp:371
Lancelot::ExtenderButton::isCheckable
bool isCheckable() const
Definition: ExtenderButton.cpp:482
QTimerEvent::timerId
int timerId() const
Lancelot::ExtenderButton::hoverEnterEvent
L_Override void hoverEnterEvent(QGraphicsSceneHoverEvent *event)
Definition: ExtenderButton.cpp:360
QStyleOptionGraphicsItem
QGraphicsItem::parentItem
QGraphicsItem * parentItem() const
Lancelot::ExtenderButton::checked
bool checked
Definition: ExtenderButton.h:48
Lancelot::ExtenderPosition
ExtenderPosition
Definition: lancelot.h:31
Lancelot::ActivationMethod
ActivationMethod
Definition: lancelot.h:39
QSizeF::height
qreal height() const
QRectF::moveTop
void moveTop(qreal y)
QObject::connect
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
QObject::parent
QObject * parent() const
Lancelot::HoverActivate
Definition: lancelot.h:40
QGraphicsItem::contains
virtual bool contains(const QPointF &point) const
QGraphicsWidget::resizeEvent
virtual void resizeEvent(QGraphicsSceneResizeEvent *event)
Lancelot::ExtenderButton::setActivationMethod
void setActivationMethod(int method)
Sets the activation method of the ExtenderButton.
Definition: ExtenderButton.cpp:396
QSizeF::width
qreal width() const
QIcon
Lancelot::ClickActivate
Definition: lancelot.h:41
Lancelot::ExtenderButton::resizeEvent
L_Override void resizeEvent(QGraphicsSceneResizeEvent *event)
Definition: ExtenderButton.cpp:422
Lancelot::RightExtender
Definition: lancelot.h:33
Lancelot::ExtenderButton::setShortcutKey
L_Override void setShortcutKey(const QString &key)
Sets a shortcut key.
Definition: ExtenderButton.cpp:487
This file is part of the KDE documentation.
Documentation copyright © 1996-2020 The KDE developers.
Generated on Mon Jun 22 2020 13:43:01 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

liblancelot

Skip menu "liblancelot"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members
  • Related Pages

workspace API Reference

Skip menu "workspace API Reference"
  • kdeplasma-addons
  •       GroupingDesktop
  •     liblancelot

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal