1 // Copyright 2001-2018 Crytek GmbH / Crytek Group. All rights reserved.
5 #include "QTrackingTooltip.h"
8 #include <QFontMetrics>
12 #include <unordered_map>
14 //Notes for future usage:
15 //CDrag object can be retrived from a drag event
16 // QDrag* const pDrag = pDragEvent->source()->findChild<QDrag*>();
18 namespace Private_DragDrop
24 enum class EDisplayMode
34 EDisplayMode m_displayMode
;
39 : m_displayMode(EDisplayMode::Clear
)
45 static CDragTooltip
& GetInstance()
47 static CDragTooltip theInstance
;
57 m_defaultScope
= SScope();
67 void SetText(QWidget
* pWidget
, const QString
& text
)
69 SScope
& scope
= GetScope(pWidget
);
70 scope
.m_displayMode
= EDisplayMode::Text
;
74 void SetPixmap(QWidget
* pWidget
, const QPixmap
& pixmap
)
76 SScope
& scope
= GetScope(pWidget
);
77 scope
.m_displayMode
= EDisplayMode::Pixmap
;
78 scope
.m_pixmap
= pixmap
;
81 void Clear(QWidget
* pWidget
)
83 SScope
& scope
= GetScope(pWidget
);
84 scope
.m_displayMode
= EDisplayMode::Clear
;
87 void SetDefaultPixmap(const QPixmap
& pixmap
)
89 m_defaultScope
.m_displayMode
= EDisplayMode::Pixmap
;
90 m_defaultScope
.m_pixmap
= pixmap
;
93 void SetCursorOffset(const QPoint
& point
)
95 m_trackingTooltip
->SetPosCursorOffset(point
);
103 QTrackingTooltip::HideTooltip(&m_trackingTooltip);
108 QWidget
* const pSubject
= qApp
->widgetAt(QCursor::pos());
109 const SScope
& scope
= pSubject
? GetScope(pSubject
) : m_defaultScope
;
111 if (scope
.m_displayMode
== EDisplayMode::Clear
)
113 QTrackingTooltip::HideTooltip(m_trackingTooltip
.data());
117 // Pixmap and text are mutually exclusive for a label.
118 if (scope
.m_displayMode
== EDisplayMode::Text
)
120 m_trackingTooltip
->SetText(scope
.m_text
);
122 else if (scope
.m_displayMode
== EDisplayMode::Pixmap
)
124 m_trackingTooltip
->SetPixmap(scope
.m_pixmap
);
127 QTrackingTooltip::ShowTrackingTooltip(m_trackingTooltip
);
133 : m_trackingTooltip(new QTrackingTooltip(), &QObject::deleteLater
)
136 QObject::connect(&m_timer
, &QTimer::timeout
, [this]() { Update(); });
139 SScope
& GetScope(QObject
* pSubject
)
141 if (m_scopes
.find(pSubject
) == m_scopes
.end())
143 m_scopes
[pSubject
].reset(new SScope(m_defaultScope
));
145 return *m_scopes
[pSubject
];
149 std::unordered_map
<const QObject
*, std::unique_ptr
<SScope
>> m_scopes
;
150 SScope m_defaultScope
;
151 QSharedPointer
<QTrackingTooltip
> m_trackingTooltip
;
156 } // namespace PrivateDragDrop
158 QString
CDragDropData::GetMimeFormatForType(const char* type
)
160 QString
typeStr(type
);
161 typeStr
= typeStr
.simplified();
162 typeStr
.replace(' ', '_');
164 return QString("application/crytek;type=\"%1\"").arg(type
);
167 const CDragDropData
* CDragDropData::FromDragDropEvent(const QDropEvent
* event
)
169 return FromMimeDataSafe(event
->mimeData());
172 const CDragDropData
* CDragDropData::FromMimeData(const QMimeData
* mimeData
)
174 return static_cast<const CDragDropData
*>(mimeData
);
177 const CDragDropData
* CDragDropData::FromMimeDataSafe(const QMimeData
* mimeData
)
179 const CDragDropData
* result
= qobject_cast
<const CDragDropData
*>(mimeData
);
180 CRY_ASSERT_MESSAGE(result
, "The QMimeData is not of type CDragDropData");
184 QByteArray
CDragDropData::GetCustomData(const char* type
) const
186 return QMimeData::data(GetMimeFormatForType(type
));
189 bool CDragDropData::HasFilePaths() const
191 // List of accepted MIME formats (in this order).
193 //These formats are not currently supported but are part of the mime types you get when drag&dropping from Windows explorer
195 || hasFormat(QStringLiteral("application/x-qt-windows-mime;value=\"FileName\""))
196 || hasFormat(QStringLiteral("application/x-qt-windows-mime;value=\"FileNameW\""));
200 QStringList
CDragDropData::GetFilePaths() const
202 //TODO : test drag&drop of several files from browser
203 QStringList filePaths
;
205 // List of accepted MIME formats (in this order).
208 QList
<QUrl
> urls
= QMimeData::urls();
209 QList
<QUrl
>::const_iterator it
= urls
.constBegin();
211 for (; it
!= urls
.constEnd(); ++it
)
212 filePaths
.append((*it
).toLocalFile());
218 void CDragDropData::SetCustomData(const char* type
, const QByteArray
& data
)
220 QMimeData::setData(GetMimeFormatForType(type
), data
);
223 bool CDragDropData::HasCustomData(const char* type
) const
225 return QMimeData::hasFormat(GetMimeFormatForType(type
));
228 void CDragDropData::ShowDragText(QWidget
* pWidget
, const QString
& what
)
230 using namespace Private_DragDrop
;
231 CDragTooltip::GetInstance().SetText(pWidget
, what
);
234 void CDragDropData::ShowDragPixmap(QWidget
* pWidget
, const QPixmap
& what
, const QPoint
& pixmapCursorOffset
/*= QPoint()*/)
236 using namespace Private_DragDrop
;
237 CDragTooltip::GetInstance().SetPixmap(pWidget
, what
);
239 if(!pixmapCursorOffset
.isNull())
240 CDragTooltip::GetInstance().SetCursorOffset(pixmapCursorOffset
);
243 void CDragDropData::ClearDragTooltip(QWidget
* pWidget
)
245 using namespace Private_DragDrop
;
246 CDragTooltip::GetInstance().Clear(pWidget
);
249 void CDragDropData::StartDrag(QObject
* pDragSource
, Qt::DropActions supportedActions
, QMimeData
* pMimeData
, const QPixmap
* pPixmap
, const QPoint
& pixmapCursorOffset
/*= QPoint()*/)
251 using namespace Private_DragDrop
;
252 QDrag
* const pDrag
= new QDrag(pDragSource
);
253 pDrag
->setMimeData(pMimeData
);
254 CDragTooltip
& tooltip
= CDragTooltip::GetInstance();
256 CDragDropData
* const pDragDropData
= (CDragDropData
*)pMimeData
;
257 if (pDragDropData
&& pPixmap
)
259 tooltip
.SetDefaultPixmap(*pPixmap
);
260 if (!pixmapCursorOffset
.isNull())
261 tooltip
.SetCursorOffset(pixmapCursorOffset
);
263 pDrag
->exec(supportedActions
);