diff --git a/src/qt/widgets/block_grid.cpp b/src/qt/widgets/block_grid.cpp index 7513538..ece8ae6 100644 --- a/src/qt/widgets/block_grid.cpp +++ b/src/qt/widgets/block_grid.cpp @@ -21,6 +21,11 @@ #include #include #include +#include +#include +#include +#include +#include #include namespace duck::widget { @@ -143,10 +148,71 @@ void BlockGrid::paintEvent (QPaintEvent* event) { } } +void BlockGrid::mousePressEvent(QMouseEvent* event) { + const auto [icon_index, block_origin] = locate_icon_index_at(event->position().toPoint()); + if (icon_index < 0) + return; + + const auto icon_index_uns = static_cast(icon_index); + if (icon_index_uns >= m_icons.size()) + return; + + QByteArray item_data; + QDataStream data_stream(&item_data, QIODevice::WriteOnly); + data_stream << m_icons[icon_index_uns].current_frame(); + + std::unique_ptr mime_data(new QMimeData); + mime_data->setData("application/x-dndblock", item_data); + + QDrag* const drag(new QDrag(this)); + drag->setMimeData(mime_data.release()); + drag->setPixmap(m_icons[icon_index_uns].current_frame()); + drag->setHotSpot(event->position().toPoint() - block_origin); + + switch (drag->exec(Qt::CopyAction | Qt::MoveAction, Qt::CopyAction)) { + case Qt::MoveAction: + break; + case Qt::CopyAction: + break; + default: + break; + } +} + void BlockGrid::advance_frame() { for (auto& ico : m_icons) { ico.advance_frame(); } this->update(); } + +std::pair BlockGrid::locate_icon_index_at(QPoint pt) const { + if (pt.x() < g_icon_spacing or pt.y() < g_icon_spacing) + return {-1, QPoint()}; + + const auto ico_spacing_uns = static_cast(g_icon_spacing); + const auto x = static_cast(pt.x()) - ico_spacing_uns; + const auto y = static_cast(pt.y()) - ico_spacing_uns; + const auto w = static_cast(m_icon_size.width()) + ico_spacing_uns; + const auto h = static_cast(m_icon_size.height()) + ico_spacing_uns; + + if (x >= w * columns() or y > h * rows()) + return {-1, QPoint()}; + + const unsigned int x_index = x / w; + const unsigned int y_index = y / h; + + const auto rel_x = x - x_index * w; + const auto rel_y = y - y_index * h; + + if (rel_x < (w - ico_spacing_uns) and rel_y < (h - ico_spacing_uns)) { + return { + static_cast(x_index + y_index * columns()), + QPoint(g_icon_spacing, g_icon_spacing) + pt - QPoint(static_cast(rel_x), static_cast(rel_y)) + }; + } + else { + return {-1, QPoint()}; + } +} } //namespace duck::widget diff --git a/src/qt/widgets/block_grid.hpp b/src/qt/widgets/block_grid.hpp index cff29f6..d52f5f4 100644 --- a/src/qt/widgets/block_grid.hpp +++ b/src/qt/widgets/block_grid.hpp @@ -22,6 +22,7 @@ #include #include #include +#include class QTimer; @@ -44,6 +45,7 @@ public: protected: void paintEvent (QPaintEvent* event) override; + void mousePressEvent(QMouseEvent* event) override; private slots: void advance_frame(); @@ -51,6 +53,7 @@ private slots: private: unsigned int rows() const; unsigned int columns() const; + std::pair locate_icon_index_at (QPoint pt) const; std::vector m_icons; QTimer* m_anim_timer;