Plasma Engine  2.0
Loading...
Searching...
No Matches
ItemView.moc.h
1#pragma once
2
3#include <Foundation/Logging/Log.h>
4#include <GuiFoundation/GuiFoundationDLL.h>
5#include <QAbstractItemView>
6#include <QHoverEvent>
7#include <QItemDelegate>
8#include <QStyledItemDelegate>
9
11class PL_GUIFOUNDATION_DLL plQtItemDelegate : public QItemDelegate
12{
13 Q_OBJECT
14public:
15 explicit plQtItemDelegate(QObject* pParent = nullptr)
16 : QItemDelegate(pParent)
17 {
18 }
19
20 virtual bool mouseHoverEvent(QHoverEvent* pEvent, const QStyleOptionViewItem& option, const QModelIndex& index) { return false; }
21 virtual bool mousePressEvent(QMouseEvent* pEvent, const QStyleOptionViewItem& option, const QModelIndex& index) { return false; }
22 virtual bool mouseReleaseEvent(QMouseEvent* pEvent, const QStyleOptionViewItem& option, const QModelIndex& index) { return false; }
23 virtual bool mouseDoubleClickEvent(QMouseEvent* pEvent, const QStyleOptionViewItem& option, const QModelIndex& index) { return false; }
24 virtual bool mouseMoveEvent(QMouseEvent* pEvent, const QStyleOptionViewItem& option, const QModelIndex& index) { return false; }
25};
26
28template <typename Base>
29class plQtItemView : public Base
30{
31public:
32 plQtItemView(QWidget* pParent)
33 : Base(pParent)
34
35 {
36 this->setAttribute(Qt::WA_Hover, true);
37 }
38
39 virtual bool event(QEvent* pEv) override
40 {
41 switch (pEv->type())
42 {
43 case QEvent::HoverEnter:
44 case QEvent::HoverMove:
45 case QEvent::HoverLeave:
46 {
47 QHoverEvent* pHoeverEvent = static_cast<QHoverEvent*>(pEv);
48
49
50#if QT_VERSION <= QT_VERSION_CHECK(5, 14, 0)
51 QPoint pos = pHoeverEvent->pos();
52#else
53 QPoint pos = pHoeverEvent->position().toPoint();
54#endif
55 QModelIndex index = this->indexAt(pos);
56 if (m_Hovered.isValid() && (pEv->type() == QEvent::HoverLeave || index != m_Hovered))
57 {
58 QHoverEvent hoverEvent(QEvent::HoverLeave, pos, pHoeverEvent->globalPosition(), pHoeverEvent->oldPos(), pHoeverEvent->modifiers());
59 ForwardEvent(m_Hovered, &hoverEvent);
60 m_Hovered = QModelIndex();
61 }
62 if (index.isValid() && pEv->type() != QEvent::HoverLeave && !m_Hovered.isValid())
63 {
64 QHoverEvent hoverEvent(QEvent::HoverEnter, pos, pHoeverEvent->globalPosition(), pHoeverEvent->oldPos(), pHoeverEvent->modifiers());
65 m_Hovered = index;
66 ForwardEvent(m_Hovered, &hoverEvent);
67 }
68 else if (m_Hovered.isValid())
69 {
70 QHoverEvent hoverEvent(QEvent::HoverMove, pos, pHoeverEvent->globalPosition(), pHoeverEvent->oldPos(), pHoeverEvent->modifiers());
71 ForwardEvent(m_Hovered, &hoverEvent);
72 }
73 break;
74 }
75 default:
76 break;
77 }
78
79 return Base::event(pEv);
80 }
81
82 virtual void mousePressEvent(QMouseEvent* pEvent) override
83 {
84 QPoint pos = pEvent->pos();
85 QModelIndex index = this->indexAt(pos);
86 if (ForwardEvent(index, pEvent))
87 {
88 if (!m_Focused.isValid())
89 {
90 m_Focused = index;
91 this->viewport()->grabMouse();
92 }
93 }
94 else
95 {
96 Base::mousePressEvent(pEvent);
97 }
98 }
99
100 virtual void mouseReleaseEvent(QMouseEvent* pEvent) override
101 {
102 if (m_Focused.isValid())
103 {
104 ForwardEvent(m_Focused, pEvent);
105 if (pEvent->buttons() == Qt::NoButton)
106 {
107 m_Focused = QModelIndex();
108 this->viewport()->releaseMouse();
109 }
110 }
111 else
112 {
113 Base::mouseReleaseEvent(pEvent);
114 }
115 }
116
117 virtual void mouseDoubleClickEvent(QMouseEvent* pEvent) override
118 {
119 QPoint pos = pEvent->pos();
120 QModelIndex index = this->indexAt(pos);
121 if (!ForwardEvent(index, pEvent))
122 {
123 Base::mouseDoubleClickEvent(pEvent);
124 }
125 }
126
127 virtual void mouseMoveEvent(QMouseEvent* pEvent) override
128 {
129 QPoint pos = pEvent->pos();
130 QModelIndex index = this->indexAt(pos);
131 if (!ForwardEvent(index, pEvent))
132 {
133 Base::mouseMoveEvent(pEvent);
134 }
135 }
136
137private:
138 bool ForwardEvent(QModelIndex index, QEvent* pEvent)
139 {
140 if (m_Focused.isValid())
141 index = m_Focused;
142 if (!index.isValid())
143 return false;
144
145 if (plQtItemDelegate* pDelegate = qobject_cast<plQtItemDelegate*>(this->itemDelegateForIndex(m_Hovered)))
146 {
147 QStyleOptionViewItem option;
148 this->initViewItemOption(&option);
149 option.rect = this->visualRect(index);
150 option.state |= (index == this->currentIndex() ? QStyle::State_HasFocus : QStyle::State_None);
151
152 bool bRes = false;
153 switch (pEvent->type())
154 {
155 case QEvent::HoverEnter:
156 case QEvent::HoverMove:
157 case QEvent::HoverLeave:
158 bRes = pDelegate->mouseHoverEvent(static_cast<QHoverEvent*>(pEvent), option, index);
159 break;
160 case QEvent::MouseButtonPress:
161 bRes = pDelegate->mousePressEvent(static_cast<QMouseEvent*>(pEvent), option, index);
162 break;
163 case QEvent::MouseButtonRelease:
164 bRes = pDelegate->mouseReleaseEvent(static_cast<QMouseEvent*>(pEvent), option, index);
165 break;
166 case QEvent::MouseButtonDblClick:
167 bRes = pDelegate->mouseDoubleClickEvent(static_cast<QMouseEvent*>(pEvent), option, index);
168 break;
169 case QEvent::MouseMove:
170 bRes = pDelegate->mouseMoveEvent(static_cast<QMouseEvent*>(pEvent), option, index);
171 break;
172 default:
173 break;
174 }
175 this->update(index);
176 return bRes;
177 }
178
179 return false;
180 }
181
182private:
183 plQtItemDelegate* m_pFocusedDelegate = nullptr;
184 QPersistentModelIndex m_Hovered;
185 QPersistentModelIndex m_Focused;
186};
In combination with plQtItemView this delegate allows for receiving the full range of mouse input.
Definition ItemView.moc.h:12
Template to be used with classes derived from QAbstractItemView. Allows the use of plQtItemDelegate.
Definition ItemView.moc.h:30