mirror of
https://github.com/linuxdeepin/dde-dock.git
synced 2025-06-02 15:45:21 +00:00
feat: 支持从快捷面板拖动图标驻留到任务栏
增加从快捷面板拖动应用到任务栏的功能 Log: Influence: 从快捷面板拖动图标到任务栏,观察是否驻留在任务栏 Bug: https://pms.uniontech.com/bug-view-171517.html Change-Id: I3351be282ef8d3afbb55f227fc6ae8ce16c78a97
This commit is contained in:
parent
75a9312fcb
commit
541cdf60e7
@ -73,6 +73,7 @@ target_include_directories(${BIN_NAME} PUBLIC
|
||||
window/components
|
||||
window/tray
|
||||
window/tray/widgets
|
||||
drag
|
||||
xcb
|
||||
../plugins/tray
|
||||
../plugins/show-desktop
|
||||
|
147
frame/drag/quickdragcore.cpp
Normal file
147
frame/drag/quickdragcore.cpp
Normal file
@ -0,0 +1,147 @@
|
||||
#include "quickdragcore.h"
|
||||
|
||||
#include <QWidget>
|
||||
#include <QTimer>
|
||||
#include <QPainter>
|
||||
#include <QPainterPath>
|
||||
#include <QBitmap>
|
||||
#include <QEvent>
|
||||
#include <QDebug>
|
||||
#include <QCoreApplication>
|
||||
#include <QDragEnterEvent>
|
||||
|
||||
QuickPluginMimeData::QuickPluginMimeData(PluginsItemInterface *item, QDrag *drag)
|
||||
: QMimeData()
|
||||
, m_item(item)
|
||||
, m_drag(drag)
|
||||
{
|
||||
}
|
||||
|
||||
QuickPluginMimeData::~QuickPluginMimeData()
|
||||
{
|
||||
}
|
||||
|
||||
PluginsItemInterface *QuickPluginMimeData::pluginItemInterface() const
|
||||
{
|
||||
return m_item;
|
||||
}
|
||||
|
||||
QDrag *QuickPluginMimeData::drag() const
|
||||
{
|
||||
return m_drag;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief 拖动图标的窗口,可以根据实际情况设置动态图标
|
||||
* @param dragSource
|
||||
*/
|
||||
QuickIconDrag::QuickIconDrag(QObject *dragSource, const QPixmap &pixmap)
|
||||
: QDrag(dragSource)
|
||||
, m_imageWidget(new QWidget)
|
||||
, m_timer(new QTimer(this))
|
||||
, m_sourcePixmap(pixmap)
|
||||
, m_hotPoint(QPoint(0, 0))
|
||||
{
|
||||
m_timer->setInterval(10);
|
||||
connect(m_timer, &QTimer::timeout, this, &QuickIconDrag::onDragMove);
|
||||
m_timer->start();
|
||||
|
||||
m_imageWidget->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowDoesNotAcceptFocus);
|
||||
m_imageWidget->setAttribute(Qt::WA_TransparentForMouseEvents);
|
||||
m_imageWidget->installEventFilter(this);
|
||||
useSourcePixmap();
|
||||
}
|
||||
|
||||
QuickIconDrag::~QuickIconDrag()
|
||||
{
|
||||
m_imageWidget->deleteLater();
|
||||
}
|
||||
|
||||
void QuickIconDrag::updatePixmap(QPixmap pixmap)
|
||||
{
|
||||
if (m_sourcePixmap == pixmap)
|
||||
return;
|
||||
|
||||
m_pixmap = pixmap;
|
||||
m_useSourcePixmap = false;
|
||||
m_imageWidget->setWindowFlags(Qt::FramelessWindowHint | Qt::WindowDoesNotAcceptFocus | Qt::WindowStaysOnTopHint | Qt::X11BypassWindowManagerHint);
|
||||
m_imageWidget->setFixedSize(pixmap.size());
|
||||
m_imageWidget->show();
|
||||
m_imageWidget->raise();
|
||||
m_imageWidget->update();
|
||||
}
|
||||
|
||||
void QuickIconDrag::useSourcePixmap()
|
||||
{
|
||||
m_useSourcePixmap = true;
|
||||
m_imageWidget->setFixedSize(m_sourcePixmap.size());
|
||||
m_imageWidget->show();
|
||||
m_imageWidget->raise();
|
||||
m_imageWidget->update();
|
||||
}
|
||||
|
||||
void QuickIconDrag::setDragHotPot(QPoint point)
|
||||
{
|
||||
m_hotPoint = point;
|
||||
m_imageWidget->update();
|
||||
}
|
||||
|
||||
bool QuickIconDrag::eventFilter(QObject *watched, QEvent *event)
|
||||
{
|
||||
if (watched == m_imageWidget) {
|
||||
switch (event->type()) {
|
||||
case QEvent::Paint: {
|
||||
QPixmap pixmap = m_useSourcePixmap ? m_sourcePixmap : m_pixmap;
|
||||
QPainter painter(m_imageWidget);
|
||||
painter.drawPixmap(QPoint(0, 0), pixmap);
|
||||
|
||||
QPixmap pixmapMask(m_imageWidget->size());
|
||||
pixmapMask.fill(Qt::transparent);
|
||||
QPainter painterMask(&pixmapMask);
|
||||
QPainterPath path;
|
||||
path.addRoundedRect(pixmapMask.rect(), 8, 8);
|
||||
painterMask.fillPath(path, Qt::white);
|
||||
painterMask.setRenderHint(QPainter::Antialiasing, true);
|
||||
painterMask.setCompositionMode(QPainter::CompositionMode_Source);
|
||||
painterMask.drawPixmap(0, 0, pixmap);
|
||||
painterMask.setCompositionMode(QPainter::CompositionMode_DestinationIn);
|
||||
QColor maskColor(Qt::black);
|
||||
maskColor.setAlpha(150);
|
||||
painterMask.fillRect(pixmapMask.rect(), maskColor);
|
||||
painterMask.end();
|
||||
|
||||
// 绘制圆角
|
||||
QBitmap radiusMask(m_imageWidget->size());
|
||||
radiusMask.fill();
|
||||
QPainter radiusPainter(&radiusMask);
|
||||
radiusPainter.setPen(Qt::NoPen);
|
||||
radiusPainter.setBrush(Qt::black);
|
||||
radiusPainter.setRenderHint(QPainter::Antialiasing);
|
||||
radiusPainter.drawRoundedRect(radiusMask.rect(), 8, 8);
|
||||
m_imageWidget->setMask(radiusMask);
|
||||
|
||||
painter.end();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
return QDrag::eventFilter(watched, event);
|
||||
}
|
||||
|
||||
QPoint QuickIconDrag::currentPoint() const
|
||||
{
|
||||
QPoint mousePos = QCursor::pos();
|
||||
if (m_useSourcePixmap)
|
||||
return mousePos - m_hotPoint;
|
||||
|
||||
QSize pixmapSize = m_pixmap.size();
|
||||
return (mousePos - QPoint(pixmapSize.width() * (m_hotPoint.x() / m_sourcePixmap.width())
|
||||
, pixmapSize.height() * (m_hotPoint.y() / m_sourcePixmap.height())));
|
||||
}
|
||||
|
||||
void QuickIconDrag::onDragMove()
|
||||
{
|
||||
m_imageWidget->move(currentPoint());
|
||||
}
|
53
frame/drag/quickdragcore.h
Normal file
53
frame/drag/quickdragcore.h
Normal file
@ -0,0 +1,53 @@
|
||||
#ifndef QUICKDRAGCORE_H
|
||||
#define QUICKDRAGCORE_H
|
||||
|
||||
#include <QMimeData>
|
||||
#include <QDrag>
|
||||
#include <QPixmap>
|
||||
|
||||
class PluginsItemInterface;
|
||||
class QTimer;
|
||||
|
||||
class QuickPluginMimeData : public QMimeData
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit QuickPluginMimeData(PluginsItemInterface *item, QDrag *drag);
|
||||
~QuickPluginMimeData();
|
||||
PluginsItemInterface *pluginItemInterface() const;
|
||||
QDrag *drag() const;
|
||||
|
||||
private:
|
||||
PluginsItemInterface *m_item;
|
||||
QDrag *m_drag;
|
||||
};
|
||||
|
||||
class QuickIconDrag : public QDrag
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit QuickIconDrag(QObject *dragSource, const QPixmap &pixmap);
|
||||
~QuickIconDrag();
|
||||
void updatePixmap(QPixmap pixmap);
|
||||
void useSourcePixmap();
|
||||
void setDragHotPot(QPoint point);
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *watched, QEvent *event) override;
|
||||
QPoint currentPoint() const;
|
||||
|
||||
private Q_SLOTS:
|
||||
void onDragMove();
|
||||
|
||||
private:
|
||||
QWidget *m_imageWidget;
|
||||
QTimer *m_timer;
|
||||
QPixmap m_sourcePixmap;
|
||||
QPixmap m_pixmap;
|
||||
QPoint m_hotPoint;
|
||||
bool m_useSourcePixmap;
|
||||
};
|
||||
|
||||
#endif // QUICKDRAGCORE_H
|
@ -120,13 +120,8 @@ QPixmap SingleQuickItem::pixmap() const
|
||||
{
|
||||
// 如果快捷面板区域的图标为空,那么就获取itemWidget的截图
|
||||
QIcon icon = pluginItem()->icon(DockPart::QuickPanel);
|
||||
if (icon.isNull()) {
|
||||
QWidget *itemWidget = pluginItem()->itemWidget(itemKey());
|
||||
if (itemWidget) {
|
||||
itemWidget->setFixedSize(24, 24);
|
||||
icon = itemWidget->grab();
|
||||
}
|
||||
}
|
||||
if (icon.isNull())
|
||||
return QPixmap();
|
||||
|
||||
int pixmapWidth = width();
|
||||
int pixmapHeight = height();
|
||||
|
@ -34,6 +34,8 @@
|
||||
#include <QPainterPath>
|
||||
#include <QPushButton>
|
||||
#include <QFontMetrics>
|
||||
#include <QPainterPath>
|
||||
#include <QBitmap>
|
||||
|
||||
#define ICONWIDTH 24
|
||||
#define ICONHEIGHT 24
|
||||
@ -72,27 +74,7 @@ DockItem::ItemType QuickSettingItem::itemType() const
|
||||
|
||||
const QPixmap QuickSettingItem::dragPixmap()
|
||||
{
|
||||
QPixmap pm = m_pluginInter->icon(DockPart::QuickPanel).pixmap(ICONWIDTH, ICONHEIGHT);
|
||||
|
||||
QPainter pa(&pm);
|
||||
pa.setPen(foregroundColor());
|
||||
pa.setCompositionMode(QPainter::CompositionMode_SourceIn);
|
||||
pa.fillRect(pm.rect(), foregroundColor());
|
||||
|
||||
QPixmap pmRet(ICONWIDTH + ICONSPACE + FONTSIZE * 2, ICONHEIGHT + ICONSPACE + FONTSIZE * 2);
|
||||
pmRet.fill(Qt::transparent);
|
||||
QPainter paRet(&pmRet);
|
||||
paRet.drawPixmap(QPoint((ICONSPACE + FONTSIZE * 2) / 2, 0), pm);
|
||||
paRet.setPen(pa.pen());
|
||||
|
||||
QFont ft;
|
||||
ft.setPixelSize(FONTSIZE);
|
||||
paRet.setFont(ft);
|
||||
QTextOption option;
|
||||
option.setAlignment(Qt::AlignTop | Qt::AlignHCenter);
|
||||
paRet.drawText(QRect(QPoint(0, ICONHEIGHT + ICONSPACE),
|
||||
QPoint(pmRet.width(), pmRet.height())), m_pluginInter->pluginDisplayName(), option);
|
||||
return pmRet;
|
||||
return grab();
|
||||
}
|
||||
|
||||
const QString QuickSettingItem::itemKey() const
|
||||
|
@ -29,6 +29,7 @@
|
||||
#include "pluginsitem.h"
|
||||
#include "quicksettingcontainer.h"
|
||||
#include "expandiconwidget.h"
|
||||
#include "quickdragcore.h"
|
||||
|
||||
#include <DGuiApplicationHelper>
|
||||
|
||||
@ -313,7 +314,6 @@ void DockTrayWindow::initConnection()
|
||||
connect(m_systemPuginWidget, &SystemPluginWindow::itemChanged, this, &DockTrayWindow::onUpdateComponentSize);
|
||||
connect(m_dateTimeWidget, &DateTimeDisplayer::requestUpdate, this, &DockTrayWindow::onUpdateComponentSize);
|
||||
connect(m_quickIconWidget, &QuickPluginWindow::itemCountChanged, this, &DockTrayWindow::onUpdateComponentSize);
|
||||
connect(m_quickIconWidget, &QuickPluginWindow::requestDrop, this, &DockTrayWindow::onDropIcon);
|
||||
connect(m_systemPuginWidget, &SystemPluginWindow::requestDrop, this, &DockTrayWindow::onDropIcon);
|
||||
connect(m_model, &TrayModel::rowCountChanged, this, &DockTrayWindow::onUpdateComponentSize);
|
||||
connect(m_model, &TrayModel::rowCountChanged, m_trayView, &TrayGridView::onUpdateEditorView);
|
||||
|
@ -25,7 +25,6 @@
|
||||
|
||||
#include <QWidget>
|
||||
|
||||
static QStringList fixedPluginNames { "network", "sound", "power" };
|
||||
#define PLUGINNAMEKEY "Dock_Quick_Plugin_Name"
|
||||
|
||||
QuickPluginModel *QuickPluginModel::instance()
|
||||
@ -40,17 +39,15 @@ void QuickPluginModel::addPlugin(PluginsItemInterface *itemInter, int index)
|
||||
if (QuickSettingController::instance()->pluginAttribute(itemInter) != QuickSettingController::PluginAttribute::Quick)
|
||||
return;
|
||||
|
||||
if (index < 0) {
|
||||
// 如果索引值小于0,则认为它插在最后面
|
||||
index = m_dockedPluginIndex.size();
|
||||
}
|
||||
|
||||
// 如果插入的插件在原来的插件列表中存在,并且位置相同,则不做任何的处理
|
||||
int oldIndex = m_dockedPluginIndex.contains(itemInter->pluginName());
|
||||
// 获取当前插件在插件区的位置索引(所有在任务栏上显示的插件)
|
||||
int oldIndex = getCurrentIndex(itemInter);
|
||||
// 计算插入之前的顺序
|
||||
if (oldIndex == index && m_dockedPluginsItems.contains(itemInter))
|
||||
return;
|
||||
|
||||
m_dockedPluginIndex[itemInter->pluginName()] = index;
|
||||
// 根据插件区域的位置计算新的索引值
|
||||
int newIndex = generaIndex(index, oldIndex);
|
||||
m_dockedPluginIndex[itemInter->pluginName()] = newIndex;
|
||||
if (!m_dockedPluginsItems.contains(itemInter)) {
|
||||
m_dockedPluginsItems << itemInter;
|
||||
// 保存配置到dConfig中
|
||||
@ -83,10 +80,10 @@ QList<PluginsItemInterface *> QuickPluginModel::dockedPluginItems() const
|
||||
QList<PluginsItemInterface *> dockedItems;
|
||||
QList<PluginsItemInterface *> activedItems;
|
||||
for (PluginsItemInterface *itemInter : m_dockedPluginsItems) {
|
||||
if (fixedPluginNames.contains(itemInter->pluginName()))
|
||||
dockedItems << itemInter;
|
||||
else
|
||||
if (isFixed(itemInter))
|
||||
activedItems << itemInter;
|
||||
else
|
||||
dockedItems << itemInter;
|
||||
}
|
||||
std::sort(dockedItems.begin(), dockedItems.end(), [ this ](PluginsItemInterface *item1, PluginsItemInterface *item2) {
|
||||
return m_dockedPluginIndex.value(item1->pluginName()) < m_dockedPluginIndex.value(item2->pluginName());
|
||||
@ -104,7 +101,7 @@ bool QuickPluginModel::isDocked(PluginsItemInterface *itemInter) const
|
||||
|
||||
bool QuickPluginModel::isFixed(PluginsItemInterface *itemInter) const
|
||||
{
|
||||
return fixedPluginNames.contains(itemInter->pluginName());
|
||||
return !(itemInter->flags() & PluginFlag::Attribute_CanInsert);
|
||||
}
|
||||
|
||||
QuickPluginModel::QuickPluginModel(QObject *parent)
|
||||
@ -206,3 +203,86 @@ void QuickPluginModel::saveConfig()
|
||||
});
|
||||
SETTINGCONFIG->setValue(PLUGINNAMEKEY, plugins);
|
||||
}
|
||||
|
||||
int QuickPluginModel::getCurrentIndex(PluginsItemInterface *itemInter)
|
||||
{
|
||||
QList<PluginsItemInterface *> dockedPluginsItems = m_dockedPluginsItems;
|
||||
std::sort(dockedPluginsItems.begin(), dockedPluginsItems.end(), [ this ](PluginsItemInterface *plugin1, PluginsItemInterface *plugin2) {
|
||||
return m_dockedPluginIndex.value(plugin1->pluginName()) < m_dockedPluginIndex.value(plugin2->pluginName());
|
||||
});
|
||||
return dockedPluginItems().indexOf(itemInter);
|
||||
}
|
||||
|
||||
int QuickPluginModel::generaIndex(int insertIndex, int oldIndex)
|
||||
{
|
||||
int newIndex = insertIndex;
|
||||
if (oldIndex < 0) {
|
||||
newIndex = insertIndex + 1;
|
||||
// 如果该插件在列表中存在,则需要将原来的索引值加一
|
||||
if (insertIndex < 0) {
|
||||
// 如果新插入的索引值为-1,则表示需要插入到末尾的位置,此时需要从索引值中找到最大值
|
||||
int lastIndex = -1;
|
||||
for (PluginsItemInterface *itemInter : m_dockedPluginsItems) {
|
||||
int index = m_dockedPluginIndex.value(itemInter->pluginName());
|
||||
if (lastIndex < index)
|
||||
lastIndex = index;
|
||||
}
|
||||
newIndex = lastIndex + 1;
|
||||
}
|
||||
if (m_dockedPluginIndex.values().contains(newIndex)) {
|
||||
// 遍历map列表,检查列表中是否存在等于新索引的插件,如果存在,将其后面的索引值向后加一
|
||||
for (auto it = m_dockedPluginIndex.begin(); it != m_dockedPluginIndex.end(); it++) {
|
||||
if (it.value() < newIndex)
|
||||
continue;
|
||||
|
||||
m_dockedPluginIndex[it.key()] = it.value() + 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
newIndex = insertIndex;
|
||||
// 如果该插件已经存在于下面的列表中,则分两种情况
|
||||
if (insertIndex < 0) {
|
||||
// 如果插入在末尾,则计算最大值
|
||||
if (m_dockedPluginIndex.size() > 0) {
|
||||
int maxIndex = m_dockedPluginIndex.first();
|
||||
for (auto it = m_dockedPluginIndex.begin(); it != m_dockedPluginIndex.end(); it++) {
|
||||
if (maxIndex < it.value())
|
||||
maxIndex = it.value();
|
||||
}
|
||||
return maxIndex;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if (insertIndex > oldIndex) {
|
||||
int minIndex = NGROUPS_MAX;
|
||||
// 新的位置的索引值大于原来位置的索引值,则认为插入在原来的任务栏的后面,将前面的插件的索引值减去1
|
||||
for (PluginsItemInterface *itemInter : m_dockedPluginsItems) {
|
||||
int pluginDockIndex = getCurrentIndex(itemInter);
|
||||
qInfo() << itemInter->pluginDisplayName() << m_dockedPluginIndex[itemInter->pluginName()] << pluginDockIndex;
|
||||
if (pluginDockIndex > oldIndex) {
|
||||
if (pluginDockIndex <= insertIndex) {
|
||||
int tmpIndex = m_dockedPluginIndex[itemInter->pluginName()];
|
||||
if (tmpIndex < minIndex)
|
||||
minIndex = tmpIndex;
|
||||
}
|
||||
m_dockedPluginIndex[itemInter->pluginName()]--;
|
||||
}
|
||||
qInfo() << itemInter->pluginDisplayName() << m_dockedPluginIndex[itemInter->pluginName()];
|
||||
}
|
||||
|
||||
if (minIndex != NGROUPS_MAX)
|
||||
newIndex = minIndex;
|
||||
} else {
|
||||
// 新的位置索引小于原来的索引值,则认为是插在任务栏的前面,将任务栏后面的插件的索引值加一
|
||||
for (PluginsItemInterface *itemInter : m_dockedPluginsItems) {
|
||||
int pluginDockIndex = getCurrentIndex(itemInter);
|
||||
if (pluginDockIndex >= insertIndex) {
|
||||
m_dockedPluginIndex[itemInter->pluginName()]++;
|
||||
}
|
||||
qInfo() << itemInter->pluginDisplayName() << m_dockedPluginIndex[itemInter->pluginName()];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return newIndex;
|
||||
}
|
||||
|
@ -60,6 +60,8 @@ private:
|
||||
void initConnection();
|
||||
void initConfig();
|
||||
void saveConfig();
|
||||
int getCurrentIndex(PluginsItemInterface *itemInter);
|
||||
int generaIndex(int sourceIndex, int oldIndex);
|
||||
|
||||
private:
|
||||
QList<PluginsItemInterface *> m_dockedPluginsItems;
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "appdrag.h"
|
||||
#include "proxyplugincontroller.h"
|
||||
#include "quickpluginmodel.h"
|
||||
#include "quickdragcore.h"
|
||||
|
||||
#include <DStyleOption>
|
||||
#include <DStandardItem>
|
||||
@ -39,6 +40,7 @@
|
||||
#include <QBoxLayout>
|
||||
#include <QGuiApplication>
|
||||
#include <QMenu>
|
||||
#include <QDragLeaveEvent>
|
||||
|
||||
#define ITEMSIZE 22
|
||||
#define ITEMSPACE 6
|
||||
@ -66,8 +68,8 @@ typedef struct DragInfo{
|
||||
if (!dragPixmap())
|
||||
return false;
|
||||
|
||||
return (qAbs(currentPoint.x() - dragPoint.x()) >= 5 ||
|
||||
qAbs(currentPoint.y() - dragPoint.y()) >= 5);
|
||||
return (qAbs(currentPoint.x() - dragPoint.x()) >= 1 ||
|
||||
qAbs(currentPoint.y() - dragPoint.y()) >= 1);
|
||||
}
|
||||
|
||||
QPixmap dragPixmap() const {
|
||||
@ -94,10 +96,12 @@ QuickPluginWindow::QuickPluginWindow(QWidget *parent)
|
||||
, m_mainLayout(new QBoxLayout(QBoxLayout::RightToLeft, this))
|
||||
, m_position(Dock::Position::Bottom)
|
||||
, m_dragInfo(new DragInfo)
|
||||
, m_dragEnterMimeData(nullptr)
|
||||
{
|
||||
initUi();
|
||||
initConnection();
|
||||
|
||||
topLevelWidget()->installEventFilter(this);
|
||||
installEventFilter(this);
|
||||
setAcceptDrops(true);
|
||||
setMouseTracking(true);
|
||||
@ -197,6 +201,22 @@ PluginsItemInterface *QuickPluginWindow::findQuickSettingItem(const QPoint &mous
|
||||
|
||||
bool QuickPluginWindow::eventFilter(QObject *watched, QEvent *event)
|
||||
{
|
||||
if (watched == topLevelWidget()) {
|
||||
switch (event->type()) {
|
||||
case QEvent::DragEnter: {
|
||||
QDragEnterEvent *dragEvent = static_cast<QDragEnterEvent *>(event);
|
||||
dragEnterEvent(dragEvent);
|
||||
break;
|
||||
}
|
||||
case QEvent::DragLeave: {
|
||||
QDragLeaveEvent *dragEvent = static_cast<QDragLeaveEvent *>(event);
|
||||
dragLeaveEvent(dragEvent);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
switch (event->type()) {
|
||||
case QEvent::MouseButtonPress: {
|
||||
QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
|
||||
@ -223,7 +243,7 @@ bool QuickPluginWindow::eventFilter(QObject *watched, QEvent *event)
|
||||
if (m_dragInfo->canDrag(mouseEvent->pos()))
|
||||
break;
|
||||
|
||||
showPopup(qobject_cast<QuickDockItem *>(watched));
|
||||
showPopup(m_dragInfo->dockItem);
|
||||
} while (false);
|
||||
m_dragInfo->reset();
|
||||
|
||||
@ -241,7 +261,13 @@ bool QuickPluginWindow::eventFilter(QObject *watched, QEvent *event)
|
||||
break;
|
||||
}
|
||||
case QEvent::Drop: {
|
||||
Q_EMIT requestDrop(static_cast<QDropEvent *>(event));
|
||||
m_dragEnterMimeData = nullptr;
|
||||
QDropEvent *dropEvent = static_cast<QDropEvent *>(event);
|
||||
if (qobject_cast<QuickSettingContainer *>(dropEvent->source())) {
|
||||
const QuickPluginMimeData *mimeData = qobject_cast<const QuickPluginMimeData *>(dropEvent->mimeData());
|
||||
if (mimeData)
|
||||
dragPlugin(mimeData->pluginItemInterface());
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
@ -250,6 +276,35 @@ bool QuickPluginWindow::eventFilter(QObject *watched, QEvent *event)
|
||||
return QWidget::eventFilter(watched, event);
|
||||
}
|
||||
|
||||
void QuickPluginWindow::dragEnterEvent(QDragEnterEvent *event)
|
||||
{
|
||||
m_dragEnterMimeData = const_cast<QuickPluginMimeData *>(qobject_cast<const QuickPluginMimeData *>(event->mimeData()));
|
||||
if (m_dragEnterMimeData) {
|
||||
QIcon icon = m_dragEnterMimeData->pluginItemInterface()->icon(DockPart::QuickShow);
|
||||
QuickIconDrag *drag = qobject_cast<QuickIconDrag *>(m_dragEnterMimeData->drag());
|
||||
if (drag && !icon.isNull()) {
|
||||
QPixmap pixmap = icon.pixmap(QSize(16, 16));
|
||||
drag->updatePixmap(pixmap);
|
||||
}
|
||||
event->accept();
|
||||
} else {
|
||||
event->ignore();
|
||||
}
|
||||
}
|
||||
|
||||
void QuickPluginWindow::dragLeaveEvent(QDragLeaveEvent *event)
|
||||
{
|
||||
if (m_dragEnterMimeData) {
|
||||
QPoint mousePos = topLevelWidget()->mapFromGlobal(QCursor::pos());
|
||||
QuickIconDrag *drag = static_cast<QuickIconDrag *>(m_dragEnterMimeData->drag());
|
||||
if (!topLevelWidget()->rect().contains(mousePos) && drag) {
|
||||
static_cast<QuickIconDrag *>(m_dragEnterMimeData->drag())->useSourcePixmap();
|
||||
}
|
||||
m_dragEnterMimeData = nullptr;
|
||||
}
|
||||
event->accept();
|
||||
}
|
||||
|
||||
void QuickPluginWindow::onRequestUpdate()
|
||||
{
|
||||
bool countChanged = false;
|
||||
@ -364,24 +419,22 @@ void QuickPluginWindow::startDrag()
|
||||
return;
|
||||
|
||||
PluginsItemInterface *moveItem = m_dragInfo->dockItem->pluginItem();
|
||||
AppDrag *drag = new AppDrag(this, new QuickDragWidget);
|
||||
QuickPluginMimeData *mimedata = new QuickPluginMimeData(moveItem);
|
||||
//AppDrag *drag = new AppDrag(this, new QuickDragWidget);
|
||||
QDrag *drag = new QDrag(this);
|
||||
QuickPluginMimeData *mimedata = new QuickPluginMimeData(moveItem, drag);
|
||||
drag->setMimeData(mimedata);
|
||||
drag->appDragWidget()->setDockInfo(m_position, QRect(mapToGlobal(pos()), size()));
|
||||
QPixmap dragPixmap = m_dragInfo->dragPixmap();
|
||||
drag->setPixmap(dragPixmap);
|
||||
|
||||
drag->setHotSpot(QPoint(0, 0));
|
||||
drag->setHotSpot(dragPixmap.rect().center());
|
||||
//connect(static_cast<QuickDragWidget *>(drag->appDragWidget()), &QuickDragWidget::requestDropItem, this, &QuickPluginWindow::onPluginDropItem);
|
||||
//connect(static_cast<QuickDragWidget *>(drag->appDragWidget()), &QuickDragWidget::requestDragMove, this, &QuickPluginWindow::onPluginDragMove);
|
||||
|
||||
connect(drag->appDragWidget(), &AppDragWidget::requestSplitWindow, this, [ this, moveItem ] {
|
||||
QuickPluginModel::instance()->removePlugin(moveItem);
|
||||
Q_EMIT itemCountChanged();
|
||||
});
|
||||
|
||||
connect(static_cast<QuickDragWidget *>(drag->appDragWidget()), &QuickDragWidget::requestDropItem, this, &QuickPluginWindow::onPluginDropItem);
|
||||
connect(static_cast<QuickDragWidget *>(drag->appDragWidget()), &QuickDragWidget::requestDragMove, this, &QuickPluginWindow::onPluginDragMove);
|
||||
|
||||
drag->exec(Qt::MoveAction | Qt::CopyAction);
|
||||
drag->exec(Qt::CopyAction);
|
||||
// 获取当前鼠标在任务栏快捷图标区域的位置
|
||||
QPoint currentPoint = mapFromGlobal(QCursor::pos());
|
||||
// 获取区域图标插入的位置
|
||||
QuickPluginModel::instance()->addPlugin(mimedata->pluginItemInterface(), getDropIndex(currentPoint));
|
||||
}
|
||||
|
||||
QuickDockItem *QuickPluginWindow::getDockItemByPlugin(PluginsItemInterface *item)
|
||||
@ -447,62 +500,69 @@ void QuickPluginWindow::showPopup(QuickDockItem *item, PluginsItemInterface *ite
|
||||
|
||||
QuickSettingContainer *container = static_cast<QuickSettingContainer *>(popWindow->getContent());
|
||||
container->showPage(childPage, itemInter, canBack);
|
||||
popWindow->raise();
|
||||
}
|
||||
|
||||
QList<QuickDockItem *> QuickPluginWindow::quickDockItems()
|
||||
{
|
||||
QList<QuickDockItem *> dockItems;
|
||||
for (int i = 0; i < m_mainLayout->count(); i++) {
|
||||
QLayoutItem *layoutItem = m_mainLayout->itemAt(i);
|
||||
if (!layoutItem)
|
||||
continue;
|
||||
|
||||
QuickDockItem *dockedItem = qobject_cast<QuickDockItem *>(layoutItem->widget());
|
||||
if (!dockedItem)
|
||||
continue;
|
||||
|
||||
dockItems << dockedItem;
|
||||
}
|
||||
|
||||
return dockItems;
|
||||
}
|
||||
|
||||
int QuickPluginWindow::getDropIndex(QPoint point)
|
||||
{
|
||||
QList<QuickDockItem *> dockedItems = quickDockItems();
|
||||
QuickDockItem *targetItem = getActiveDockItem(point);
|
||||
if (targetItem) {
|
||||
for (int i = 0; i < m_mainLayout->count(); i++) {
|
||||
QLayoutItem *layoutItem = m_mainLayout->itemAt(i);
|
||||
if (!layoutItem)
|
||||
continue;
|
||||
|
||||
if (layoutItem->widget() == targetItem)
|
||||
for (int i = 0; i < dockedItems.count(); i++) {
|
||||
if (dockedItems[i] == targetItem)
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
// 上下方向从右向左排列
|
||||
QList<PluginsItemInterface *> dockItemInter = QuickPluginModel::instance()->dockedPluginItems();
|
||||
if (m_position == Dock::Position::Top || m_position == Dock::Position::Bottom) {
|
||||
for (int i = 0; i < m_mainLayout->count() - 1; i++) {
|
||||
QLayoutItem *layoutBefore = m_mainLayout->itemAt(i);
|
||||
QLayoutItem *layoutItem = m_mainLayout->itemAt(i + 1);
|
||||
if (!layoutBefore || !layoutItem)
|
||||
continue;
|
||||
|
||||
QuickDockItem *dockBeforeItem = qobject_cast<QuickDockItem *>(layoutBefore->widget());
|
||||
QuickDockItem *dockItem = qobject_cast<QuickDockItem *>(layoutItem->widget());
|
||||
if (dockItem->canInsert())
|
||||
// 上下方向从右向左排列
|
||||
for (int i = 0; i < dockItemInter.count() - 1; i++) {
|
||||
QuickDockItem *dockBeforeItem = dockedItems[i];
|
||||
QuickDockItem *dockItem = dockedItems[i + 1];
|
||||
if (!dockItem->canInsert())
|
||||
continue;
|
||||
|
||||
if (dockBeforeItem->geometry().x() > point.x() && dockItem->geometry().right() < point.x())
|
||||
return i;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < m_mainLayout->count() - 1; i++) {
|
||||
QLayoutItem *layoutBefore = m_mainLayout->itemAt(i);
|
||||
QLayoutItem *layoutItem = m_mainLayout->itemAt(i + 1);
|
||||
if (!layoutBefore || !layoutItem)
|
||||
continue;
|
||||
} else {
|
||||
// 左右方向从下向上排列
|
||||
for (int i = 0; i < dockItemInter.count() - 1; i++) {
|
||||
QuickDockItem *dockBeforeItem = dockedItems[i];
|
||||
QuickDockItem *dockItem = dockedItems[i + 1];
|
||||
if (!dockItem->canInsert())
|
||||
continue;
|
||||
|
||||
QuickDockItem *dockBeforeItem = qobject_cast<QuickDockItem *>(layoutBefore->widget());
|
||||
if (dockBeforeItem->canInsert())
|
||||
break;
|
||||
|
||||
QuickDockItem *dockItem = qobject_cast<QuickDockItem *>(layoutItem->widget());
|
||||
|
||||
// 从上向下排列
|
||||
if (dockBeforeItem->geometry().bottom() < point.y() && dockItem->geometry().top() > point.y())
|
||||
return i;
|
||||
if (dockBeforeItem->geometry().bottom() > point.y() && dockItem->geometry().top() < point.y())
|
||||
return i;
|
||||
}
|
||||
}
|
||||
// 如果都没有找到,直接插入到最后
|
||||
return -1;
|
||||
}
|
||||
|
||||
void QuickPluginWindow::onPluginDropItem(QDropEvent *event)
|
||||
/*void QuickPluginWindow::onPluginDropItem(QDropEvent *event)
|
||||
{
|
||||
const QuickPluginMimeData *data = qobject_cast<const QuickPluginMimeData *>(event->mimeData());
|
||||
if (!data)
|
||||
@ -512,7 +572,7 @@ void QuickPluginWindow::onPluginDropItem(QDropEvent *event)
|
||||
QPoint currentPoint = mapFromGlobal(QCursor::pos());
|
||||
// 获取区域图标插入的位置
|
||||
QuickPluginModel::instance()->addPlugin(data->pluginItemInterface(), getDropIndex(currentPoint));
|
||||
}
|
||||
}*/
|
||||
|
||||
void QuickPluginWindow::onPluginDragMove(QDragMoveEvent *event)
|
||||
{
|
||||
@ -549,6 +609,11 @@ void QuickPluginWindow::onPluginDragMove(QDragMoveEvent *event)
|
||||
event->accept();
|
||||
}
|
||||
|
||||
void QuickPluginWindow::dragMoveEvent(QDragMoveEvent *event)
|
||||
{
|
||||
event->accept();
|
||||
}
|
||||
|
||||
void QuickPluginWindow::initConnection()
|
||||
{
|
||||
QuickPluginModel *model = QuickPluginModel::instance();
|
||||
@ -571,7 +636,6 @@ QuickDockItem::QuickDockItem(PluginsItemInterface *pluginItem, const QString &it
|
||||
, m_contextMenu(new QMenu(this))
|
||||
, m_tipParent(nullptr)
|
||||
, m_mainLayout(nullptr)
|
||||
, m_canInsert(QuickSettingController::instance()->hasFlag(pluginItem, PluginFlag::Attribute_CanInsert))
|
||||
, m_dockItemParent(nullptr)
|
||||
{
|
||||
initUi();
|
||||
@ -595,7 +659,7 @@ PluginsItemInterface *QuickDockItem::pluginItem()
|
||||
|
||||
bool QuickDockItem::canInsert() const
|
||||
{
|
||||
return m_canInsert;
|
||||
return (m_pluginItem->flags() & PluginFlag::Attribute_CanInsert);
|
||||
}
|
||||
|
||||
void QuickDockItem::hideToolTip()
|
||||
|
@ -36,6 +36,7 @@ class QBoxLayout;
|
||||
class QuickDockItem;
|
||||
class DockPopupWindow;
|
||||
class QMenu;
|
||||
class QuickPluginMimeData;
|
||||
enum class DockPart;
|
||||
|
||||
namespace Dtk { namespace Gui { class DRegionMonitor; }
|
||||
@ -59,14 +60,16 @@ public:
|
||||
|
||||
Q_SIGNALS:
|
||||
void itemCountChanged();
|
||||
void requestDrop(QDropEvent *dropEvent);
|
||||
|
||||
protected:
|
||||
bool eventFilter(QObject *watched, QEvent *event) override;
|
||||
void dragEnterEvent(QDragEnterEvent *event) override;
|
||||
void dragLeaveEvent(QDragLeaveEvent *event) override;
|
||||
void dragMoveEvent(QDragMoveEvent *event) override;
|
||||
|
||||
private Q_SLOTS:
|
||||
void onRequestUpdate();
|
||||
void onPluginDropItem(QDropEvent *event);
|
||||
//void onPluginDropItem(QDropEvent *event);
|
||||
void onPluginDragMove(QDragMoveEvent *event);
|
||||
void onUpdatePlugin(PluginsItemInterface *itemInter, const DockPart &dockPart);
|
||||
void onRequestAppletShow(PluginsItemInterface * itemInter, const QString &itemKey);
|
||||
@ -81,11 +84,13 @@ private:
|
||||
QuickDockItem *getDockItemByPlugin(PluginsItemInterface *item);
|
||||
QuickDockItem *getActiveDockItem(QPoint point) const;
|
||||
void showPopup(QuickDockItem *item, PluginsItemInterface *itemInter = nullptr, QWidget *childPage = nullptr);
|
||||
QList<QuickDockItem *> quickDockItems();
|
||||
|
||||
private:
|
||||
QBoxLayout *m_mainLayout;
|
||||
Dock::Position m_position;
|
||||
struct DragInfo *m_dragInfo;
|
||||
QuickPluginMimeData *m_dragEnterMimeData;
|
||||
};
|
||||
|
||||
// 用于在任务栏上显示的插件
|
||||
@ -131,7 +136,6 @@ private:
|
||||
QMenu *m_contextMenu;
|
||||
QWidget *m_tipParent;
|
||||
QHBoxLayout *m_mainLayout;
|
||||
bool m_canInsert;
|
||||
QWidget *m_dockItemParent;
|
||||
};
|
||||
|
||||
|
@ -26,6 +26,7 @@
|
||||
#include "slidercontainer.h"
|
||||
#include "pluginchildpage.h"
|
||||
#include "utils.h"
|
||||
#include "quickdragcore.h"
|
||||
|
||||
#include <DListView>
|
||||
#include <DStyle>
|
||||
@ -35,6 +36,9 @@
|
||||
#include <QMetaObject>
|
||||
#include <QStackedLayout>
|
||||
#include <QMouseEvent>
|
||||
#include <QLabel>
|
||||
#include <QBitmap>
|
||||
#include <QPainterPath>
|
||||
|
||||
DWIDGET_USE_NAMESPACE
|
||||
|
||||
@ -132,8 +136,7 @@ DockPopupWindow *QuickSettingContainer::popWindow()
|
||||
m_popWindow->setArrowHeight(10);
|
||||
m_popWindow->setArrowDirection(getDirection(m_position));
|
||||
m_popWindow->setContent(new QuickSettingContainer(m_popWindow));
|
||||
if (Utils::IS_WAYLAND_DISPLAY)
|
||||
m_popWindow->setWindowFlags(m_popWindow->windowFlags() | Qt::FramelessWindowHint);
|
||||
m_popWindow->setWindowFlags(Qt::FramelessWindowHint | Qt::Tool);
|
||||
return m_popWindow;
|
||||
}
|
||||
|
||||
@ -181,17 +184,6 @@ bool QuickSettingContainer::eventFilter(QObject *watched, QEvent *event)
|
||||
return QWidget::eventFilter(watched, event);
|
||||
}
|
||||
|
||||
QPoint QuickSettingContainer::hotSpot(const QPixmap &pixmap)
|
||||
{
|
||||
if (m_position == Dock::Position::Left)
|
||||
return QPoint(0, pixmap.height());
|
||||
|
||||
if (m_position == Dock::Position::Top)
|
||||
return QPoint(pixmap.width(), 0);
|
||||
|
||||
return QPoint(pixmap.width(), pixmap.height());
|
||||
}
|
||||
|
||||
void QuickSettingContainer::appendPlugin(PluginsItemInterface *itemInter, bool needLayout)
|
||||
{
|
||||
QuickSettingItem *quickItem = QuickSettingFactory::createQuickWidget(itemInter);
|
||||
@ -259,24 +251,14 @@ void QuickSettingContainer::mouseMoveEvent(QMouseEvent *event)
|
||||
QPoint pointCurrent = event->pos();
|
||||
if (qAbs(m_dragInfo->dragPosition.x() - pointCurrent.x()) > 5
|
||||
|| qAbs(m_dragInfo->dragPosition.y() - pointCurrent.y()) > 5) {
|
||||
|
||||
QDrag *drag = new QDrag(this);
|
||||
QuickSettingItem *moveItem = qobject_cast<QuickSettingItem *>(m_dragInfo->dragItem);
|
||||
QuickPluginMimeData *mimedata = new QuickPluginMimeData(m_dragInfo->pluginInter);
|
||||
QuickIconDrag *drag = new QuickIconDrag(this, moveItem->dragPixmap());
|
||||
QuickPluginMimeData *mimedata = new QuickPluginMimeData(m_dragInfo->pluginInter, drag);
|
||||
drag->setMimeData(mimedata);
|
||||
if (moveItem) {
|
||||
QPixmap dragPixmap = moveItem->dragPixmap();
|
||||
drag->setPixmap(dragPixmap);
|
||||
drag->setHotSpot(hotSpot(dragPixmap));
|
||||
} else {
|
||||
// 如果拖动的是声音等插件
|
||||
QPixmap dragPixmap = m_dragInfo->dragItem->grab();
|
||||
drag->setPixmap(dragPixmap);
|
||||
drag->setHotSpot(hotSpot(dragPixmap));
|
||||
}
|
||||
drag->setDragHotPot(m_dragInfo->dragPosition);
|
||||
|
||||
m_dragInfo->reset();
|
||||
drag->exec(Qt::MoveAction | Qt::CopyAction);
|
||||
drag->exec(Qt::CopyAction);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -77,8 +77,6 @@ private:
|
||||
void updateItemLayout();
|
||||
// 调整全列插件的位置
|
||||
void updateFullItemLayout();
|
||||
// 获取拖动图标的热点
|
||||
QPoint hotSpot(const QPixmap &pixmap);
|
||||
// 插入插件
|
||||
void appendPlugin(PluginsItemInterface *itemInter, bool needLayout = true);
|
||||
|
||||
@ -98,17 +96,4 @@ private:
|
||||
PluginsItemInterface *m_childShowPlugin;
|
||||
};
|
||||
|
||||
class QuickPluginMimeData : public QMimeData
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
explicit QuickPluginMimeData(PluginsItemInterface *item) : QMimeData(), m_item(item) {}
|
||||
~QuickPluginMimeData() {}
|
||||
PluginsItemInterface *pluginItemInterface() const { return m_item; }
|
||||
|
||||
private:
|
||||
PluginsItemInterface *m_item;
|
||||
};
|
||||
|
||||
#endif // PLUGINCONTAINER_H
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "systempluginwindow.h"
|
||||
#include "datetimedisplayer.h"
|
||||
#include "expandiconwidget.h"
|
||||
#include "quickdragcore.h"
|
||||
|
||||
#include <DGuiApplicationHelper>
|
||||
#include <DRegionMonitor>
|
||||
@ -40,7 +41,6 @@
|
||||
#include <QPainter>
|
||||
#include <QPainterPath>
|
||||
|
||||
#define MAXFIXEDSIZE 999999
|
||||
#define CRITLCALHEIGHT 42
|
||||
#define CONTENTSPACE 7
|
||||
// 高度小于等于这个值的时候,间距最小值
|
||||
|
Loading…
x
Reference in New Issue
Block a user