2016-06-15 16:17:51 +08:00
|
|
|
|
2016-06-02 09:46:43 +08:00
|
|
|
#include "dockitem.h"
|
2016-06-15 16:17:51 +08:00
|
|
|
#include "dbus/dbusmenu.h"
|
2016-06-15 17:44:38 +08:00
|
|
|
#include "dbus/dbusmenumanager.h"
|
2016-06-15 16:17:51 +08:00
|
|
|
|
|
|
|
#include <QMouseEvent>
|
|
|
|
#include <QJsonObject>
|
2016-06-02 09:46:43 +08:00
|
|
|
|
2016-06-21 17:24:03 +08:00
|
|
|
Position DockItem::DockPosition = Position::Top;
|
2016-06-23 14:28:47 +08:00
|
|
|
DisplayMode DockItem::DockDisplayMode = DisplayMode::Efficient;
|
2016-07-15 11:00:55 +08:00
|
|
|
std::unique_ptr<DockPopupWindow> DockItem::PopupWindow(nullptr);
|
2016-06-21 17:24:03 +08:00
|
|
|
|
2016-08-08 09:52:05 +08:00
|
|
|
DockItem::DockItem(QWidget *parent)
|
2016-06-06 11:37:09 +08:00
|
|
|
: QWidget(parent),
|
2016-06-27 20:16:35 +08:00
|
|
|
m_hover(false),
|
2016-07-20 16:30:56 +08:00
|
|
|
m_popupShown(false),
|
2016-06-15 16:17:51 +08:00
|
|
|
|
2016-07-01 10:42:08 +08:00
|
|
|
m_popupTipsDelayTimer(new QTimer(this)),
|
|
|
|
|
2016-06-15 16:17:51 +08:00
|
|
|
m_menuManagerInter(new DBusMenuManager(this))
|
2016-06-02 09:46:43 +08:00
|
|
|
{
|
2016-07-15 11:00:55 +08:00
|
|
|
if (!PopupWindow.get())
|
2016-07-13 14:24:39 +08:00
|
|
|
{
|
2016-07-15 11:00:55 +08:00
|
|
|
DockPopupWindow *arrowRectangle = new DockPopupWindow(nullptr);
|
2016-07-14 09:15:14 +08:00
|
|
|
arrowRectangle->setShadowBlurRadius(0);
|
2016-07-15 11:00:55 +08:00
|
|
|
PopupWindow.reset(arrowRectangle);
|
2016-07-13 14:24:39 +08:00
|
|
|
}
|
2016-07-01 10:42:08 +08:00
|
|
|
|
2016-07-18 14:13:36 +08:00
|
|
|
m_popupTipsDelayTimer->setInterval(500);
|
2016-07-01 10:42:08 +08:00
|
|
|
m_popupTipsDelayTimer->setSingleShot(true);
|
|
|
|
|
2016-07-15 11:00:55 +08:00
|
|
|
connect(m_popupTipsDelayTimer, &QTimer::timeout, this, &DockItem::showHoverTips);
|
2016-06-02 09:46:43 +08:00
|
|
|
}
|
2016-06-03 16:06:11 +08:00
|
|
|
|
2016-07-20 16:30:56 +08:00
|
|
|
DockItem::~DockItem()
|
|
|
|
{
|
|
|
|
if (m_popupShown)
|
|
|
|
popupWindowAccept();
|
|
|
|
}
|
|
|
|
|
2016-06-21 17:24:03 +08:00
|
|
|
void DockItem::setDockPosition(const Position side)
|
2016-06-16 16:56:21 +08:00
|
|
|
{
|
2016-06-21 17:24:03 +08:00
|
|
|
DockPosition = side;
|
2016-06-16 16:56:21 +08:00
|
|
|
}
|
2016-06-06 11:37:09 +08:00
|
|
|
|
2016-06-23 14:28:47 +08:00
|
|
|
void DockItem::setDockDisplayMode(const DisplayMode mode)
|
|
|
|
{
|
|
|
|
DockDisplayMode = mode;
|
|
|
|
}
|
|
|
|
|
2016-08-01 14:26:15 +08:00
|
|
|
void DockItem::updatePopupPosition()
|
|
|
|
{
|
2016-08-02 09:43:37 +08:00
|
|
|
if (!m_popupShown || !PopupWindow->isVisible())
|
2016-08-01 14:26:15 +08:00
|
|
|
return;
|
|
|
|
|
|
|
|
const QPoint p = popupMarkPoint();
|
|
|
|
PopupWindow->show(p, PopupWindow->model());
|
|
|
|
}
|
|
|
|
|
2016-06-03 16:06:11 +08:00
|
|
|
void DockItem::paintEvent(QPaintEvent *e)
|
|
|
|
{
|
|
|
|
QWidget::paintEvent(e);
|
2016-08-02 09:43:37 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void DockItem::moveEvent(QMoveEvent *e)
|
|
|
|
{
|
|
|
|
QWidget::moveEvent(e);
|
2016-08-01 14:26:15 +08:00
|
|
|
|
|
|
|
updatePopupPosition();
|
2016-06-03 16:06:11 +08:00
|
|
|
}
|
2016-06-15 16:17:51 +08:00
|
|
|
|
2016-07-01 10:42:08 +08:00
|
|
|
void DockItem::mouseMoveEvent(QMouseEvent *e)
|
|
|
|
{
|
|
|
|
QWidget::mouseMoveEvent(e);
|
|
|
|
|
|
|
|
m_popupTipsDelayTimer->start();
|
|
|
|
}
|
|
|
|
|
2016-06-15 16:17:51 +08:00
|
|
|
void DockItem::mousePressEvent(QMouseEvent *e)
|
|
|
|
{
|
|
|
|
if (e->button() == Qt::RightButton)
|
|
|
|
return showContextMenu();
|
|
|
|
}
|
|
|
|
|
2016-06-27 20:16:35 +08:00
|
|
|
void DockItem::enterEvent(QEvent *e)
|
|
|
|
{
|
|
|
|
m_hover = true;
|
2016-07-01 10:42:08 +08:00
|
|
|
m_popupTipsDelayTimer->start();
|
2016-06-27 20:16:35 +08:00
|
|
|
|
|
|
|
update();
|
|
|
|
|
|
|
|
return QWidget::enterEvent(e);
|
|
|
|
}
|
|
|
|
|
|
|
|
void DockItem::leaveEvent(QEvent *e)
|
|
|
|
{
|
|
|
|
m_hover = false;
|
2016-07-01 10:42:08 +08:00
|
|
|
m_popupTipsDelayTimer->stop();
|
|
|
|
|
2016-07-18 09:32:01 +08:00
|
|
|
// auto hide if popup is not model window
|
|
|
|
if (!PopupWindow->model())
|
2016-07-20 16:30:56 +08:00
|
|
|
{
|
|
|
|
m_popupShown = false;
|
2016-07-18 09:32:01 +08:00
|
|
|
PopupWindow->hide();
|
2016-07-20 16:30:56 +08:00
|
|
|
}
|
2016-06-27 20:16:35 +08:00
|
|
|
|
|
|
|
update();
|
|
|
|
|
|
|
|
return QWidget::leaveEvent(e);
|
|
|
|
}
|
|
|
|
|
2016-06-22 11:02:52 +08:00
|
|
|
const QRect DockItem::perfectIconRect() const
|
|
|
|
{
|
|
|
|
const QRect itemRect = rect();
|
2016-06-23 19:32:53 +08:00
|
|
|
const int iconSize = std::min(itemRect.width(), itemRect.height()) * 0.8;
|
2016-06-22 11:02:52 +08:00
|
|
|
|
|
|
|
QRect iconRect;
|
|
|
|
iconRect.setWidth(iconSize);
|
|
|
|
iconRect.setHeight(iconSize);
|
|
|
|
iconRect.moveTopLeft(itemRect.center() - iconRect.center());
|
|
|
|
|
|
|
|
return iconRect;
|
|
|
|
}
|
|
|
|
|
2016-06-15 16:17:51 +08:00
|
|
|
void DockItem::showContextMenu()
|
|
|
|
{
|
|
|
|
const QString menuJson = contextMenu();
|
|
|
|
if (menuJson.isEmpty())
|
|
|
|
return;
|
|
|
|
|
|
|
|
QDBusPendingReply<QDBusObjectPath> result = m_menuManagerInter->RegisterMenu();
|
|
|
|
|
|
|
|
result.waitForFinished();
|
|
|
|
if (result.isError())
|
|
|
|
{
|
|
|
|
qWarning() << result.error();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2016-07-01 10:42:08 +08:00
|
|
|
const QPoint p = popupMarkPoint();
|
2016-06-23 19:32:53 +08:00
|
|
|
|
2016-06-15 16:17:51 +08:00
|
|
|
QJsonObject menuObject;
|
2016-06-23 19:32:53 +08:00
|
|
|
menuObject.insert("x", QJsonValue(p.x()));
|
2016-06-15 16:17:51 +08:00
|
|
|
menuObject.insert("y", QJsonValue(p.y()));
|
|
|
|
menuObject.insert("isDockMenu", QJsonValue(true));
|
|
|
|
menuObject.insert("menuJsonContent", QJsonValue(menuJson));
|
|
|
|
|
2016-06-29 11:15:56 +08:00
|
|
|
switch (DockPosition)
|
|
|
|
{
|
|
|
|
case Top: menuObject.insert("direction", "top"); break;
|
|
|
|
case Bottom: menuObject.insert("direction", "bottom"); break;
|
|
|
|
case Left: menuObject.insert("direction", "left"); break;
|
|
|
|
case Right: menuObject.insert("direction", "right"); break;
|
|
|
|
}
|
|
|
|
|
2016-06-15 16:17:51 +08:00
|
|
|
const QDBusObjectPath path = result.argumentAt(0).value<QDBusObjectPath>();
|
|
|
|
DBusMenu *menuInter = new DBusMenu(path.path(), this);
|
|
|
|
|
|
|
|
connect(menuInter, &DBusMenu::ItemInvoked, this, &DockItem::invokedMenuItem);
|
2016-07-18 09:32:01 +08:00
|
|
|
connect(menuInter, &DBusMenu::MenuUnregistered, this, &DockItem::requestRefershWindowVisible);
|
2016-06-15 16:17:51 +08:00
|
|
|
connect(menuInter, &DBusMenu::MenuUnregistered, menuInter, &DBusMenu::deleteLater, Qt::QueuedConnection);
|
|
|
|
|
|
|
|
menuInter->ShowMenu(QString(QJsonDocument(menuObject).toJson()));
|
|
|
|
}
|
|
|
|
|
2016-07-15 11:00:55 +08:00
|
|
|
void DockItem::showHoverTips()
|
2016-07-01 10:42:08 +08:00
|
|
|
{
|
2016-07-18 09:32:01 +08:00
|
|
|
// another model popup window is alread exists
|
|
|
|
if (PopupWindow->isVisible() && PopupWindow->model())
|
|
|
|
return;
|
|
|
|
|
2016-07-13 16:47:59 +08:00
|
|
|
QWidget * const content = popupTips();
|
|
|
|
if (!content)
|
|
|
|
return;
|
|
|
|
|
2016-07-15 11:00:55 +08:00
|
|
|
showPopupWindow(content);
|
|
|
|
}
|
|
|
|
|
2016-07-18 09:32:01 +08:00
|
|
|
void DockItem::showPopupWindow(QWidget * const content, const bool model)
|
2016-07-15 11:00:55 +08:00
|
|
|
{
|
2016-07-20 16:30:56 +08:00
|
|
|
m_popupShown = true;
|
|
|
|
|
2016-07-18 09:32:01 +08:00
|
|
|
if (model)
|
|
|
|
emit requestWindowAutoHide(false);
|
|
|
|
|
2016-07-15 11:00:55 +08:00
|
|
|
DockPopupWindow *popup = PopupWindow.get();
|
|
|
|
QWidget *lastContent = popup->getContent();
|
2016-07-13 16:47:59 +08:00
|
|
|
if (lastContent)
|
|
|
|
lastContent->hide();
|
|
|
|
|
|
|
|
switch (DockPosition)
|
|
|
|
{
|
2016-07-15 11:00:55 +08:00
|
|
|
case Top: popup->setArrowDirection(DockPopupWindow::ArrowTop); break;
|
|
|
|
case Bottom:popup->setArrowDirection(DockPopupWindow::ArrowBottom); break;
|
|
|
|
case Left: popup->setArrowDirection(DockPopupWindow::ArrowLeft); break;
|
|
|
|
case Right: popup->setArrowDirection(DockPopupWindow::ArrowRight); break;
|
2016-07-13 16:47:59 +08:00
|
|
|
}
|
2016-07-15 11:00:55 +08:00
|
|
|
popup->setContent(content);
|
|
|
|
popup->setMargin(5);
|
|
|
|
popup->setWidth(content->sizeHint().width());
|
|
|
|
popup->setHeight(content->sizeHint().height());
|
2016-07-13 16:47:59 +08:00
|
|
|
|
|
|
|
const QPoint p = popupMarkPoint();
|
2016-07-18 10:09:26 +08:00
|
|
|
QMetaObject::invokeMethod(popup, "show", Qt::QueuedConnection, Q_ARG(QPoint, p), Q_ARG(bool, model));
|
|
|
|
|
|
|
|
connect(popup, &DockPopupWindow::accept, this, &DockItem::popupWindowAccept);
|
2016-07-01 10:42:08 +08:00
|
|
|
}
|
|
|
|
|
2016-07-18 09:32:01 +08:00
|
|
|
void DockItem::popupWindowAccept()
|
|
|
|
{
|
|
|
|
if (!PopupWindow->isVisible())
|
|
|
|
return;
|
|
|
|
|
2016-07-18 10:09:26 +08:00
|
|
|
disconnect(PopupWindow.get(), &DockPopupWindow::accept, this, &DockItem::popupWindowAccept);
|
|
|
|
|
2016-07-20 16:30:56 +08:00
|
|
|
m_popupShown = false;
|
2016-07-18 09:32:01 +08:00
|
|
|
PopupWindow->hide();
|
|
|
|
|
|
|
|
emit requestWindowAutoHide(true);
|
|
|
|
}
|
|
|
|
|
2016-07-27 14:08:23 +08:00
|
|
|
void DockItem::showPopupApplet(QWidget * const applet)
|
|
|
|
{
|
|
|
|
// another model popup window is alread exists
|
|
|
|
if (PopupWindow->isVisible() && PopupWindow->model())
|
|
|
|
return;
|
|
|
|
|
|
|
|
showPopupWindow(applet, true);
|
|
|
|
}
|
|
|
|
|
2016-06-15 16:17:51 +08:00
|
|
|
void DockItem::invokedMenuItem(const QString &itemId, const bool checked)
|
|
|
|
{
|
|
|
|
Q_UNUSED(itemId)
|
|
|
|
Q_UNUSED(checked)
|
|
|
|
}
|
|
|
|
|
|
|
|
const QString DockItem::contextMenu() const
|
|
|
|
{
|
2016-06-15 17:44:38 +08:00
|
|
|
return QString();
|
2016-06-15 16:17:51 +08:00
|
|
|
}
|
2016-07-01 10:42:08 +08:00
|
|
|
|
2016-07-13 16:47:59 +08:00
|
|
|
QWidget *DockItem::popupTips()
|
|
|
|
{
|
|
|
|
return nullptr;
|
|
|
|
}
|
|
|
|
|
2016-07-01 10:42:08 +08:00
|
|
|
const QPoint DockItem::popupMarkPoint()
|
|
|
|
{
|
|
|
|
QPoint p;
|
|
|
|
QWidget *w = this;
|
|
|
|
do {
|
|
|
|
p += w->pos();
|
|
|
|
w = qobject_cast<QWidget *>(w->parent());
|
|
|
|
} while (w);
|
|
|
|
|
|
|
|
const QRect r = rect();
|
|
|
|
switch (DockPosition)
|
|
|
|
{
|
|
|
|
case Top: p += QPoint(r.width() / 2, r.height()); break;
|
|
|
|
case Bottom: p += QPoint(r.width() / 2, 0); break;
|
|
|
|
case Left: p += QPoint(r.width(), r.height() / 2); break;
|
|
|
|
case Right: p += QPoint(0, r.height() / 2); break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return p;
|
|
|
|
}
|