Refactor d&d code out into a separate class
This commit is contained in:
parent
ed1a70b8ce
commit
d35a4f6d08
5 changed files with 137 additions and 35 deletions
|
@ -35,6 +35,7 @@ executable(app_name,
|
|||
project_config_file,
|
||||
gitrev_config_file,
|
||||
'widgets/block_grid.cpp',
|
||||
'widgets/detail/block_drag_and_drop.cpp',
|
||||
'make_qt_animation.cpp',
|
||||
'animated_pixmap.cpp',
|
||||
include_directories: inc,
|
||||
|
|
|
@ -21,11 +21,6 @@
|
|||
#include <QTimer>
|
||||
#include <QPixmap>
|
||||
#include <QPoint>
|
||||
#include <QByteArray>
|
||||
#include <QDataStream>
|
||||
#include <QMouseEvent>
|
||||
#include <QMimeData>
|
||||
#include <QDrag>
|
||||
#include <algorithm>
|
||||
|
||||
namespace duck::widget {
|
||||
|
@ -48,8 +43,14 @@ namespace {
|
|||
|
||||
BlockGrid::BlockGrid (QWidget* parent, unsigned int rows, unsigned int columns, float fps) :
|
||||
QWidget(parent),
|
||||
m_anim_timer(new QTimer(this)),
|
||||
m_block_dnd(
|
||||
this,
|
||||
{[this](QPoint pt){return locate_icon_index_at(pt);}},
|
||||
{[this](){return m_icons.size();}},
|
||||
{[this](std::size_t index)->const QPixmap&{return m_icons[index].current_frame();}}
|
||||
),
|
||||
m_icon_size(-1, -1),
|
||||
m_anim_timer(new QTimer(this)),
|
||||
m_rows(rows),
|
||||
m_columns(columns)
|
||||
{
|
||||
|
@ -126,34 +127,7 @@ 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<std::size_t>(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<QMimeData> 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;
|
||||
}
|
||||
m_block_dnd.mouse_press_event(event);
|
||||
}
|
||||
|
||||
void BlockGrid::advance_frame() {
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#pragma once
|
||||
|
||||
#include "../animated_pixmap.hpp"
|
||||
#include "detail/block_drag_and_drop.hpp"
|
||||
#include <QWidget>
|
||||
#include <QPixmap>
|
||||
#include <memory>
|
||||
|
@ -55,10 +56,11 @@ private:
|
|||
unsigned int columns() const;
|
||||
std::pair<int, QPoint> locate_icon_index_at (QPoint pt) const;
|
||||
|
||||
detail::BlockDragAndDrop m_block_dnd;
|
||||
std::vector<AnimatedPixmap> m_icons;
|
||||
QSize m_icon_size;
|
||||
QTimer* m_anim_timer;
|
||||
std::unique_ptr<QPixmap> m_empty_icon;
|
||||
QSize m_icon_size;
|
||||
unsigned int m_rows;
|
||||
unsigned int m_columns;
|
||||
};
|
||||
|
|
77
src/qt/widgets/detail/block_drag_and_drop.cpp
Normal file
77
src/qt/widgets/detail/block_drag_and_drop.cpp
Normal file
|
@ -0,0 +1,77 @@
|
|||
/* Copyright 2020-2025, Michele Santullo
|
||||
* This file is part of memoserv.
|
||||
*
|
||||
* Memoserv is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Memoserv is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Memoserv. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "block_drag_and_drop.hpp"
|
||||
#include <QByteArray>
|
||||
#include <QDataStream>
|
||||
#include <QMouseEvent>
|
||||
#include <QMimeData>
|
||||
#include <QDrag>
|
||||
#include <QApplication>
|
||||
#include <cassert>
|
||||
#include <ciso646>
|
||||
#include <memory>
|
||||
|
||||
namespace duck::widget::detail {
|
||||
namespace {
|
||||
constexpr char g_drag_mime[] = "application/x-dndblock";
|
||||
} //unnamed namespace
|
||||
|
||||
BlockDragAndDrop::BlockDragAndDrop (
|
||||
QObject* parent,
|
||||
PointToIndexFunc&& func,
|
||||
std::function<std::size_t()>&& get_block_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_pixmap(std::move(get_pixmap)),
|
||||
m_parent(parent)
|
||||
{
|
||||
assert(m_parent);
|
||||
}
|
||||
|
||||
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())
|
||||
return;
|
||||
|
||||
QByteArray item_data;
|
||||
QDataStream data_stream(&item_data, QIODevice::WriteOnly);
|
||||
data_stream << m_get_pixmap(icon_index_uns);
|
||||
|
||||
std::unique_ptr<QMimeData> mime_data(new QMimeData);
|
||||
mime_data->setData(g_drag_mime, item_data);
|
||||
|
||||
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);
|
||||
|
||||
switch (drag->exec(Qt::CopyAction | Qt::MoveAction, Qt::CopyAction)) {
|
||||
case Qt::MoveAction:
|
||||
break;
|
||||
case Qt::CopyAction:
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
} //namespace duck::widget::detail
|
48
src/qt/widgets/detail/block_drag_and_drop.hpp
Normal file
48
src/qt/widgets/detail/block_drag_and_drop.hpp
Normal file
|
@ -0,0 +1,48 @@
|
|||
/* Copyright 2020-2025, Michele Santullo
|
||||
* This file is part of memoserv.
|
||||
*
|
||||
* Memoserv is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Memoserv is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Memoserv. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QPoint>
|
||||
#include <functional>
|
||||
#include <utility>
|
||||
|
||||
class QMouseEvent;
|
||||
class QPixmap;
|
||||
|
||||
namespace duck::widget::detail {
|
||||
class BlockDragAndDrop {
|
||||
public:
|
||||
typedef std::function<std::pair<int,QPoint>(QPoint)> PointToIndexFunc;
|
||||
|
||||
BlockDragAndDrop (
|
||||
QObject* parent,
|
||||
PointToIndexFunc&& func,
|
||||
std::function<std::size_t()>&& get_block_count,
|
||||
std::function<const QPixmap&(std::size_t)>&& get_pixmap
|
||||
);
|
||||
|
||||
void mouse_press_event (const QMouseEvent* event);
|
||||
|
||||
private:
|
||||
PointToIndexFunc m_point_to_index;
|
||||
std::function<std::size_t()> m_get_block_count;
|
||||
std::function<const QPixmap&(std::size_t)> m_get_pixmap;
|
||||
QObject* m_parent;
|
||||
};
|
||||
|
||||
} //namespace duck::widget::detail
|
Loading…
Add table
Reference in a new issue