summaryrefslogtreecommitdiffstats
path: root/application/groupview/GroupView.h
blob: a3863b6dd4229f408cda40d596451c4bbf1e0e43 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#pragma once

#include <QListView>
#include <QLineEdit>
#include <QScrollBar>
#include <QCache>
#include "VisualGroup.h"

struct GroupViewRoles
{
	enum
	{
		GroupRole = Qt::UserRole,
		ProgressValueRole,
		ProgressMaximumRole
	};
};

class GroupView : public QAbstractItemView
{
	Q_OBJECT

public:
	GroupView(QWidget *parent = 0);
	~GroupView();

	void setModel(QAbstractItemModel *model) override;

	/// return geometry rectangle occupied by the specified model item
	QRect geometryRect(const QModelIndex &index) const;
	/// return visual rectangle occupied by the specified model item
	virtual QRect visualRect(const QModelIndex &index) const override;
	/// get the model index at the specified visual point
	virtual QModelIndex indexAt(const QPoint &point) const override;
	QString groupNameAt(const QPoint &point);
	void setSelection(const QRect &rect,
					  const QItemSelectionModel::SelectionFlags commands) override;

	virtual int horizontalOffset() const override;
	virtual int verticalOffset() const override;
	virtual void scrollContentsBy(int dx, int dy) override;
	virtual void scrollTo(const QModelIndex &index, ScrollHint hint = EnsureVisible) override;

	virtual QModelIndex moveCursor(CursorAction cursorAction,
								   Qt::KeyboardModifiers modifiers) override;

	virtual QRegion visualRegionForSelection(const QItemSelection &selection) const override;

	int spacing() const
	{
		return m_spacing;
	};

public slots:
	virtual void updateGeometries() override;

protected slots:
	virtual void dataChanged(const QModelIndex &topLeft, const QModelIndex &bottomRight,
							 const QVector<int> &roles) override;
	virtual void rowsInserted(const QModelIndex &parent, int start, int end) override;
	virtual void rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end) override;
	void modelReset();

protected:
	virtual bool isIndexHidden(const QModelIndex &index) const override;
	void mousePressEvent(QMouseEvent *event) override;
	void mouseMoveEvent(QMouseEvent *event) override;
	void mouseReleaseEvent(QMouseEvent *event) override;
	void mouseDoubleClickEvent(QMouseEvent *event) override;
	void paintEvent(QPaintEvent *event) override;
	void resizeEvent(QResizeEvent *event) override;

	void dragEnterEvent(QDragEnterEvent *event) override;
	void dragMoveEvent(QDragMoveEvent *event) override;
	void dragLeaveEvent(QDragLeaveEvent *event) override;
	void dropEvent(QDropEvent *event) override;

	void startDrag(Qt::DropActions supportedActions) override;

private:
	friend struct VisualGroup;
	QList<VisualGroup *> m_groups;

	// geometry
	int m_leftMargin = 5;
	int m_rightMargin = 5;
	int m_bottomMargin = 5;
	int m_categoryMargin = 5;
	int m_spacing = 5;
	int m_itemWidth = 100;
	int m_currentItemsPerRow = -1;
	int m_currentCursorColumn= -1;
	mutable QCache<int, QRect> geometryCache;

	// point where the currently active mouse action started in geometry coordinates
	QPoint m_pressedPosition;
	QPersistentModelIndex m_pressedIndex;
	bool m_pressedAlreadySelected;
	VisualGroup *m_pressedCategory;
	QItemSelectionModel::SelectionFlag m_ctrlDragSelectionFlag;
	QPoint m_lastDragPosition;

	VisualGroup *category(const QModelIndex &index) const;
	VisualGroup *category(const QString &cat) const;
	VisualGroup *categoryAt(const QPoint &pos, VisualGroup::HitResults & result) const;

	int itemsPerRow() const
	{
		return m_currentItemsPerRow;
	};
	int contentWidth() const;

private: /* methods */
	int itemWidth() const;
	int calculateItemsPerRow() const;
	int verticalScrollToValue(const QModelIndex &index, const QRect &rect,
							  QListView::ScrollHint hint) const;
	QPixmap renderToPixmap(const QModelIndexList &indices, QRect *r) const;
	QList<QPair<QRect, QModelIndex>> draggablePaintPairs(const QModelIndexList &indices,
														 QRect *r) const;

	bool isDragEventAccepted(QDropEvent *event);

	QPair<VisualGroup *, int> rowDropPos(const QPoint &pos);

	QPoint offset() const;
};