!XT (BREAK-16) (Sandbox) Remove double-newlines at the end of files.
[CRYENGINE.git] / Code / Sandbox / Plugins / EditorCommon / DragDrop.cpp
bloba11e66d415c1eed2d8b4da332c69b6bcf4f1ed38
1 // Copyright 2001-2018 Crytek GmbH / Crytek Group. All rights reserved.
2 #include "StdAfx.h"
3 #include "DragDrop.h"
5 #include "QTrackingTooltip.h"
7 #include <QDrag>
8 #include <QFontMetrics>
9 #include <QTimer>
10 #include <QUrl>
11 #include <qevent.h>
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
21 class CDragTooltip
23 public:
24 enum class EDisplayMode
26 Clear = 0,
27 Text,
28 Pixmap
31 private:
32 struct SScope
34 EDisplayMode m_displayMode;
35 QString m_text;
36 QPixmap m_pixmap;
38 SScope()
39 : m_displayMode(EDisplayMode::Clear)
44 public:
45 static CDragTooltip& GetInstance()
47 static CDragTooltip theInstance;
48 return theInstance;
51 void StartDrag()
53 m_scopes.clear();
54 m_bDragging = true;
55 m_timer.start(0);
57 m_defaultScope = SScope();
60 void StopDrag()
62 m_bDragging = false;
63 m_timer.stop();
64 Update();
67 void SetText(QWidget* pWidget, const QString& text)
69 SScope& scope = GetScope(pWidget);
70 scope.m_displayMode = EDisplayMode::Text;
71 scope.m_text = 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);
98 void Update()
100 if (!m_bDragging)
103 QTrackingTooltip::HideTooltip(&m_trackingTooltip);
104 return;
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());
115 else
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);
131 private:
132 CDragTooltip()
133 : m_trackingTooltip(new QTrackingTooltip(), &QObject::deleteLater)
134 , m_bDragging(false)
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];
148 private:
149 std::unordered_map<const QObject*, std::unique_ptr<SScope>> m_scopes;
150 SScope m_defaultScope;
151 QSharedPointer<QTrackingTooltip> m_trackingTooltip;
152 QTimer m_timer;
153 bool m_bDragging;
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");
181 return result;
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).
192 return hasUrls();
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).
206 if (hasUrls())
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());
215 return filePaths;
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();
255 tooltip.StartDrag();
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);
264 tooltip.StopDrag();