490 lines
11 KiB
C++
Executable File
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"
|
|
|