┌   ┐
54
└   ┘

summaryrefslogtreecommitdiff
path: root/src/kitemviews/kitemlistview.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/kitemviews/kitemlistview.h')
-rw-r--r--src/kitemviews/kitemlistview.h360
1 files changed, 360 insertions, 0 deletions
diff --git a/src/kitemviews/kitemlistview.h b/src/kitemviews/kitemlistview.h
new file mode 100644
index 000000000..829736a09
--- /dev/null
+++ b/src/kitemviews/kitemlistview.h
@@ -0,0 +1,360 @@
+/***************************************************************************
+ * Copyright (C) 2011 by Peter Penz <[email protected]> *
+ * *
+ * Based on the Itemviews NG project from Trolltech Labs: *
+ * http://qt.gitorious.org/qt-labs/itemviews-ng *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *
+ ***************************************************************************/
+
+#ifndef KITEMLISTVIEW_H
+#define KITEMLISTVIEW_H
+
+#include <libdolphin_export.h>
+
+#include <kitemviews/kitemliststyleoption.h>
+#include <kitemviews/kitemlistviewanimation_p.h>
+#include <kitemviews/kitemlistwidget.h>
+#include <kitemviews/kitemmodelbase.h>
+#include <QGraphicsWidget>
+
+class KItemListController;
+class KItemListWidgetCreatorBase;
+class KItemListGroupHeader;
+class KItemListGroupHeaderCreatorBase;
+class KItemListSizeHintResolver;
+class KItemListViewAnimation;
+class KItemListViewLayouter;
+class KItemListWidget;
+class KItemListViewCreatorBase;
+class QTimer;
+
+/**
+ * @brief Represents the view of an item-list.
+ *
+ * The view is responsible for showing the items of the model within
+ * a GraphicsItem. Each visible item is represented by a KItemListWidget.
+ *
+ * The created view must be applied to the KItemListController with
+ * KItemListController::setView(). For showing a custom model it is not
+ * mandatory to derive from KItemListView, all that is necessary is
+ * to set a widget-creator that is capable to create KItemListWidgets
+ * showing the model items. A widget-creator can be set with
+ * KItemListView::setWidgetCreator().
+ *
+ * @see KItemListWidget
+ * @see KItemModelBase
+ */
+class LIBDOLPHINPRIVATE_EXPORT KItemListView : public QGraphicsWidget
+{
+ Q_OBJECT
+
+public:
+ KItemListView(QGraphicsWidget* parent = 0);
+ virtual ~KItemListView();
+
+ void setScrollOrientation(Qt::Orientation orientation);
+ Qt::Orientation scrollOrientation() const;
+
+ void setItemSize(const QSizeF& size);
+ QSizeF itemSize() const;
+
+ // TODO: add note that offset is not checked against maximumOffset, only against 0.
+ void setOffset(qreal offset);
+ qreal offset() const;
+
+ qreal maximumOffset() const;
+
+ /**
+ * Sets the visible roles to \p roles. The integer-value defines
+ * the order of the visible role: Smaller values are ordered first.
+ */
+ void setVisibleRoles(const QHash<QByteArray, int>& roles);
+ QHash<QByteArray, int> visibleRoles() const;
+
+ /**
+ * @return Controller of the item-list. The controller gets
+ * initialized by KItemListController::setView() and will
+ * result in calling KItemListController::onControllerChanged().
+ */
+ KItemListController* controller() const;
+
+ /**
+ * @return Model of the item-list. The model gets
+ * initialized by KItemListController::setView() and will
+ * result in calling KItemListController::onModelChanged().
+ */
+ KItemModelBase* model() const;
+
+ /**
+ * Sets the creator that creates a widget showing the
+ * content of one model-item. Usually it is sufficient
+ * to implement a custom widget X derived from KItemListWidget and
+ * set the creator by:
+ * <code>
+ * itemListView->setWidgetCreator(new KItemListWidgetCreator<X>());
+ * </code>
+ * Note that the ownership of the widget creator is not transferred to
+ * the item-list view: One instance of a widget creator might get shared
+ * by several item-list view instances.
+ **/
+ void setWidgetCreator(KItemListWidgetCreatorBase* widgetCreator);
+ KItemListWidgetCreatorBase* widgetCreator() const;
+
+ void setGroupHeaderCreator(KItemListGroupHeaderCreatorBase* groupHeaderCreator);
+ KItemListGroupHeaderCreatorBase* groupHeaderCreator() const;
+
+ void setStyleOption(const KItemListStyleOption& option);
+ const KItemListStyleOption& styleOption() const;
+
+ virtual void setGeometry(const QRectF& rect);
+
+ int itemAt(const QPointF& pos) const;
+ bool isAboveSelectionToggle(int index, const QPointF& pos) const;
+ bool isAboveExpansionToggle(int index, const QPointF& pos) const;
+
+ int firstVisibleIndex() const;
+ int lastVisibleIndex() const;
+
+ virtual QSizeF itemSizeHint(int index) const;
+ virtual QHash<QByteArray, QSizeF> visibleRoleSizes() const;
+
+ void beginTransaction();
+ void endTransaction();
+ bool isTransactionActive() const;
+
+signals:
+ void offsetChanged(int current, int previous);
+ void maximumOffsetChanged(int current, int previous);
+
+protected:
+ virtual void initializeItemListWidget(KItemListWidget* item);
+
+ virtual void onControllerChanged(KItemListController* current, KItemListController* previous);
+ virtual void onModelChanged(KItemModelBase* current, KItemModelBase* previous);
+
+ virtual void onScrollOrientationChanged(Qt::Orientation current, Qt::Orientation previous);
+ virtual void onItemSizeChanged(const QSizeF& current, const QSizeF& previous);
+ virtual void onOffsetChanged(qreal current, qreal previous);
+ virtual void onVisibleRolesChanged(const QHash<QByteArray, int>& current, const QHash<QByteArray, int>& previous);
+ virtual void onStyleOptionChanged(const KItemListStyleOption& current, const KItemListStyleOption& previous);
+
+ virtual void onTransactionBegin();
+ virtual void onTransactionEnd();
+
+ virtual bool event(QEvent* event);
+ virtual void mousePressEvent(QGraphicsSceneMouseEvent* event);
+ virtual void hoverMoveEvent(QGraphicsSceneHoverEvent* event);
+ virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent* event);
+
+ QList<KItemListWidget*> visibleItemListWidgets() const;
+
+protected slots:
+ virtual void slotItemsInserted(const KItemRangeList& itemRanges);
+ virtual void slotItemsRemoved(const KItemRangeList& itemRanges);
+ virtual void slotItemsChanged(const KItemRangeList& itemRanges,
+ const QSet<QByteArray>& roles);
+
+private slots:
+ void slotAnimationFinished(QGraphicsWidget* widget,
+ KItemListViewAnimation::AnimationType type);
+ void slotLayoutTimerFinished();
+
+private:
+ enum LayoutAnimationHint
+ {
+ NoAnimation,
+ Animation
+ };
+
+ enum SizeType
+ {
+ LayouterSize,
+ ItemSize
+ };
+
+ void setController(KItemListController* controller);
+ void setModel(KItemModelBase* model);
+
+ void updateLayout();
+ void doLayout(LayoutAnimationHint hint, int changedIndex, int changedCount);
+ void doGroupHeadersLayout(LayoutAnimationHint hint, int changedIndex, int changedCount);
+ void emitOffsetChanges();
+
+ KItemListWidget* createWidget(int index);
+ void recycleWidget(KItemListWidget* widget);
+ void setWidgetIndex(KItemListWidget* widget, int index);
+
+ /**
+ * Helper method for setGeometry() and setItemSize(): Calling both methods might result
+ * in a changed number of visible items. To assure that currently invisible items can
+ * get animated from the old position to the new position prepareLayoutForIncreasedItemCount()
+ * takes care to create all item widgets that are visible with the old or the new size.
+ * @param size Size of the layouter or the item dependent on \p sizeType.
+ * @param sizeType LayouterSize: KItemListLayouter::setSize() is used.
+ * ItemSize: KItemListLayouter::setItemSize() is used.
+ */
+ void prepareLayoutForIncreasedItemCount(const QSizeF& size, SizeType sizeType);
+
+ /**
+ * Helper method for prepareLayoutForIncreasedItemCount().
+ */
+ void setLayouterSize(const QSizeF& size, SizeType sizeType);
+
+ /**
+ * Marks the visible roles as dirty so that they will get updated when doing the next
+ * layout. The visible roles will only get marked as dirty if an empty item-size is
+ * given.
+ * @return True if the visible roles have been marked as dirty.
+ */
+ bool markVisibleRolesSizesAsDirty();
+
+ /**
+ * Updates the m_visibleRoleSizes property and applies the dynamic
+ * size to the layouter.
+ */
+ void applyDynamicItemSize();
+
+private:
+ bool m_grouped;
+ int m_activeTransactions; // Counter for beginTransaction()/endTransaction()
+
+ QSizeF m_itemSize;
+ KItemListController* m_controller;
+ KItemModelBase* m_model;
+ QHash<QByteArray, int> m_visibleRoles;
+ QHash<QByteArray, QSizeF> m_visibleRolesSizes;
+ KItemListWidgetCreatorBase* m_widgetCreator;
+ KItemListGroupHeaderCreatorBase* m_groupHeaderCreator;
+ KItemListStyleOption m_styleOption;
+
+ QHash<int, KItemListWidget*> m_visibleItems;
+ QHash<KItemListWidget*, KItemListGroupHeader*> m_visibleGroups;
+
+ int m_scrollBarExtent;
+ KItemListSizeHintResolver* m_sizeHintResolver;
+ KItemListViewLayouter* m_layouter;
+ KItemListViewAnimation* m_animation;
+
+ QTimer* m_layoutTimer; // Triggers an asynchronous doLayout() call.
+ int m_oldOffset;
+ int m_oldMaximumOffset;
+
+ friend class KItemListController;
+};
+
+/**
+ * Allows to do a fast logical creation and deletion of QGraphicsWidgets
+ * by recycling existing QGraphicsWidgets instances. Is used by
+ * KItemListWidgetCreatorBase and KItemListGroupHeaderCreatorBase.
+ * @internal
+ */
+class LIBDOLPHINPRIVATE_EXPORT KItemListCreatorBase
+{
+public:
+ virtual ~KItemListCreatorBase();
+
+protected:
+ void addCreatedWidget(QGraphicsWidget* widget);
+ void pushRecycleableWidget(QGraphicsWidget* widget);
+ QGraphicsWidget* popRecycleableWidget();
+
+private:
+ QSet<QGraphicsWidget*> m_createdWidgets;
+ QList<QGraphicsWidget*> m_recycleableWidgets;
+};
+
+/**
+ * @brief Base class for creating KItemListWidgets.
+ *
+ * It is recommended that applications simply use the KItemListWidgetCreator-template class.
+ * For a custom implementation the methods create() and recyle() must be reimplemented.
+ * The intention of the widget creator is to prevent repetitive and expensive instantiations and
+ * deletions of KItemListWidgets by recycling existing widget instances.
+ */
+class LIBDOLPHINPRIVATE_EXPORT KItemListWidgetCreatorBase : public KItemListCreatorBase
+{
+public:
+ virtual ~KItemListWidgetCreatorBase();
+ virtual KItemListWidget* create(KItemListView* view) = 0;
+ virtual void recycle(KItemListWidget* widget);
+};
+
+template <class T>
+class LIBDOLPHINPRIVATE_EXPORT KItemListWidgetCreator : public KItemListWidgetCreatorBase
+{
+public:
+ virtual ~KItemListWidgetCreator();
+ virtual KItemListWidget* create(KItemListView* view);
+};
+
+template <class T>
+KItemListWidgetCreator<T>::~KItemListWidgetCreator()
+{
+}
+
+template <class T>
+KItemListWidget* KItemListWidgetCreator<T>::create(KItemListView* view)
+{
+ KItemListWidget* widget = static_cast<KItemListWidget*>(popRecycleableWidget());
+ if (!widget) {
+ widget = new T(view);
+ addCreatedWidget(widget);
+ }
+ return widget;
+}
+
+/**
+ * @brief Base class for creating KItemListGroupHeaders.
+ *
+ * It is recommended that applications simply use the KItemListGroupHeaderCreator-template class.
+ * For a custom implementation the methods create() and recyle() must be reimplemented.
+ * The intention of the group-header creator is to prevent repetitive and expensive instantiations and
+ * deletions of KItemListGroupHeaders by recycling existing header instances.
+ */
+class LIBDOLPHINPRIVATE_EXPORT KItemListGroupHeaderCreatorBase : public KItemListCreatorBase
+{
+public:
+ virtual ~KItemListGroupHeaderCreatorBase();
+ virtual KItemListGroupHeader* create(QGraphicsWidget* parent) = 0;
+ virtual void recycle(KItemListGroupHeader* header);
+};
+
+template <class T>
+class LIBDOLPHINPRIVATE_EXPORT KItemListGroupHeaderCreator : public KItemListGroupHeaderCreatorBase
+{
+public:
+ virtual ~KItemListGroupHeaderCreator();
+ virtual KItemListGroupHeader* create(QGraphicsWidget* parent);
+};
+
+template <class T>
+KItemListGroupHeaderCreator<T>::~KItemListGroupHeaderCreator()
+{
+}
+
+template <class T>
+KItemListGroupHeader* KItemListGroupHeaderCreator<T>::create(QGraphicsWidget* parent)
+{
+ KItemListGroupHeader* widget = static_cast<KItemListGroupHeader*>(popRecycleableWidget());
+ if (!widget) {
+ widget = new T(parent);
+ addCreatedWidget(widget);
+ }
+ return widget;
+}
+
+#endif