• 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
ScrollPane.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 "ScrollPane.h"
21 #include "ScrollBar.h"
22 #include "Widget.h"
23 
24 #include <Plasma/Animator>
25 #include <QGraphicsSceneWheelEvent>
26 
27 #include <lancelot/layouts/FullBorderLayout.h>
28 
29 #include "kineticscroll_p.h"
30 
31 namespace Lancelot
32 {
33 
34 // Scrollable interface common functions implementation
35 //>
36 class Scrollable::Private {
37 public:
38  ScrollPane * pane;
39 };
40 
41 Scrollable::Scrollable()
42  : d(new Private())
43 {
44  d->pane = NULL;
45 }
46 
47 Scrollable::~Scrollable()
48 {
49  delete d;
50 }
51 
52 void Scrollable::setScrollPane(ScrollPane * pane)
53 {
54  if (pane == d->pane) return;
55  d->pane = pane;
56  d->pane->setScrollableWidget(this);
57 }
58 
59 ScrollPane * Scrollable::scrollPane() const
60 {
61  return d->pane;
62 }
63 //<
64 
65 // ScrollPane implementation
66 
67 class ScrollPane::Private { //>
68 public:
69  Private(ScrollPane * parent)
70  : q(parent), widget(NULL), layout(NULL),
71  vertical(NULL), horizontal(NULL),
72  flags(ScrollPane::ClipScrollable)
73  {
74  q->setAcceptTouchEvents(true);
75  }
76 
77  void updateViewport()
78  {
79  widget->viewportChanged(QRectF(QPointF(horizontal->value(), vertical->value()),
80  q->currentViewportSize()));
81  }
82 
83  ScrollPane * q;
84  Scrollable * widget;
85  /*FlipLayout <*/ FullBorderLayout /*>*/ * layout;
86  ScrollBar * vertical;
87  ScrollBar * horizontal;
88  QGraphicsWidget * centerContainer;
89  Flags flags;
90 }; //<
91 
92 ScrollPane::ScrollPane(QGraphicsItem * parent) //>
93  : Widget(parent), d(new Private(this))
94 {
95  setAcceptsHoverEvents(true);
96  d->layout = new /*FlipLayout <*/ FullBorderLayout /*>*/ (this);
97  // d->layout->setParentLayoutItem(this);
98 
99  d->vertical = new ScrollBar(this);
100  d->vertical->setOrientation(Qt::Vertical);
101  d->vertical->setZValue(1);
102  d->horizontal = new ScrollBar(this);
103  d->horizontal->setOrientation(Qt::Horizontal);
104  d->horizontal->setZValue(1);
105 
106  d->centerContainer = new QGraphicsWidget(this);
107  d->centerContainer->setAcceptsHoverEvents(true);
108  d->centerContainer->setFlag(QGraphicsItem::ItemClipsChildrenToShape);
109 
110  connect (d->vertical, SIGNAL(valueChanged(int)),
111  this, SLOT(scrollVertical(int)));
112  connect (d->horizontal, SIGNAL(valueChanged(int)),
113  this, SLOT(scrollHorizontal(int)));
114 
115  d->layout->addItem(d->vertical, FullBorderLayout::Right);
116  d->layout->addItem(d->horizontal, FullBorderLayout::Bottom);
117  d->layout->addItem(d->centerContainer, FullBorderLayout::Center);
118 
119  d->layout->setContentsMargins(0, 0, 0, 0);
120 
121  setLayout(d->layout);
122 
123  new Plasma::KineticScrolling(this);
124 } //<
125 
126 ScrollPane::~ScrollPane() //>
127 {
128  // delete d->layout;
129  setLayout(NULL);
130 
131  delete d->horizontal;
132  delete d->vertical;
133  delete d->centerContainer;
134  delete d;
135 } //<
136 
137 void ScrollPane::setScrollableWidget(Scrollable * widget) //>
138 {
139  if (d->widget == widget) {
140  return;
141  }
142 
143  d->widget = widget;
144  widget->setScrollPane(this);
145 
146  QGraphicsWidget * qgw = dynamic_cast<QGraphicsWidget *>(widget);
147  if (qgw) {
148  qgw->setParentItem(d->centerContainer);
149  scrollableWidgetSizeUpdateNeeded();
150  }
151 } //<
152 
153 QSizeF ScrollPane::maximumViewportSize() const //>
154 {
155  return size();
156 } //<
157 
158 QSizeF ScrollPane::currentViewportSize() const //>
159 {
160  return d->centerContainer->size();
161 } //<
162 
163 void ScrollPane::scrollableWidgetSizeUpdateNeeded() //>
164 {
165  if (!d->widget || !layout()) {
166  return;
167  }
168 
169  d->layout->setAutoSize(FullBorderLayout::RightBorder);
170  d->layout->setAutoSize(FullBorderLayout::BottomBorder);
171 
172  bool hasHorizontal;
173  bool hasVertical;
174 
175  QSizeF testSize = maximumViewportSize();
176  QSizeF neededSize = d->widget->sizeFor(testSize);
177  hasHorizontal = neededSize.width() > testSize.width();
178  hasVertical = neededSize.height() > testSize.height();
179  if (hasVertical) {
180  hasHorizontal = d->widget->sizeFor(currentViewportSize()).width() > testSize.width();
181  }
182 
183  d->horizontal->setVisible(hasHorizontal);
184  d->vertical->setVisible(hasVertical);
185 
186  if (!hasHorizontal) {
187  d->horizontal->setValue(0);
188  d->horizontal->setRange(0, 0);
189  d->layout->setSize(0, FullBorderLayout::BottomBorder);
190  }
191 
192  if (!hasVertical) {
193  d->vertical->setValue(0);
194  d->horizontal->setRange(0, 0);
195  d->layout->setSize(0, FullBorderLayout::RightBorder);
196  }
197 
198  int viewportSize;
199 
200  if (hasHorizontal) {
201  viewportSize = currentViewportSize().width();
202  d->horizontal->setRange(0, d->widget->sizeFor(currentViewportSize()).width() - viewportSize);
203  d->horizontal->setPageStep(viewportSize);
204  d->horizontal->setSingleStep(d->widget->scrollUnit(Qt::Horizontal));
205  if ((d->flags & HoverShowScrollbars) && !isHovered()) {
206  d->horizontal->hide();
207  }
208  }
209 
210  if (hasVertical) {
211  viewportSize = currentViewportSize().height();
212  d->vertical->setRange(0, d->widget->sizeFor(currentViewportSize()).height() - viewportSize);
213  d->vertical->setPageStep(viewportSize);
214  d->vertical->setSingleStep(d->widget->scrollUnit(Qt::Vertical));
215  if ((d->flags & HoverShowScrollbars) && !isHovered()) {
216  d->vertical->hide();
217  }
218  }
219 
220  d->updateViewport();
221 } //<
222 
223 void ScrollPane::resizeEvent(QGraphicsSceneResizeEvent * event) //>
224 {
225  Lancelot::Widget::resizeEvent(event);
226  scrollableWidgetSizeUpdateNeeded();
227 } //<
228 
229 void ScrollPane::scrollHorizontal(int value) //>
230 {
231  d->horizontal->setValue(value);
232  d->updateViewport();
233 } //<
234 
235 void ScrollPane::scrollVertical(int value) //>
236 {
237  d->vertical->setValue(value);
238  d->updateViewport();
239 } //<
240 
241 void ScrollPane::setFlag(Flag flag) //>
242 {
243  d->flags |= flag;
244  setFlags(d->flags);
245 } //<
246 
247 void ScrollPane::clearFlag(Flag flag) //>
248 {
249  d->flags &= ~ flag;
250  setFlags(d->flags);
251 } //<
252 
253 ScrollPane::Flags ScrollPane::flags() const //>
254 {
255  return d->flags;
256 } //<
257 
258 void ScrollPane::setFlags(Flags flags) //>
259 {
260  d->flags = flags;
261  if (d->flags & ClipScrollable) {
262  d->centerContainer->setFlag(QGraphicsItem::ItemClipsChildrenToShape);
263  } else {
264  d->centerContainer->setFlags(
265  d->centerContainer->flags() & ~QGraphicsItem::ItemClipsChildrenToShape);
266  }
267 
268  if ((d->flags & HoverShowScrollbars) && !isHovered()) {
269  d->horizontal->hide();
270  d->vertical->hide();
271  }
272 } //<
273 
274 void ScrollPane::hoverEnterEvent(QGraphicsSceneHoverEvent * event) //>
275 {
276  Widget::hoverEnterEvent(event);
277 
278  if (!(d->flags & HoverShowScrollbars)) {
279  return;
280  }
281  if (d->layout->size(FullBorderLayout::RightBorder) != 0) {
282  d->vertical->setVisible(true);
283  }
284  if (d->layout->size(FullBorderLayout::BottomBorder) != 0) {
285  d->horizontal->setVisible(true);
286  }
287 } //<
288 
289 void ScrollPane::hoverLeaveEvent(QGraphicsSceneHoverEvent * event) //>
290 {
291  Widget::hoverLeaveEvent(event);
292 
293  if (!(d->flags & HoverShowScrollbars)) {
294  return;
295  }
296 
297  if (d->layout->size(FullBorderLayout::RightBorder) != 0) {
298  d->vertical->hide();
299  }
300  if (d->layout->size(FullBorderLayout::BottomBorder) != 0) {
301  d->horizontal->hide();
302  }
303 } //<
304 
305 void ScrollPane::setFlip(Plasma::Flip flip) //>
306 {
307  if (flip & Plasma::HorizontalFlip) {
308  // TODO: Replace this with a real removeItem(...)
309  d->layout->addItem(NULL, FullBorderLayout::Right);
310  d->layout->addItem(d->vertical, FullBorderLayout::Left);
311 
312  } else {
313  d->layout->addItem(NULL, FullBorderLayout::Left);
314  d->layout->addItem(d->vertical, FullBorderLayout::Right);
315 
316  }
317  // d->layout->setFlip(flip);
318 } //<
319 
320 void ScrollPane::scrollTo(QRectF rect) //>
321 {
322  QSizeF viewportSize = currentViewportSize();
323  QSizeF scrollableSize = d->widget->sizeFor(viewportSize);
324 
325  // Vertical scroll
326  // TODO: It would be prettier to do this differently
327  // (a variable indicating whether pane can scroll or smth)
328  // We have this in a few places
329  if (d->layout->size(FullBorderLayout::RightBorder) != 0) {
330  if (d->vertical->value() > rect.top()) {
331  scrollVertical(rect.top());
332  } else if (d->vertical->value() + viewportSize.height() < rect.bottom()) {
333  scrollVertical(rect.bottom() - viewportSize.height());
334  }
335  }
336 
337  // Horizontal scroll
338  if (d->layout->size(FullBorderLayout::BottomBorder) != 0) {
339  if (d->horizontal->value() > rect.left()) {
340  scrollHorizontal(rect.left());
341  } else if (d->horizontal->value() + viewportSize.width() < rect.right()) {
342  scrollHorizontal(rect.right() - viewportSize.width());
343  }
344  }
345 } //<
346 
347 QSizeF ScrollPane::contentsSize() const //>
348 {
349  return d->widget->sizeFor(currentViewportSize());
350 } //<
351 
352 void ScrollPane::setScrollPosition(const QPointF &position) //>
353 {
354  scrollTo(QRectF(position, currentViewportSize()));
355 } //<
356 
357 QPointF ScrollPane::scrollPosition() const //>
358 {
359  if (!d || !d->horizontal || !d->vertical) {
360  return QPointF();
361  }
362  return QPointF(d->horizontal->value(), d->vertical->value());
363 } //<
364 
365 QRectF ScrollPane::viewportGeometry() const //>
366 {
367  return QRectF(QPointF(), currentViewportSize());
368 } //<
369 
370 } // namespace Lancelot
371 
Lancelot::Widget::isHovered
bool isHovered() const
Returns whether the mouse cursor is hovering the widget.
Definition: Widget.cpp:121
Lancelot::Scrollable::~Scrollable
virtual ~Scrollable()
Destroys this Lancelot::Scrollable.
Definition: ScrollPane.cpp:47
Lancelot::Scrollable::scrollPane
virtual ScrollPane * scrollPane() const
Definition: ScrollPane.cpp:59
Lancelot::ScrollPane::setFlags
void setFlags(Flags flags)
Sets all flags.
Definition: ScrollPane.cpp:258
Lancelot::ScrollPane::setFlip
void setFlip(Plasma::Flip flip)
Flips the layout of the scrollbars.
Definition: ScrollPane.cpp:305
QGraphicsItem::setParentItem
void setParentItem(QGraphicsItem *newParent)
Lancelot::FullBorderLayout::RightBorder
Left border.
Definition: FullBorderLayout.h:47
QRectF::top
qreal top() const
QGraphicsItem
Lancelot::ScrollPane::scrollVertical
void scrollVertical(int value)
Scrolls the view vertically to the specified value.
Definition: ScrollPane.cpp:235
Lancelot::ScrollBar
A widget implementing scroll bars.
Definition: ScrollBar.h:36
Lancelot::FullBorderLayout
A modified version of Plasma::BorderLayout.
Definition: FullBorderLayout.h:38
QRectF::left
qreal left() const
kineticscroll_p.h
QPointF
QGraphicsWidget::size
QSizeF size() const
QRectF::bottom
qreal bottom() const
Lancelot::FullBorderLayout::Right
Definition: FullBorderLayout.h:58
Lancelot::ScrollPane::HoverShowScrollbars
Definition: ScrollPane.h:107
Lancelot::Widget
Base class for Widgets that want to use Lancelot framework.
Definition: Widget.h:37
Lancelot::ScrollPane::viewportGeometry
QRectF viewportGeometry() const
The geometry of the area that actually displays the web page.
Lancelot::Scrollable::setScrollPane
virtual void setScrollPane(ScrollPane *pane)
Sets the scroll pane that contains this Scrollable widget.
Definition: ScrollPane.cpp:52
Lancelot::ScrollPane::flags
Flags flags() const
Definition: ScrollPane.cpp:253
Lancelot::ScrollPane::scrollTo
void scrollTo(QRectF rect)
Ensures that the specified area is visible.
Definition: ScrollPane.cpp:320
Lancelot::ScrollPane::currentViewportSize
QSizeF currentViewportSize() const
Definition: ScrollPane.cpp:158
Lancelot::ScrollPane::clearFlag
void clearFlag(Flag flag)
Turns the specified flag off.
Definition: ScrollPane.cpp:247
FullBorderLayout.h
Lancelot::ScrollPane::scrollableWidgetSizeUpdateNeeded
void scrollableWidgetSizeUpdateNeeded()
Call this slot when the scrollable widget updates its side.
Definition: ScrollPane.cpp:163
QGraphicsWidget
QGraphicsSceneResizeEvent
QGraphicsSceneHoverEvent
Lancelot::FullBorderLayout::Left
Definition: FullBorderLayout.h:57
Lancelot::ScrollPane::scrollPosition
QPointF scrollPosition() const
Lancelot::ScrollPane
Pane for containing scrollable items.
Definition: ScrollPane.h:94
Lancelot::FullBorderLayout::Center
Definition: FullBorderLayout.h:54
QRectF::right
qreal right() const
Lancelot::Scrollable
Interface for items that support scrolling.
Definition: ScrollPane.h:34
Lancelot::ScrollPane::Flag
Flag
Definition: ScrollPane.h:105
Widget.h
Lancelot::ScrollPane::ClipScrollable
Definition: ScrollPane.h:106
Lancelot::FullBorderLayout::BottomBorder
Top border.
Definition: FullBorderLayout.h:45
Lancelot::ScrollPane::scrollHorizontal
void scrollHorizontal(int value)
Scrolls the view horizontally to the specified value.
Definition: ScrollPane.cpp:229
QGraphicsItem::setAcceptsHoverEvents
void setAcceptsHoverEvents(bool enabled)
QSizeF
Lancelot::Scrollable::Scrollable
Scrollable()
Creates a new Lancelot::Scrollable.
Definition: ScrollPane.cpp:41
QRectF
Lancelot::ScrollPane::~ScrollPane
virtual ~ScrollPane()
Destroys this ScrollPane.
Definition: ScrollPane.cpp:126
Lancelot::Widget::hoverEnterEvent
L_Override void hoverEnterEvent(QGraphicsSceneHoverEvent *event)
Definition: Widget.cpp:59
Lancelot::Widget::hoverLeaveEvent
L_Override void hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
Definition: Widget.cpp:71
Plasma::KineticScrolling
Definition: kineticscroll_p.h:36
Lancelot::ScrollPane::resizeEvent
L_Override void resizeEvent(QGraphicsSceneResizeEvent *event)
Definition: ScrollPane.cpp:223
Lancelot::FullBorderLayout::Bottom
Definition: FullBorderLayout.h:56
QGraphicsWidget::QGraphicsWidget
QGraphicsWidget(QGraphicsItem *parent, QFlags< Qt::WindowType > wFlags)
Lancelot::ScrollPane::hoverEnterEvent
L_Override void hoverEnterEvent(QGraphicsSceneHoverEvent *event)
Definition: ScrollPane.cpp:274
Lancelot::ScrollPane::contentsSize
QSizeF contentsSize() const
Lancelot::ScrollPane::ScrollPane
ScrollPane(QGraphicsItem *parent=0)
Creates a new Lancelot::ScrollPane.
Definition: ScrollPane.cpp:92
Lancelot::ScrollPane::hoverLeaveEvent
L_Override void hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
Definition: ScrollPane.cpp:289
QGraphicsWidget::layout
QGraphicsLayout * layout() const
Lancelot::ScrollPane::maximumViewportSize
QSizeF maximumViewportSize() const
Definition: ScrollPane.cpp:153
ScrollBar.h
Lancelot::ScrollPane::setScrollableWidget
void setScrollableWidget(Scrollable *widget)
Sets the widget that should be contained by this ScrollPane.
Definition: ScrollPane.cpp:137
QSizeF::height
qreal height() const
QObject::connect
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
ScrollPane.h
QObject::parent
QObject * parent() const
QGraphicsWidget::resizeEvent
virtual void resizeEvent(QGraphicsSceneResizeEvent *event)
QSizeF::width
qreal width() const
Lancelot::ScrollPane::setFlag
void setFlag(Flag flag)
Turns the specified flag on.
Definition: ScrollPane.cpp:241
Lancelot::ScrollPane::setScrollPosition
void setScrollPosition(const QPointF &position)
Sets the position of the webpage relative to this widget.
Definition: ScrollPane.cpp:352
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