Files
qt6-migration-pipeline/Lts/Common/LtsWidgets/lts_drag_icon.cpp
T

490 lines
11 KiB
C++
Executable File

#include "lts_drag_icon.h"
#include <QDrag>
#include <QDragEnterEvent>
#include <QDragLeaveEvent>
#include <QDropEvent>
#include <QMimeData>
#include <QAction>
#include <QVBoxLayout>
#include <QLabel>
#include <QPixmap>
#include <QToolButton>
#include <QButtonGroup>
#include <QPainter>
namespace LtsWidgets
{
class LtsToolButton : public QToolButton
{
Q_OBJECT
public:
explicit LtsToolButton(QWidget *parent)
: QToolButton(parent)
, m_sameWidgetDrop(false)
, m_isDraggable(true)
, m_startPos(QPoint())
{
setAutoFillBackground(false);
setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
}
virtual ~LtsToolButton() = default;
void mousePressEvent(QMouseEvent *event) override;
void mouseReleaseEvent(QMouseEvent *event) override;
void mouseMoveEvent(QMouseEvent *event) override;
void dragEnterEvent(QDragEnterEvent *event) override;
void setSameWidgetDrop(bool drop) { m_sameWidgetDrop = drop; }
bool sameWidgetDrop() const { return m_sameWidgetDrop; }
void setDraggable(bool isDraggable) { m_isDraggable = isDraggable; }
void dropEvent(QDropEvent *event) override
{
emit newDropEvent(event);
QToolButton::dropEvent(event);
}
void addMimeData(const QString &mimeType, const QByteArray &data);
bool removeMimeData(const QString &mimeType);
void removeAllMimeData() { m_mimeData.clear(); }
protected:
void initButton();
signals:
void newDropEvent(QDropEvent *e);
void dropSuc();
private:
void performDrag(QMouseEvent *event);
bool m_sameWidgetDrop;
bool m_isDraggable;
QPoint m_startPos;
QMap<QString, QByteArray> m_mimeData;
};
LtsDragIcon::LtsDragIcon(QWidget *parent)
: QWidget(parent)
, m_lay(nullptr)
, m_toolButton(nullptr)
, m_icon()
, m_dragLabel(new QLabel(this))
, m_text()
, m_style(ButtonStyle::eAll)
, m_forceFixedSize(false)
, m_isDraggable(true)
, m_dropHandlerKey(0L)
, m_buttonSize(ButtonSize::eDefault)
, m_showDragIcon(true)
{
setAutoFillBackground(false);
initButton();
}
void LtsDragIcon::setStyleToButton()
{
if (nullptr == m_toolButton) return;
switch (m_style)
{
case ButtonStyle::eIconOnly:
{
setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
m_toolButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
setFixedSize(QSize(static_cast<int>(m_buttonSize), static_cast<int>(m_buttonSize)));
m_toolButton->setToolButtonStyle(Qt::ToolButtonIconOnly);
} break;
case ButtonStyle::eTextOnly:
{
setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
m_toolButton->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum);
setFixedSize( QSize(QWIDGETSIZE_MAX,QWIDGETSIZE_MAX) );
m_toolButton->setToolButtonStyle(Qt::ToolButtonTextOnly);
layout()->setSizeConstraint( QLayout::SetDefaultConstraint );
} break;
case ButtonStyle::eTextNextToIcon:
{
setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Fixed);
m_toolButton->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum);
setFixedSize( QSize(QWIDGETSIZE_MAX,QWIDGETSIZE_MAX) );
m_toolButton->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
layout()->setSizeConstraint( QLayout::SetDefaultConstraint );
} break;
default: break;
}
}
void LtsDragIcon::initButton()
{
setMinimumSize(static_cast<int>(m_buttonSize), static_cast<int>(m_buttonSize));
delete m_toolButton;
delete m_lay;
delete layout();
m_toolButton = new LtsToolButton(this);
m_toolButton->setDraggable(m_isDraggable);
connect(m_toolButton, &LtsToolButton::clicked, this, &LtsDragIcon::clicked);
connect(m_toolButton, &LtsToolButton::toggled, this, &LtsDragIcon::toggled);
connect(m_toolButton, &LtsToolButton::newDropEvent, this, &LtsDragIcon::newDropEvent);
connect(m_toolButton, &LtsToolButton::dropSuc, this, &LtsDragIcon::dropSuc);
m_toolButton->setIcon(modifyIcon(m_icon));
m_toolButton->setText(m_text);
generateToolTip();
m_toolButton->setIconSize(QSize(static_cast<int>(m_buttonSize), static_cast<int>(m_buttonSize)));
QVBoxLayout *box = new QVBoxLayout(this);
box->setMargin(0);
box->setSpacing(0);
box->addWidget(m_toolButton);
this->setLayout(box);
m_toolButton->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
if (m_forceFixedSize)
{
m_toolButton->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
setFixedSize(QSize(static_cast<int>(m_buttonSize), static_cast<int>(m_buttonSize)));
}
else
{
m_toolButton->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum);
setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum);
}
setStyleToButton();
}
void LtsDragIcon::addToButtonGroup(QButtonGroup *btnGrp, int btnGrpId)
{
btnGrp->addButton(m_toolButton, btnGrpId);
}
void LtsDragIcon::setIcon(const QIcon &icon)
{
m_icon = icon;
(m_toolButton) ? m_toolButton->setIcon(modifyIcon(m_icon)) : initButton();
}
void LtsDragIcon::setMenu(QMenu *menu)
{
if (nullptr == m_toolButton)
initButton();
m_toolButton->setMenu(menu);
}
QMenu *LtsDragIcon::menu() const
{
if (nullptr == m_toolButton)
return nullptr;
return m_toolButton->menu();
}
void LtsDragIcon::setText(const QString &text)
{
m_text = text;
(m_toolButton) ? generateToolTip() : initButton();
}
void LtsDragIcon::setContext(const QString &context)
{
m_context = context;
generateToolTip();
}
void LtsDragIcon::generateToolTip()
{
if (!m_toolButton || m_text.isEmpty())
return;
QString text(m_text);
if (!m_context.isEmpty())
text.prepend(m_context + QLatin1String(" - "));
m_toolButton->setText(m_text);
m_toolButton->setToolTip(text);
}
bool LtsDragIcon::isCheckable()
{
return (m_toolButton) ? m_toolButton->isCheckable() : false;
}
void LtsDragIcon::setDraggable(bool draggable)
{
m_isDraggable = draggable;
m_toolButton->setDraggable(m_isDraggable);
}
void LtsDragIcon::setCheckable(bool checkable)
{
m_toolButton->setCheckable(checkable);
}
bool LtsDragIcon::isChecked() const
{
return (m_toolButton) ? m_toolButton->isChecked() : false;
}
void LtsDragIcon::setChecked(bool checked)
{
if (nullptr == m_toolButton)
initButton();
m_toolButton->setChecked(checked);
}
void LtsDragIcon::setSameWidgetDrop(bool drop)
{
if (nullptr == m_toolButton)
initButton();
m_toolButton->setSameWidgetDrop(drop);
}
bool LtsDragIcon::sameWidgetDrop() const
{
if (nullptr == m_toolButton)
return false;
return m_toolButton->sameWidgetDrop();
}
void LtsDragIcon::addMimeData(const QString &mimeType, const QByteArray &data)
{
if (nullptr == m_toolButton)
initButton();
m_toolButton->addMimeData(mimeType, data);
}
bool LtsDragIcon::removeMimeData(const QString &mimeType)
{
if (nullptr == m_toolButton)
initButton();
return m_toolButton->removeMimeData(mimeType);
}
void LtsDragIcon::removeAllMimeData()
{
if (nullptr == m_toolButton)
initButton();
m_toolButton->removeAllMimeData();
}
void LtsDragIcon::setAcceptDrops(bool on)
{
if (nullptr == m_toolButton)
initButton();
m_toolButton->setAcceptDrops(on);
}
void LtsDragIcon::dragEnterEvent(QDragEnterEvent *e)
{
if (m_toolButton)
m_toolButton->dragEnterEvent(e);
}
void LtsDragIcon::dropEvent(QDropEvent *e)
{
QWidget::dropEvent(e);
}
void LtsDragIcon::setButtonStyle(ButtonStyle style)
{
m_style = style;
setStyleToButton();
}
void LtsDragIcon::setIconSize(ButtonSize buttonSize)
{
m_buttonSize = buttonSize;
(m_toolButton) ? m_toolButton->setIconSize(QSize(static_cast<int>(m_buttonSize), static_cast<int>(m_buttonSize))) : initButton();
}
void LtsDragIcon::setForceFixedSize(bool force)
{
m_forceFixedSize = force;
initButton();
}
void LtsDragIcon::setButtonVisible(bool visible)
{
if (nullptr == m_toolButton)
initButton();
m_toolButton->setVisible(visible);
}
bool LtsDragIcon::buttonVisible() const
{
if (nullptr == m_toolButton)
return false;
return m_toolButton->isVisible();
}
void LtsDragIcon::setAction(QAction *action)
{
QIcon icon = action->icon();
if(!icon.isNull())
m_icon = icon;
m_toolButton->setDefaultAction(action);
this->setObjectName(action->objectName());
}
void LtsDragIcon::changeEvent(QEvent *event)
{
if (event->type() == QEvent::EnabledChange)
emit enabledChanged(isEnabled());
}
void LtsToolButton::mousePressEvent(QMouseEvent *event)
{
if (event->button() == Qt::LeftButton)
m_startPos = event->pos();
QToolButton::mousePressEvent(event);
}
void LtsToolButton::mouseReleaseEvent(QMouseEvent *event)
{
QToolButton::mouseReleaseEvent(event);
}
void LtsToolButton::mouseMoveEvent(QMouseEvent *event)
{
if (!m_isDraggable)
return;
if (event->buttons() & Qt::LeftButton) {
int distance = (event->pos() - m_startPos).manhattanLength();
if (distance >= 5)
{
this->setDown(false);
performDrag(event);
return;
}
}
QToolButton::mouseMoveEvent(event);
}
void LtsToolButton::performDrag(QMouseEvent *)
{
QWidget *item = this;
if (item)
{
LtsDragIcon *dragIcon = nullptr;
QString name;
while (dragIcon == nullptr)
{
if ((!item->objectName().isEmpty()) && (name.isNull()))
{
name = item->objectName();
}
item = item->parentWidget();
if (nullptr == item) return;
dragIcon = dynamic_cast<LtsDragIcon*>(item);
}
QMimeData *mimeData = new QMimeData();
mimeData->setText(name);
for(auto it = m_mimeData.cbegin(); it != m_mimeData.cend(); ++it)
mimeData->setData(it.key(), it.value());
if (dragIcon->dropHandlerKey() != 0L)
{
QByteArray data = QByteArray(QByteArray::number(dragIcon->dropHandlerKey()));
mimeData->setData(QLatin1String("DropHandlerPtr"),data);
}
QDrag *drag = new QDrag(item);
drag->setMimeData(mimeData);
QAction *action = defaultAction();
if ((action) && (dragIcon->showDragIcon()))
{
drag->setPixmap(action->icon().pixmap(16,16) );
}
else
{
drag->setPixmap(dragIcon->icon().pixmap(16, 16));
}
Qt::DropAction drop = drag->exec(Qt::CopyAction | Qt::MoveAction);
if (drop == Qt::MoveAction || drop == Qt::CopyAction )
emit dropSuc();
}
}
void LtsToolButton::dragEnterEvent(QDragEnterEvent *event)
{
QWidget *source =
qobject_cast<QWidget *>(event->source());
if (source && source != this) {
event->setDropAction(Qt::MoveAction);
event->accept();
}
QWidget::dragEnterEvent(event);
}
void LtsToolButton::addMimeData(const QString &mimeType, const QByteArray &data)
{
m_mimeData.insert(mimeType,data);
}
bool LtsToolButton::removeMimeData(const QString &mimeType)
{
return (m_mimeData.remove(mimeType) > 0);
}
#define SIZE 40
QIcon LtsDragIcon::modifyIcon(const QIcon &icon)
{
if (m_modification.isEmpty())
return icon;
QPixmap iconImage(icon.pixmap(SIZE*0.8, SIZE*0.8));
QPainter painter(&iconImage);
painter.save();
painter.setRenderHints(QPainter::TextAntialiasing | QPainter::Antialiasing | QPainter::HighQualityAntialiasing | QPainter::SmoothPixmapTransform);
painter.setBrush(QColor("red"));
painter.setPen(QPen(QColor("red"), 3));
QFont f;
f.setFamily(QStringLiteral("Monospace"));
f.setPointSize(12);
f.setBold(true);
painter.setFont(f);
painter.drawText(QRect(0, 0, 28, 28), m_modification);
painter.restore();
return iconImage;
}
}
#include "lts_drag_icon.moc"