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;
|
return;
|
||||||
}
|
}
|
||||||
m_dragging = true;
|
m_dragging = true;
|
||||||
|
if (m_panel) {
|
||||||
|
m_panel->setDragging(true);
|
||||||
|
}
|
||||||
if (!m_model->isEmpty()) {
|
if (!m_model->isEmpty()) {
|
||||||
if (m_panel && m_panel->isVisible()) {
|
if (m_panel && m_panel->isVisible()) {
|
||||||
m_panel->suppressPortalIfUnderCursor();
|
m_panel->suppressPortalIfUnderCursor();
|
||||||
@@ -107,6 +110,7 @@ bool App::init(bool daemon, bool forceShow, bool showTodo, bool showChat)
|
|||||||
m_dragging = false;
|
m_dragging = false;
|
||||||
if (m_panel) {
|
if (m_panel) {
|
||||||
m_panel->stopPortalSuppression();
|
m_panel->stopPortalSuppression();
|
||||||
|
m_panel->setDragging(false);
|
||||||
}
|
}
|
||||||
if (m_model->isEmpty() && m_panel && m_panel->isVisible()) {
|
if (m_model->isEmpty() && m_panel && m_panel->isVisible()) {
|
||||||
m_panel->dismiss();
|
m_panel->dismiss();
|
||||||
|
|||||||
@@ -1281,9 +1281,6 @@ void ChatWindow::startConversationWith(const QString &text, const QStringList &f
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
m_input->setFocus();
|
m_input->setFocus();
|
||||||
|
|
||||||
m_status->setText(tr("拖到左侧空白处=新对话,拖到左侧会话=追加到该会话,拖到右侧对话区=发给当前会话"));
|
|
||||||
m_status->show();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ChatWindow::activateForAsk()
|
void ChatWindow::activateForAsk()
|
||||||
|
|||||||
@@ -317,6 +317,45 @@ void ContentFactory::paintEvent(QPaintEvent *event)
|
|||||||
painter.drawPath(path);
|
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)
|
bool ContentFactory::eventFilter(QObject *watched, QEvent *event)
|
||||||
{
|
{
|
||||||
if (event->type() == QEvent::DragEnter || event->type() == QEvent::DragMove) {
|
if (event->type() == QEvent::DragEnter || event->type() == QEvent::DragMove) {
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ signals:
|
|||||||
void actionRequested(const QString &id, const DropContent &content);
|
void actionRequested(const QString &id, const DropContent &content);
|
||||||
void heightChanged();
|
void heightChanged();
|
||||||
void dragActivity();
|
void dragActivity();
|
||||||
|
void dragContent(const QMimeData *mime);
|
||||||
void askRequested();
|
void askRequested();
|
||||||
void askDropped(const QMimeData *mime);
|
void askDropped(const QMimeData *mime);
|
||||||
|
|
||||||
@@ -42,6 +43,10 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
void paintEvent(QPaintEvent *event) override;
|
void paintEvent(QPaintEvent *event) override;
|
||||||
bool eventFilter(QObject *watched, QEvent *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:
|
private:
|
||||||
void rebuild();
|
void rebuild();
|
||||||
|
|||||||
@@ -50,6 +50,9 @@ PortalClient::PortalClient(QObject *parent)
|
|||||||
bus.connect(QString::fromLatin1(kService), QString::fromLatin1(kPath),
|
bus.connect(QString::fromLatin1(kService), QString::fromLatin1(kPath),
|
||||||
QString::fromLatin1(kInterface), QStringLiteral("PortalDropped"), this,
|
QString::fromLatin1(kInterface), QStringLiteral("PortalDropped"), this,
|
||||||
SLOT(onDropped(QString, bool)));
|
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)
|
bool PortalClient::beginPortal(const QRect &panelRect)
|
||||||
@@ -93,6 +96,11 @@ void PortalClient::onDragStarted(const QString &mimeTypes)
|
|||||||
Q_EMIT dragStarted(mimeTypes);
|
Q_EMIT dragStarted(mimeTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PortalClient::onPortalClosed()
|
||||||
|
{
|
||||||
|
Q_EMIT portalClosed();
|
||||||
|
}
|
||||||
|
|
||||||
void PortalClient::onDragEnded()
|
void PortalClient::onDragEnded()
|
||||||
{
|
{
|
||||||
Q_EMIT dragEnded();
|
Q_EMIT dragEnded();
|
||||||
|
|||||||
@@ -33,11 +33,13 @@ public:
|
|||||||
signals:
|
signals:
|
||||||
void dragStarted(const QString &mimeTypes);
|
void dragStarted(const QString &mimeTypes);
|
||||||
void dragEnded();
|
void dragEnded();
|
||||||
|
void portalClosed();
|
||||||
void dropped(const QString &uuid, bool accepted);
|
void dropped(const QString &uuid, bool accepted);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void onDragStarted(const QString &mimeTypes);
|
void onDragStarted(const QString &mimeTypes);
|
||||||
void onDragEnded();
|
void onDragEnded();
|
||||||
|
void onPortalClosed();
|
||||||
void onDropped(const QString &uuid, bool accepted);
|
void onDropped(const QString &uuid, bool accepted);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|||||||
+42
-3
@@ -784,6 +784,7 @@ PortalPanel::PortalPanel(StagingModel *model, QWidget *parent)
|
|||||||
if (m_countLabel) {
|
if (m_countLabel) {
|
||||||
m_countLabel->setText(tr("%1 项").arg(m_model->count()));
|
m_countLabel->setText(tr("%1 项").arg(m_model->count()));
|
||||||
}
|
}
|
||||||
|
updateMode();
|
||||||
refreshLayout();
|
refreshLayout();
|
||||||
});
|
});
|
||||||
connect(m_model, &StagingModel::countChanged, m_view->viewport(),
|
connect(m_model, &StagingModel::countChanged, m_view->viewport(),
|
||||||
@@ -873,7 +874,15 @@ void PortalPanel::setupUi()
|
|||||||
|
|
||||||
connect(m_zone, &PortalZone::portalRequested, this, [this]() {
|
connect(m_zone, &PortalZone::portalRequested, this, [this]() {
|
||||||
PortalClient *portal = PortalClient::instance();
|
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->setPortalActive(true);
|
||||||
m_zone->showMessage(tr("移动到目标窗口上松手"));
|
m_zone->showMessage(tr("移动到目标窗口上松手"));
|
||||||
} else {
|
} else {
|
||||||
@@ -886,6 +895,8 @@ void PortalPanel::setupUi()
|
|||||||
});
|
});
|
||||||
connect(PortalClient::instance(), &PortalClient::dragEnded, this,
|
connect(PortalClient::instance(), &PortalClient::dragEnded, this,
|
||||||
[this]() { m_zone->setPortalActive(false); });
|
[this]() { m_zone->setPortalActive(false); });
|
||||||
|
connect(PortalClient::instance(), &PortalClient::portalClosed, this,
|
||||||
|
[this]() { m_zone->setPortalActive(false); });
|
||||||
|
|
||||||
auto *right = new QVBoxLayout;
|
auto *right = new QVBoxLayout;
|
||||||
right->setContentsMargins(0, 0, 0, 0);
|
right->setContentsMargins(0, 0, 0, 0);
|
||||||
@@ -990,6 +1001,7 @@ void PortalPanel::setupUi()
|
|||||||
Q_EMIT askWithContent(text, files);
|
Q_EMIT askWithContent(text, files);
|
||||||
});
|
});
|
||||||
connect(m_factory, &ContentFactory::heightChanged, this, [this]() { refreshLayout(); });
|
connect(m_factory, &ContentFactory::heightChanged, this, [this]() { refreshLayout(); });
|
||||||
|
connect(m_factory, &ContentFactory::dragContent, this, &PortalPanel::noteDragContent);
|
||||||
connect(m_factory, &ContentFactory::dragActivity, this, [this]() {
|
connect(m_factory, &ContentFactory::dragActivity, this, [this]() {
|
||||||
if (m_factoryTimer) {
|
if (m_factoryTimer) {
|
||||||
m_factoryTimer->start();
|
m_factoryTimer->start();
|
||||||
@@ -1002,6 +1014,32 @@ void PortalPanel::refreshLayout()
|
|||||||
updateGeometryForContent();
|
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()
|
void PortalPanel::updateGeometryForContent()
|
||||||
{
|
{
|
||||||
QScreen *scr = screen();
|
QScreen *scr = screen();
|
||||||
@@ -1020,10 +1058,11 @@ void PortalPanel::updateGeometryForContent()
|
|||||||
const int selectionHeight = (m_selectionBar && m_selectionBar->isVisible()) ? 32 : 0;
|
const int selectionHeight = (m_selectionBar && m_selectionBar->isVisible()) ? 32 : 0;
|
||||||
/* The factory always occupies the same strip, so neither the panel size nor
|
/* The factory always occupies the same strip, so neither the panel size nor
|
||||||
* its position changes when a drag starts or ends. */
|
* 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 =
|
const int totalHeight =
|
||||||
kMargin * 2 + headerHeight + 6 + selectionHeight + listHeight + factoryHeight;
|
kMargin * 2 + headerHeight + 6 + selectionHeight + listHeight + factoryHeight;
|
||||||
resize(kPanelWidth, totalHeight);
|
resize(m_stagingOnly ? 360 : kPanelWidth, totalHeight);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PortalPanel::noteDragContent(const QMimeData *mime)
|
void PortalPanel::noteDragContent(const QMimeData *mime)
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ public:
|
|||||||
void refreshLayout();
|
void refreshLayout();
|
||||||
void popup();
|
void popup();
|
||||||
void suppressPortalIfUnderCursor();
|
void suppressPortalIfUnderCursor();
|
||||||
|
void setDragging(bool dragging);
|
||||||
void stopPortalSuppression();
|
void stopPortalSuppression();
|
||||||
void dismiss();
|
void dismiss();
|
||||||
|
|
||||||
@@ -52,6 +53,7 @@ private:
|
|||||||
void setupUi();
|
void setupUi();
|
||||||
void setupWindow();
|
void setupWindow();
|
||||||
void updateGeometryForContent();
|
void updateGeometryForContent();
|
||||||
|
void updateMode();
|
||||||
void updateSelectionBar();
|
void updateSelectionBar();
|
||||||
void noteDragContent(const QMimeData *mime);
|
void noteDragContent(const QMimeData *mime);
|
||||||
void noteDragFinished();
|
void noteDragFinished();
|
||||||
@@ -79,6 +81,8 @@ private:
|
|||||||
int m_bottomMargin = 16;
|
int m_bottomMargin = 16;
|
||||||
int m_manualListHeight = 0;
|
int m_manualListHeight = 0;
|
||||||
QTimer *m_suppressWatch = nullptr;
|
QTimer *m_suppressWatch = nullptr;
|
||||||
|
bool m_stagingOnly = false;
|
||||||
|
bool m_dragging = false;
|
||||||
bool m_fixedPosition = true;
|
bool m_fixedPosition = true;
|
||||||
bool m_fixedSize = false;
|
bool m_fixedSize = false;
|
||||||
int m_dragMode = 0; // 0 none, 1 move, 2 resize
|
int m_dragMode = 0; // 0 none, 1 move, 2 resize
|
||||||
|
|||||||
Reference in New Issue
Block a user