diff options
Diffstat (limited to 'src/kitemviews/kitemlistview.h')
| -rw-r--r-- | src/kitemviews/kitemlistview.h | 360 |
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 |
