1
0
mirror of https://github.com/KDE/latte-dock.git synced 2025-01-08 01:18:21 +03:00
latte-dock/declarativeimports/core/dialog.cpp
2022-05-22 18:38:54 +03:00

263 lines
8.5 KiB
C++

/*
SPDX-FileCopyrightText: 2020 Michail Vourlakos <mvourlakos@gmail.com>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "dialog.h"
// Qt
#include <QScreen>
#include <QWindow>
namespace Latte {
namespace Quick {
Dialog::Dialog(QQuickItem *parent)
: PlasmaQuick::Dialog(parent)
{
connect(this, &PlasmaQuick::Dialog::visualParentChanged, this, &Dialog::onVisualParentChanged);
}
bool Dialog::containsMouse() const
{
return m_containsMouse;
}
void Dialog::setContainsMouse(bool contains)
{
if (m_containsMouse == contains) {
return;
}
m_containsMouse = contains;
emit containsMouseChanged();
}
Plasma::Types::Location Dialog::edge() const
{
return m_edge;
}
void Dialog::setEdge(const Plasma::Types::Location &edge)
{
if (m_edge == edge) {
return;
}
m_edge = edge;
emit edgeChanged();
}
bool Dialog::isRespectingAppletsLayoutGeometry() const
{
//! As it appears plasma applets popups are defining their popups to Normal window.
//! Dock type is needed from wayland scenario. In wayland after a while popups from Normal become Dock types
return (type() == Dialog::Normal || type() == Dialog::PopupMenu || type() == Dialog::Tooltip || type() == Dialog::Dock);
}
QRect Dialog::appletsLayoutGeometryFromContainment() const
{
QVariant geom = visualParent() && visualParent()->window() ? visualParent()->window()->property("_applets_layout_geometry") : QVariant();
return geom.isValid() ? geom.toRect() : QRect();
}
int Dialog::appletsPopUpMargin() const
{
QVariant margin = visualParent() && visualParent()->window() ? visualParent()->window()->property("_applets_popup_margin") : QVariant();
return margin.isValid() ? margin.toInt() : -1;
}
void Dialog::onVisualParentChanged()
{
// clear mode
for (auto &c : m_visualParentConnections) {
disconnect(c);
}
if (!visualParent() || !flags().testFlag(Qt::ToolTip) || !visualParent()->metaObject()) {
return;
}
bool hassignal = (visualParent()->metaObject()->indexOfSignal(QMetaObject::normalizedSignature("anchoredTooltipPositionChanged()")) != -1);
if (hassignal) {
m_visualParentConnections[0] = connect(visualParent(), SIGNAL(anchoredTooltipPositionChanged()) , this, SLOT(updateGeometry()));
}
}
void Dialog::updateGeometry()
{
if (visualParent()) {
setPosition(popupPosition(visualParent(), size()));
}
}
void Dialog::updatePopUpEnabledBorders()
{
QRect appletslayoutgeometry = appletsLayoutGeometryFromContainment();
int appletspopupmargin = appletsPopUpMargin();
//! Plasma Scenario
bool hideEdgeBorder = isRespectingAppletsLayoutGeometry() && !appletslayoutgeometry.isEmpty() && appletspopupmargin==-1;
if (hideEdgeBorder) {
setLocation(m_edge);
} else {
setLocation(Plasma::Types::Floating);
}
}
QPoint Dialog::popupPosition(QQuickItem *item, const QSize &size)
{
auto visualparent = item;
if (visualparent && visualparent->window() && visualparent->window()->screen()) {
updatePopUpEnabledBorders();
QPointF parenttopleftf = visualparent->mapToGlobal(QPointF(0, 0));
QPoint parenttopleft = parenttopleftf.toPoint();
QScreen *screen = visualparent->window()->screen();
QRect screengeometry = screen->geometry();
int x = 0;
int y = 0;
int popupmargin = qMax(0, appletsPopUpMargin());
if (m_edge == Plasma::Types::LeftEdge || m_edge == Plasma::Types::RightEdge) {
//! vertical scenario
screengeometry -= QMargins(0, popupmargin, 0, popupmargin);
y = parenttopleft.y() + (visualparent->height()/2) - (size.height()/2);
} else {
//! horizontal scenario
screengeometry -= QMargins(popupmargin, 0, popupmargin, 0);
x = parenttopleft.x() + (visualparent->width()/2) - (size.width()/2);
}
if (m_edge == Plasma::Types::LeftEdge) {
x = parenttopleft.x() + visualparent->width() + popupmargin;
} else if (m_edge == Plasma::Types::RightEdge) {
x = parenttopleft.x() - size.width() - popupmargin;
} else if (m_edge == Plasma::Types::TopEdge) {
y = parenttopleft.y() + visualparent->height() + popupmargin;
} else { // bottom case
y = parenttopleft.y() - size.height() - popupmargin;
}
x = qBound(screengeometry.x(), x, screengeometry.right() - size.width() + 1);
y = qBound(screengeometry.y(), y, screengeometry.bottom() - size.height() + 1);
QRect appletslayoutgeometry = appletsLayoutGeometryFromContainment();
if (isRespectingAppletsLayoutGeometry() && !appletslayoutgeometry.isEmpty()) {
QPoint appletsglobaltopleft = visualparent->window()->mapToGlobal(appletslayoutgeometry.topLeft());
QRect appletsglobalgeometry(appletsglobaltopleft.x(), appletsglobaltopleft.y(), appletslayoutgeometry.width(), appletslayoutgeometry.height());
if (m_edge == Plasma::Types::LeftEdge || m_edge == Plasma::Types::RightEdge) {
int bottomy = appletsglobalgeometry.bottom()-size.height();
if (appletsglobalgeometry.height() >= size.height()) {
y = qBound(appletsglobalgeometry.y(), y, bottomy + 1);
}
} else {
int rightx = appletsglobalgeometry.right()-size.width();
if (appletsglobalgeometry.width() >= size.width()) {
x = qBound(appletsglobalgeometry.x(), x, rightx + 1);
}
}
}
return QPoint(x,y);
}
return PlasmaQuick::Dialog::popupPosition(item, size);
}
/*
void Dialog::adjustGeometry(const QRect &geom)
{
auto visualparent = visualParent();
if (visualparent && visualparent->window() && visualparent->window()->screen()) {
updatePopUpEnabledBorders();
QPointF parenttopleftf = visualparent->mapToGlobal(QPointF(0, 0));
QPoint parenttopleft = parenttopleftf.toPoint();
QScreen *screen = visualparent->window()->screen();
QRect screengeometry = screen->geometry();
int x = 0;
int y = 0;
if (m_edge == Plasma::Types::LeftEdge || m_edge == Plasma::Types::RightEdge) {
y = parenttopleft.y() + (visualparent->height()/2) - (geom.height()/2);
} else {
x = parenttopleft.x() + (visualparent->width()/2) - (geom.width()/2);
}
int popupmargin = qMax(0, appletsPopUpMargin());
if (m_edge == Plasma::Types::LeftEdge) {
x = parenttopleft.x() + visualparent->width() + popupmargin;
} else if (m_edge == Plasma::Types::RightEdge) {
x = parenttopleft.x() - geom.width() - popupmargin;
} else if (m_edge == Plasma::Types::TopEdge) {
y = parenttopleft.y() + visualparent->height() + popupmargin;
} else { // bottom case
y = parenttopleft.y() - geom.height() - popupmargin;
}
x = qBound(screengeometry.x(), x, screengeometry.right()-1);
y = qBound(screengeometry.y(), y, screengeometry.bottom()-1);
QRect appletslayoutgeometry = appletsLayoutGeometryFromContainment();
if (isRespectingAppletsLayoutGeometry() && !appletslayoutgeometry.isEmpty()) {
QPoint appletsglobaltopleft = visualparent->window()->mapToGlobal(appletslayoutgeometry.topLeft());
QRect appletsglobalgeometry(appletsglobaltopleft.x(), appletsglobaltopleft.y(), appletslayoutgeometry.width(), appletslayoutgeometry.height());
if (m_edge == Plasma::Types::LeftEdge || m_edge == Plasma::Types::RightEdge) {
int bottomy = appletsglobalgeometry.bottom()-geom.height();
if (appletsglobalgeometry.height() >= geom.height()) {
y = qBound(appletsglobalgeometry.y(), y, bottomy + 1);
}
} else {
int rightx = appletsglobalgeometry.right()-geom.width();
if (appletsglobalgeometry.width() >= geom.width()) {
x = qBound(appletsglobalgeometry.x(), x, rightx + 1);
}
}
}
QRect repositionedrect(x, y, geom.width(), geom.height());
setGeometry(repositionedrect);
return;
}
PlasmaQuick::Dialog::adjustGeometry(geom);
}
*/
bool Dialog::event(QEvent *e)
{
if (e->type() == QEvent::Enter) {
setContainsMouse(true);
} else if (e->type() == QEvent::Leave
|| e->type() == QEvent::Hide) {
setContainsMouse(false);
}
return PlasmaQuick::Dialog::event(e);
}
}
}