feat: 支持从快捷面板拖动图标驻留到任务栏

增加从快捷面板拖动应用到任务栏的功能

Log:
Influence: 从快捷面板拖动图标到任务栏,观察是否驻留在任务栏
Bug: https://pms.uniontech.com/bug-view-171517.html
Change-Id: I3351be282ef8d3afbb55f227fc6ae8ce16c78a97
This commit is contained in:
donghualin 2022-12-12 10:30:44 +00:00
parent 75a9312fcb
commit 541cdf60e7
13 changed files with 435 additions and 140 deletions

View File

@ -73,6 +73,7 @@ target_include_directories(${BIN_NAME} PUBLIC
window/components
window/tray
window/tray/widgets
drag
xcb
../plugins/tray
../plugins/show-desktop

View 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());
}

View 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

View File

@ -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();

View File

@ -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

View File

@ -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);

View File

@ -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;
}

View File

@ -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;

View File

@ -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()

View File

@ -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;
};

View File

@ -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);
}
}

View File

@ -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

View File

@ -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
// 高度小于等于这个值的时候,间距最小值