Drag&drop, working towards making it accept drop events
Still work in progress
This commit is contained in:
parent
f933d66e55
commit
b427f9e094
4 changed files with 95 additions and 15 deletions
|
@ -126,10 +126,26 @@ void BlockGrid::paintEvent (QPaintEvent* event) {
|
|||
}
|
||||
}
|
||||
|
||||
void BlockGrid::dragEnterEvent(QDragEnterEvent* event) {
|
||||
m_block_dnd.drag_enter_event(event);
|
||||
}
|
||||
|
||||
void BlockGrid::dropEvent(QDropEvent* event) {
|
||||
m_block_dnd.drop_event(event);
|
||||
}
|
||||
|
||||
void BlockGrid::mousePressEvent(QMouseEvent* event) {
|
||||
m_block_dnd.mouse_press_event(event);
|
||||
}
|
||||
|
||||
void BlockGrid::mouseReleaseEvent(QMouseEvent* event) {
|
||||
m_block_dnd.mouse_release_event(event);
|
||||
}
|
||||
|
||||
void BlockGrid::mouseMoveEvent(QMouseEvent* event) {
|
||||
m_block_dnd.mouse_move_event(event);
|
||||
}
|
||||
|
||||
void BlockGrid::advance_frame() {
|
||||
for (auto& ico : m_icons) {
|
||||
ico.advance_frame();
|
||||
|
|
|
@ -46,7 +46,11 @@ public:
|
|||
|
||||
protected:
|
||||
void paintEvent (QPaintEvent* event) override;
|
||||
void dragEnterEvent(QDragEnterEvent* event) override;
|
||||
void dropEvent(QDropEvent* event) override;
|
||||
void mousePressEvent(QMouseEvent* event) override;
|
||||
void mouseReleaseEvent(QMouseEvent* event) override;
|
||||
void mouseMoveEvent(QMouseEvent* event) override;
|
||||
|
||||
private slots:
|
||||
void advance_frame();
|
||||
|
|
|
@ -22,9 +22,13 @@
|
|||
#include <QMimeData>
|
||||
#include <QDrag>
|
||||
#include <QApplication>
|
||||
#include <QWidget>
|
||||
#include <cassert>
|
||||
#include <ciso646>
|
||||
#include <memory>
|
||||
#if !defined(NDEBUG)
|
||||
# include <iostream>
|
||||
#endif
|
||||
|
||||
namespace duck::widget::detail {
|
||||
namespace {
|
||||
|
@ -32,38 +36,74 @@ constexpr char g_drag_mime[] = "application/x-dndblock";
|
|||
} //unnamed namespace
|
||||
|
||||
BlockDragAndDrop::BlockDragAndDrop (
|
||||
QObject* parent,
|
||||
QWidget* parent,
|
||||
PointToIndexFunc&& func,
|
||||
std::function<std::size_t()>&& get_block_count,
|
||||
std::function<std::size_t()>&& get_icon_count,
|
||||
std::function<const QPixmap&(std::size_t)>&& get_pixmap
|
||||
) :
|
||||
m_point_to_index(std::move(func)),
|
||||
m_get_block_count(std::move(get_block_count)),
|
||||
m_get_icon_count(std::move(get_icon_count)),
|
||||
m_get_pixmap(std::move(get_pixmap)),
|
||||
m_parent(parent)
|
||||
{
|
||||
assert(m_parent);
|
||||
m_parent->setAcceptDrops(true);
|
||||
}
|
||||
|
||||
void BlockDragAndDrop::mouse_press_event (const QMouseEvent* event) {
|
||||
const auto [icon_index, block_origin] = m_point_to_index(event->position().toPoint());
|
||||
if (icon_index < 0)
|
||||
return;
|
||||
const auto icon_index_uns = static_cast<std::size_t>(icon_index);
|
||||
if (icon_index_uns >= m_get_block_count())
|
||||
if (event->button() & Qt::LeftButton) {
|
||||
assert(not m_dragging);
|
||||
|
||||
const auto [block_index, block_origin] = m_point_to_index(event->position().toPoint());
|
||||
if (block_index < 0)
|
||||
return;
|
||||
|
||||
const auto icon_index = static_cast<std::size_t>(block_index);
|
||||
if (icon_index >= m_get_icon_count())
|
||||
return;
|
||||
|
||||
m_start_pos = event->position().toPoint();
|
||||
m_dragging = true;
|
||||
m_block_index = block_index;
|
||||
m_hot_spot = m_start_pos - block_origin;
|
||||
}
|
||||
}
|
||||
|
||||
void BlockDragAndDrop::mouse_release_event(const QMouseEvent* event) {
|
||||
if (event->button() & Qt::LeftButton) {
|
||||
m_dragging = false;
|
||||
#if !defined(NDEBUG)
|
||||
std::cout << "Mouse button released before block's drag&drop\n";
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void BlockDragAndDrop::mouse_move_event (const QMouseEvent* event) {
|
||||
if (not m_dragging)
|
||||
return;
|
||||
|
||||
if (not (event->buttons() & Qt::LeftButton))
|
||||
return;
|
||||
|
||||
if ((event->position().toPoint() - m_start_pos).manhattanLength() < QApplication::startDragDistance())
|
||||
return;
|
||||
|
||||
#if !defined(NDEBUG)
|
||||
std::cout << "mouse_move_event() drag&drop started\n";
|
||||
#endif
|
||||
QByteArray item_data;
|
||||
QDataStream data_stream(&item_data, QIODevice::WriteOnly);
|
||||
data_stream << m_get_pixmap(icon_index_uns);
|
||||
data_stream << m_get_pixmap(m_block_index);
|
||||
|
||||
std::unique_ptr<QMimeData> mime_data(new QMimeData);
|
||||
mime_data->setData(g_drag_mime, item_data);
|
||||
|
||||
assert(m_block_index >= 0);
|
||||
const auto icon_index = static_cast<unsigned int>(m_block_index);
|
||||
QDrag* const drag(new QDrag(m_parent));
|
||||
drag->setMimeData(mime_data.release());
|
||||
drag->setPixmap(m_get_pixmap(icon_index_uns));
|
||||
drag->setHotSpot(event->position().toPoint() - block_origin);
|
||||
drag->setPixmap(m_get_pixmap(icon_index));
|
||||
drag->setHotSpot(m_hot_spot);
|
||||
|
||||
switch (drag->exec(Qt::CopyAction | Qt::MoveAction, Qt::CopyAction)) {
|
||||
case Qt::MoveAction:
|
||||
|
@ -73,5 +113,14 @@ void BlockDragAndDrop::mouse_press_event (const QMouseEvent* event) {
|
|||
default:
|
||||
break;
|
||||
}
|
||||
m_dragging = false;
|
||||
}
|
||||
|
||||
void BlockDragAndDrop::drag_enter_event(QDragEnterEvent* event) {
|
||||
if (not m_dragging and event->mimeData()->hasFormat(g_drag_mime))
|
||||
event->acceptProposedAction();
|
||||
}
|
||||
|
||||
void BlockDragAndDrop::drop_event(QDropEvent* event) {
|
||||
}
|
||||
} //namespace duck::widget::detail
|
||||
|
|
|
@ -23,6 +23,9 @@
|
|||
|
||||
class QMouseEvent;
|
||||
class QPixmap;
|
||||
class QWidget;
|
||||
class QDragEnterEvent;
|
||||
class QDropEvent;
|
||||
|
||||
namespace duck::widget::detail {
|
||||
class BlockDragAndDrop {
|
||||
|
@ -30,19 +33,27 @@ public:
|
|||
typedef std::function<std::pair<int,QPoint>(QPoint)> PointToIndexFunc;
|
||||
|
||||
BlockDragAndDrop (
|
||||
QObject* parent,
|
||||
QWidget* parent,
|
||||
PointToIndexFunc&& func,
|
||||
std::function<std::size_t()>&& get_block_count,
|
||||
std::function<std::size_t()>&& get_icon_count,
|
||||
std::function<const QPixmap&(std::size_t)>&& get_pixmap
|
||||
);
|
||||
|
||||
void mouse_press_event (const QMouseEvent* event);
|
||||
void mouse_release_event (const QMouseEvent* event);
|
||||
void mouse_move_event (const QMouseEvent* event);
|
||||
void drag_enter_event(QDragEnterEvent* event);
|
||||
void drop_event(QDropEvent* event);
|
||||
|
||||
private:
|
||||
PointToIndexFunc m_point_to_index;
|
||||
std::function<std::size_t()> m_get_block_count;
|
||||
std::function<std::size_t()> m_get_icon_count;
|
||||
std::function<const QPixmap&(std::size_t)> m_get_pixmap;
|
||||
QObject* m_parent;
|
||||
QWidget* m_parent;
|
||||
QPoint m_start_pos;
|
||||
QPoint m_hot_spot;
|
||||
int m_block_index;
|
||||
bool m_dragging {false};
|
||||
};
|
||||
|
||||
} //namespace duck::widget::detail
|
||||
|
|
Loading…
Add table
Reference in a new issue