27 #include <QGraphicsSceneWheelEvent>
28 #include <QGraphicsView>
30 #include <QToolButton>
31 #include <QGraphicsLinearLayout>
34 #include <KIconLoader>
36 #include <KPushButton>
38 #include <Plasma/Animation>
39 #include <Plasma/Animator>
40 #include <Plasma/Containment>
41 #include <Plasma/Corona>
42 #include <Plasma/ItemBackground>
43 #include <Plasma/Theme>
44 #include <Plasma/ToolButton>
55 m_arrowsSvg(new Plasma::Svg(this)),
56 m_location(Plasma::Floating),
58 m_scrollingDueToWheel(false)
64 m_arrowsSvg->setImagePath(
"widgets/arrows");
65 m_arrowsSvg->setContainsMultipleImages(
true);
66 m_arrowsSvg->resize(KIconLoader::SizeSmall, KIconLoader::SizeSmall);
68 m_slide = Plasma::Animator::create(Plasma::Animator::SlideAnimation);
69 m_slide->setEasingCurve(QEasingCurve::Linear);
70 connect(m_slide, SIGNAL(finished()),
this, SLOT(scrollStepFinished()));
73 m_upLeftArrow =
new Plasma::ToolButton(
this);
74 m_upLeftArrow->setPreferredSize(IconSize(KIconLoader::Panel), IconSize(KIconLoader::Panel));
75 m_upLeftArrow->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
76 m_downRightArrow =
new Plasma::ToolButton(
this);
77 m_downRightArrow->setPreferredSize(IconSize(KIconLoader::Panel), IconSize(KIconLoader::Panel));
78 m_downRightArrow->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Expanding);
80 connect(m_downRightArrow, SIGNAL(pressed()),
this, SLOT(scrollDownRight()));
81 connect(m_upLeftArrow, SIGNAL(pressed()),
this, SLOT(scrollUpLeft()));
84 m_scrollWidget->setFlag(QGraphicsItem::ItemClipsChildrenToShape,
true);
85 m_scrollWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
87 m_listWidget->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
88 m_listLayout =
new QGraphicsLinearLayout(m_listWidget);
90 m_slide->setTargetWidget(m_listWidget);
92 m_listWidget->installEventFilter(
this);
93 m_scrollWidget->installEventFilter(
this);
95 m_arrowsLayout =
new QGraphicsLinearLayout();
96 m_arrowsLayout->addItem(m_scrollWidget);
97 m_arrowsLayout->addItem(m_upLeftArrow);
98 m_arrowsLayout->addItem(m_downRightArrow);
99 m_arrowsLayout->setAlignment(m_downRightArrow, Qt::AlignVCenter | Qt::AlignHCenter);
100 m_arrowsLayout->setAlignment(m_upLeftArrow, Qt::AlignVCenter | Qt::AlignHCenter);
101 m_arrowsLayout->setAlignment(m_scrollWidget, Qt::AlignVCenter | Qt::AlignHCenter);
103 m_hoverIndicator =
new Plasma::ItemBackground(m_listWidget);
105 setLayout(m_arrowsLayout);
109 foreach (
const QString &group, groups) {
124 if (event->type() == QEvent::GraphicsSceneResize) {
127 if (widget == m_listWidget) {
129 if (m_orientation == Qt::Horizontal) {
130 m_scrollWidget->setMinimumSize(0, m_listWidget->minimumHeight());
132 m_scrollWidget->setMinimumSize(m_listWidget->minimumWidth(), 0);
136 }
else if (widget == m_scrollWidget) {
139 int maxVisibleIconsOnList = maximumAproxVisibleIconsOnList();
140 m_scrollStep = ceil((
float)maxVisibleIconsOnList/2);
141 if (m_orientation == Qt::Vertical) {
142 m_listWidget->setMinimumSize(m_scrollWidget->size().width(), 0);
147 return QObject::eventFilter(obj, event);
157 if (m_location == location) {
161 m_orientation = ((location == Plasma::LeftEdge || location == Plasma::RightEdge)?Qt::Vertical:Qt::Horizontal);
163 m_listLayout->invalidate();
164 m_listLayout->setOrientation(m_orientation);
165 m_arrowsLayout->setOrientation(m_orientation);
167 if(m_orientation == Qt::Horizontal) {
168 m_upLeftArrow->nativeWidget()->setIcon(KIcon(QIcon(m_arrowsSvg->pixmap(
"left-arrow"))));
169 m_downRightArrow->nativeWidget()->setIcon(KIcon(QIcon(m_arrowsSvg->pixmap(
"right-arrow"))));
170 m_upLeftArrow->setMaximumSize(IconSize(KIconLoader::Panel), -1);
171 m_downRightArrow->setMaximumSize(IconSize(KIconLoader::Panel), -1);
173 m_upLeftArrow->nativeWidget()->setIcon(KIcon(QIcon(m_arrowsSvg->pixmap(
"up-arrow"))));
174 m_downRightArrow->nativeWidget()->setIcon(KIcon(QIcon(m_arrowsSvg->pixmap(
"down-arrow"))));
175 m_upLeftArrow->setMaximumSize(-1, IconSize(KIconLoader::Panel));
176 m_downRightArrow->setMaximumSize(-1, IconSize(KIconLoader::Panel));
179 m_listLayout->activate();
182 void GroupIconList::iconHoverEnter(
GroupIcon *icon)
185 m_hoverIndicator->setTargetItem(icon);
186 if (!m_hoverIndicator->isVisible()) {
187 m_hoverIndicator->setGeometry(icon->geometry());
188 m_hoverIndicator->show();
191 m_hoverIndicator->hide();
196 int GroupIconList::maximumAproxVisibleIconsOnList()
200 qreal iconAverageSize;
201 qreal maxVisibleIconsOnList;
203 if (m_orientation == Qt::Horizontal) {
204 windowSize = m_scrollWidget->geometry().width();
205 listTotalSize = m_listLayout->preferredSize().width();
207 windowSize = m_scrollWidget->geometry().height();
208 listTotalSize = m_listLayout->preferredSize().height();
211 iconAverageSize = listTotalSize/
213 m_listLayout->spacing();
215 maxVisibleIconsOnList = floor(windowSize/iconAverageSize);
217 return maxVisibleIconsOnList;
220 void GroupIconList::addIcon(
GroupIcon *icon)
222 icon->setParent(m_listWidget);
224 m_hoverIndicator->getContentsMargins(&l, &t, &r, &b);
225 icon->setContentsMargins(l, t, r, b);
232 m_listLayout->addItem(icon);
233 m_listLayout->setAlignment(icon, Qt::AlignHCenter);
235 m_items.append(icon);
237 connect(icon, SIGNAL(hoverEnter(
GroupIcon*)),
this, SLOT(iconHoverEnter(
GroupIcon*)));
243 m_hoverIndicator->hide();
244 QTimer::singleShot(0,
this, SLOT(resetScroll()));
249 bool isDownRight =
event->delta() < 0;
250 m_scrollingDueToWheel =
true;
253 if (m_downRightArrow->isEnabled()) {
257 if (m_upLeftArrow->isEnabled()) {
263 void GroupIconList::scrollDownRight()
265 int nextFirstItemIndex = m_firstItemIndex + m_scrollStep;
266 if (nextFirstItemIndex > m_items.count() - 1) {
267 nextFirstItemIndex = m_items.count() - 1;
270 if (nextFirstItemIndex < 0) {
275 qreal startPosition = itemPosition(nextFirstItemIndex);
276 qreal endPosition = startPosition + (visibleEndPosition() - visibleStartPosition());
279 if (endPosition > listSize()) {
281 qreal searchPosition = startPosition - (endPosition - listSize());
282 for (
int i = 0; i < m_items.count(); i++) {
283 if (itemPosition(i) >= searchPosition) {
284 nextFirstItemIndex = i;
290 scrollTo(nextFirstItemIndex);
293 void GroupIconList::scrollUpLeft()
295 int nextFirstItemIndex = m_firstItemIndex - m_scrollStep;
296 if (nextFirstItemIndex < 0) {
297 nextFirstItemIndex = 0;
300 if (nextFirstItemIndex > m_items.count() - 1) {
305 scrollTo(nextFirstItemIndex);
308 void GroupIconList::scrollTo(
int index)
310 qreal startPosition = itemPosition(index);
311 qreal move = startPosition - visibleStartPosition();
313 m_firstItemIndex = index;
317 if (m_orientation == Qt::Horizontal) {
318 m_slide->setProperty(
"movementDirection", Plasma::Animation::MoveLeft);
320 m_slide->setProperty(
"movementDirection", Plasma::Animation::MoveUp);
323 m_slide->setProperty(
"distance", move);
329 void GroupIconList::scrollStepFinished()
333 if (m_scrollingDueToWheel && m_hoverIndicator->isVisible() && scene()) {
334 QGraphicsView *view = Plasma::viewFor(
this);
336 GroupIcon *icon =
dynamic_cast<GroupIcon *
>(scene()->itemAt(view->mapToScene(view->mapFromGlobal(QCursor::pos()))));
340 iconHoverEnter(icon);
343 m_scrollingDueToWheel =
false;
346 bool movingLeftUp = m_slide->property(
"distance").value<qreal>() < 0;
348 if (m_upLeftArrow->isEnabled() && m_upLeftArrow->isDown()) {
351 }
else if (m_downRightArrow->isEnabled() && m_downRightArrow->isDown()) {
356 void GroupIconList::resetScroll()
358 m_listWidget->setPos(0,0);
359 m_firstItemIndex = 0;
361 m_listWidget->resize(m_listLayout->geometry().size());
364 void GroupIconList::manageArrows()
366 qreal list_size = listSize();
367 qreal window_size = windowSize();
369 if (list_size <= window_size || m_items.isEmpty()) {
370 m_upLeftArrow->setEnabled(
false);
371 m_downRightArrow->setEnabled(
false);
372 m_upLeftArrow->setVisible(
false);
373 m_downRightArrow->setVisible(
false);
375 qreal endPosition = itemPosition(m_firstItemIndex) + window_size;
376 m_upLeftArrow->setVisible(
true);
377 m_downRightArrow->setVisible(
true);
378 m_upLeftArrow->setEnabled(m_firstItemIndex > 0);
379 m_downRightArrow->setEnabled(endPosition < list_size);
383 QRectF GroupIconList::visibleListRect()
385 QRectF visibleRect = m_scrollWidget->mapRectToItem(m_listWidget, m_scrollWidget->boundingRect());
390 qreal GroupIconList::visibleStartPosition()
392 if (m_orientation == Qt::Horizontal) {
393 return m_scrollWidget->mapToItem(m_listWidget, m_scrollWidget->boundingRect().left(), 0).x();
395 return m_scrollWidget->mapToItem(m_listWidget, 0, m_scrollWidget->boundingRect().top()).y();
399 qreal GroupIconList::visibleEndPosition()
401 if (m_orientation == Qt::Horizontal) {
402 return m_scrollWidget->mapToItem(m_listWidget, m_scrollWidget->boundingRect().right(), 0).x();
404 return m_scrollWidget->mapToItem(m_listWidget, 0, m_scrollWidget->boundingRect().bottom()).y();
408 qreal GroupIconList::listSize()
410 if (m_orientation == Qt::Horizontal) {
411 return m_listWidget->boundingRect().size().width();
413 return m_listWidget->boundingRect().size().height();
417 qreal GroupIconList::windowSize()
419 return (visibleEndPosition() - visibleStartPosition());
422 qreal GroupIconList::itemPosition(
int i)
429 if (m_orientation == Qt::Horizontal) {
430 return applet->pos().x();
432 return applet->pos().y();
438 if (m_iconSize == size || size < 16) {
456 #include "groupiconlist.moc"
GroupIconList(Plasma::Location location=Plasma::BottomEdge, QGraphicsItem *parent=0)
void setLocation(Plasma::Location location)
void setIconSize(int height)
bool eventFilter(QObject *obj, QEvent *event)
static const int DEFAULT_ICON_SIZE
static QStringList availableGroups()
Returns a list of all identifiers of the available Groups.
void wheelEvent(QGraphicsSceneWheelEvent *event)
void setIconSize(int size)
Plasma::Location location()
const int SCROLL_STEP_DURATION