fix(panel): 暂存优先模式;工厂自身接收拖拽;去掉 drop 提示
- 暂存区非空且未拖拽时只显示暂存列表,隐藏传送门与内容工厂并收窄窗口 - 内容工厂自身区域拖入也会展开动作 - 面板矩形改用屏幕可用区 + 边距计算(layer-shell 下 mapToGlobal 不可靠) - 离开概览只复位传送门状态,不关闭面板;125ms - 移除“在哪里 drop”提示
This commit is contained in:
@@ -88,6 +88,9 @@ bool App::init(bool daemon, bool forceShow, bool showTodo, bool showChat)
|
||||
return;
|
||||
}
|
||||
m_dragging = true;
|
||||
if (m_panel) {
|
||||
m_panel->setDragging(true);
|
||||
}
|
||||
if (!m_model->isEmpty()) {
|
||||
if (m_panel && m_panel->isVisible()) {
|
||||
m_panel->suppressPortalIfUnderCursor();
|
||||
@@ -107,6 +110,7 @@ bool App::init(bool daemon, bool forceShow, bool showTodo, bool showChat)
|
||||
m_dragging = false;
|
||||
if (m_panel) {
|
||||
m_panel->stopPortalSuppression();
|
||||
m_panel->setDragging(false);
|
||||
}
|
||||
if (m_model->isEmpty() && m_panel && m_panel->isVisible()) {
|
||||
m_panel->dismiss();
|
||||
|
||||
@@ -1281,9 +1281,6 @@ void ChatWindow::startConversationWith(const QString &text, const QStringList &f
|
||||
}
|
||||
}
|
||||
m_input->setFocus();
|
||||
|
||||
m_status->setText(tr("拖到左侧空白处=新对话,拖到左侧会话=追加到该会话,拖到右侧对话区=发给当前会话"));
|
||||
m_status->show();
|
||||
}
|
||||
|
||||
void ChatWindow::activateForAsk()
|
||||
|
||||
@@ -317,6 +317,45 @@ void ContentFactory::paintEvent(QPaintEvent *event)
|
||||
painter.drawPath(path);
|
||||
}
|
||||
|
||||
void ContentFactory::dragEnterEvent(QDragEnterEvent *event)
|
||||
{
|
||||
if (!event->mimeData() ||
|
||||
!(event->mimeData()->hasUrls() || event->mimeData()->hasText() ||
|
||||
event->mimeData()->hasImage())) {
|
||||
event->ignore();
|
||||
return;
|
||||
}
|
||||
Q_EMIT dragContent(event->mimeData());
|
||||
Q_EMIT dragActivity();
|
||||
event->acceptProposedAction();
|
||||
}
|
||||
|
||||
void ContentFactory::dragMoveEvent(QDragMoveEvent *event)
|
||||
{
|
||||
if (event->mimeData() &&
|
||||
(event->mimeData()->hasUrls() || event->mimeData()->hasText() ||
|
||||
event->mimeData()->hasImage())) {
|
||||
Q_EMIT dragContent(event->mimeData());
|
||||
Q_EMIT dragActivity();
|
||||
event->acceptProposedAction();
|
||||
return;
|
||||
}
|
||||
event->ignore();
|
||||
}
|
||||
|
||||
void ContentFactory::dragLeaveEvent(QDragLeaveEvent *event)
|
||||
{
|
||||
Q_UNUSED(event)
|
||||
Q_EMIT dragActivity();
|
||||
}
|
||||
|
||||
void ContentFactory::dropEvent(QDropEvent *event)
|
||||
{
|
||||
if (event->mimeData()) {
|
||||
event->acceptProposedAction();
|
||||
}
|
||||
}
|
||||
|
||||
bool ContentFactory::eventFilter(QObject *watched, QEvent *event)
|
||||
{
|
||||
if (event->type() == QEvent::DragEnter || event->type() == QEvent::DragMove) {
|
||||
|
||||
@@ -33,6 +33,7 @@ signals:
|
||||
void actionRequested(const QString &id, const DropContent &content);
|
||||
void heightChanged();
|
||||
void dragActivity();
|
||||
void dragContent(const QMimeData *mime);
|
||||
void askRequested();
|
||||
void askDropped(const QMimeData *mime);
|
||||
|
||||
@@ -42,6 +43,10 @@ public:
|
||||
protected:
|
||||
void paintEvent(QPaintEvent *event) override;
|
||||
bool eventFilter(QObject *watched, QEvent *event) override;
|
||||
void dragEnterEvent(QDragEnterEvent *event) override;
|
||||
void dragMoveEvent(QDragMoveEvent *event) override;
|
||||
void dragLeaveEvent(QDragLeaveEvent *event) override;
|
||||
void dropEvent(QDropEvent *event) override;
|
||||
|
||||
private:
|
||||
void rebuild();
|
||||
|
||||
@@ -50,6 +50,9 @@ PortalClient::PortalClient(QObject *parent)
|
||||
bus.connect(QString::fromLatin1(kService), QString::fromLatin1(kPath),
|
||||
QString::fromLatin1(kInterface), QStringLiteral("PortalDropped"), this,
|
||||
SLOT(onDropped(QString, bool)));
|
||||
bus.connect(QString::fromLatin1(kService), QString::fromLatin1(kPath),
|
||||
QString::fromLatin1(kInterface), QStringLiteral("PortalClosed"), this,
|
||||
SLOT(onPortalClosed()));
|
||||
}
|
||||
|
||||
bool PortalClient::beginPortal(const QRect &panelRect)
|
||||
@@ -93,6 +96,11 @@ void PortalClient::onDragStarted(const QString &mimeTypes)
|
||||
Q_EMIT dragStarted(mimeTypes);
|
||||
}
|
||||
|
||||
void PortalClient::onPortalClosed()
|
||||
{
|
||||
Q_EMIT portalClosed();
|
||||
}
|
||||
|
||||
void PortalClient::onDragEnded()
|
||||
{
|
||||
Q_EMIT dragEnded();
|
||||
|
||||
@@ -33,11 +33,13 @@ public:
|
||||
signals:
|
||||
void dragStarted(const QString &mimeTypes);
|
||||
void dragEnded();
|
||||
void portalClosed();
|
||||
void dropped(const QString &uuid, bool accepted);
|
||||
|
||||
private slots:
|
||||
void onDragStarted(const QString &mimeTypes);
|
||||
void onDragEnded();
|
||||
void onPortalClosed();
|
||||
void onDropped(const QString &uuid, bool accepted);
|
||||
|
||||
private:
|
||||
|
||||
+42
-3
@@ -784,6 +784,7 @@ PortalPanel::PortalPanel(StagingModel *model, QWidget *parent)
|
||||
if (m_countLabel) {
|
||||
m_countLabel->setText(tr("%1 项").arg(m_model->count()));
|
||||
}
|
||||
updateMode();
|
||||
refreshLayout();
|
||||
});
|
||||
connect(m_model, &StagingModel::countChanged, m_view->viewport(),
|
||||
@@ -873,7 +874,15 @@ void PortalPanel::setupUi()
|
||||
|
||||
connect(m_zone, &PortalZone::portalRequested, this, [this]() {
|
||||
PortalClient *portal = PortalClient::instance();
|
||||
if (portal->beginPortal(QRect(mapToGlobal(QPoint(0, 0)), size()))) {
|
||||
QScreen *scr = screen() ? screen() : QGuiApplication::primaryScreen();
|
||||
QRect panelRect = geometry();
|
||||
if (scr) {
|
||||
const QRect avail = scr->availableGeometry();
|
||||
panelRect = QRect(avail.x() + avail.width() - width() - m_rightMargin,
|
||||
avail.y() + avail.height() - height() - m_bottomMargin,
|
||||
width(), height());
|
||||
}
|
||||
if (portal->beginPortal(panelRect)) {
|
||||
m_zone->setPortalActive(true);
|
||||
m_zone->showMessage(tr("移动到目标窗口上松手"));
|
||||
} else {
|
||||
@@ -886,6 +895,8 @@ void PortalPanel::setupUi()
|
||||
});
|
||||
connect(PortalClient::instance(), &PortalClient::dragEnded, this,
|
||||
[this]() { m_zone->setPortalActive(false); });
|
||||
connect(PortalClient::instance(), &PortalClient::portalClosed, this,
|
||||
[this]() { m_zone->setPortalActive(false); });
|
||||
|
||||
auto *right = new QVBoxLayout;
|
||||
right->setContentsMargins(0, 0, 0, 0);
|
||||
@@ -990,6 +1001,7 @@ void PortalPanel::setupUi()
|
||||
Q_EMIT askWithContent(text, files);
|
||||
});
|
||||
connect(m_factory, &ContentFactory::heightChanged, this, [this]() { refreshLayout(); });
|
||||
connect(m_factory, &ContentFactory::dragContent, this, &PortalPanel::noteDragContent);
|
||||
connect(m_factory, &ContentFactory::dragActivity, this, [this]() {
|
||||
if (m_factoryTimer) {
|
||||
m_factoryTimer->start();
|
||||
@@ -1002,6 +1014,32 @@ void PortalPanel::refreshLayout()
|
||||
updateGeometryForContent();
|
||||
}
|
||||
|
||||
void PortalPanel::setDragging(bool dragging)
|
||||
{
|
||||
if (m_dragging == dragging) {
|
||||
return;
|
||||
}
|
||||
m_dragging = dragging;
|
||||
updateMode();
|
||||
}
|
||||
|
||||
void PortalPanel::updateMode()
|
||||
{
|
||||
const bool stagingOnly = !m_dragging && m_model && m_model->count() > 0;
|
||||
if (stagingOnly == m_stagingOnly) {
|
||||
return;
|
||||
}
|
||||
m_stagingOnly = stagingOnly;
|
||||
if (m_zone) {
|
||||
m_zone->setVisible(!stagingOnly);
|
||||
}
|
||||
if (m_factory) {
|
||||
m_factory->setVisible(!stagingOnly);
|
||||
}
|
||||
setFixedWidth(stagingOnly ? 360 : kPanelWidth);
|
||||
refreshLayout();
|
||||
}
|
||||
|
||||
void PortalPanel::updateGeometryForContent()
|
||||
{
|
||||
QScreen *scr = screen();
|
||||
@@ -1020,10 +1058,11 @@ void PortalPanel::updateGeometryForContent()
|
||||
const int selectionHeight = (m_selectionBar && m_selectionBar->isVisible()) ? 32 : 0;
|
||||
/* The factory always occupies the same strip, so neither the panel size nor
|
||||
* its position changes when a drag starts or ends. */
|
||||
const int factoryHeight = m_factory ? m_factory->sizeHint().height() + 6 : 0;
|
||||
const int factoryHeight =
|
||||
(!m_stagingOnly && m_factory) ? m_factory->sizeHint().height() + 6 : 0;
|
||||
const int totalHeight =
|
||||
kMargin * 2 + headerHeight + 6 + selectionHeight + listHeight + factoryHeight;
|
||||
resize(kPanelWidth, totalHeight);
|
||||
resize(m_stagingOnly ? 360 : kPanelWidth, totalHeight);
|
||||
}
|
||||
|
||||
void PortalPanel::noteDragContent(const QMimeData *mime)
|
||||
|
||||
@@ -34,6 +34,7 @@ public:
|
||||
void refreshLayout();
|
||||
void popup();
|
||||
void suppressPortalIfUnderCursor();
|
||||
void setDragging(bool dragging);
|
||||
void stopPortalSuppression();
|
||||
void dismiss();
|
||||
|
||||
@@ -52,6 +53,7 @@ private:
|
||||
void setupUi();
|
||||
void setupWindow();
|
||||
void updateGeometryForContent();
|
||||
void updateMode();
|
||||
void updateSelectionBar();
|
||||
void noteDragContent(const QMimeData *mime);
|
||||
void noteDragFinished();
|
||||
@@ -79,6 +81,8 @@ private:
|
||||
int m_bottomMargin = 16;
|
||||
int m_manualListHeight = 0;
|
||||
QTimer *m_suppressWatch = nullptr;
|
||||
bool m_stagingOnly = false;
|
||||
bool m_dragging = false;
|
||||
bool m_fixedPosition = true;
|
||||
bool m_fixedSize = false;
|
||||
int m_dragMode = 0; // 0 none, 1 move, 2 resize
|
||||
|
||||
Reference in New Issue
Block a user