Improved drag&drop: when an applet gets dragged, it now only moves to a toplevel
window when necesarry (when the applet moves over another view or window). svn path=/trunk/KDE/kdebase/workspace/libs/plasma/; revision=806641
This commit is contained in:
parent
c4ff00eb0f
commit
143b126bca
131
applethandle.cpp
131
applethandle.cpp
@ -252,6 +252,7 @@ AppletHandle::ButtonType AppletHandle::mapToButton(const QPointF &point) const
|
||||
//return m_applet->mapToParent(m_applet->shape()).contains(point) ? NoButton : MoveButton;
|
||||
}
|
||||
|
||||
|
||||
void AppletHandle::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
if (m_pendingFade) {
|
||||
@ -345,29 +346,22 @@ void AppletHandle::mouseReleaseEvent(QGraphicsSceneMouseEvent *event)
|
||||
m_topview = 0;
|
||||
m_applet->setGhostView(0);
|
||||
}
|
||||
//find out if we were dropped on a panel or something
|
||||
QWidget *w = QApplication::topLevelAt(event->screenPos());
|
||||
kDebug() << "move to widget" << w;
|
||||
if (w) {
|
||||
Plasma::View *v = qobject_cast<Plasma::View *>(w);
|
||||
if (v) {
|
||||
Containment *c = v->containment();
|
||||
QPoint pos = v->mapFromGlobal(event->screenPos() - m_mousePos);
|
||||
|
||||
//XXX the dashboard view won't give us a
|
||||
//containment. if it did, this could
|
||||
//break shit.
|
||||
if (c && c != m_containment) {
|
||||
//we actually have been dropped on another
|
||||
//containment, so move there
|
||||
//we have a screenpos, we need a scenepos
|
||||
//FIXME how reliable is this transform?
|
||||
switchContainment(c, v->mapToScene(pos));
|
||||
} else {
|
||||
//just update the position
|
||||
kDebug() << "just update the position";
|
||||
m_applet->setPos(v->mapToScene(pos));
|
||||
}
|
||||
//find out if we were dropped on a panel or something
|
||||
Plasma::View *v = Plasma::View::topLevelViewAt(event->screenPos());
|
||||
if (v) {
|
||||
Containment *c = v->containment();
|
||||
QPoint pos = v->mapFromGlobal(event->screenPos() - m_mousePos);
|
||||
|
||||
//XXX the dashboard view won't give us a
|
||||
//containment. if it did, this could
|
||||
//break shit.
|
||||
if (c && c != m_containment) {
|
||||
//we actually have been dropped on another
|
||||
//containment, so move there
|
||||
//we have a screenpos, we need a scenepos
|
||||
//FIXME how reliable is this transform?
|
||||
switchContainment(c, v->mapToScene(pos));
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -397,6 +391,15 @@ qreal _k_angleForPoints(const QPointF ¢er, const QPointF &pt1, const QPointF
|
||||
return beta - alpha;
|
||||
}
|
||||
|
||||
bool AppletHandle::goTopLevel(const QPoint & pos) {
|
||||
Plasma::View *v = Plasma::View::topLevelViewAt(pos);
|
||||
if (v != m_applet->containment()->view()) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void AppletHandle::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
||||
{
|
||||
static const qreal snapAngle = M_PI_2 /* $i 3.14159 / 2.0 */;
|
||||
@ -411,34 +414,65 @@ void AppletHandle::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
||||
QPointF delta = curPos-lastPos;
|
||||
|
||||
if (m_pressedButton == MoveButton) {
|
||||
if (!m_topview) { //create a new toplevel view
|
||||
m_topview = new View(m_applet->containment(), -1, 0);
|
||||
m_topview->setTrackContainmentChanges(false);
|
||||
|
||||
m_topview->setWindowFlags(Qt::Widget | Qt::FramelessWindowHint
|
||||
| Qt::WindowStaysOnTopHint);
|
||||
KWindowSystem::setState(m_topview->winId(), NET::SkipTaskbar | NET::SkipPager);
|
||||
|
||||
m_topview->setWallpaperEnabled(false);
|
||||
|
||||
m_topview->resize(m_applet->screenRect().size());
|
||||
kDebug() << "resizing topview to: " << m_applet->screenRect().size();
|
||||
|
||||
//TODO: when zoomed out, this doesn't work correctly
|
||||
m_topview->setSceneRect(m_applet->sceneBoundingRect());
|
||||
|
||||
m_topview->centerOn(m_applet);
|
||||
//We might have to scale the qgv, because we might be zoomed out.
|
||||
qreal scale = m_applet->screenRect().width() / m_applet->boundingRect().width();
|
||||
kDebug() << "scaling topview with: " << scale;
|
||||
m_topview->scale(scale, scale);
|
||||
|
||||
m_topview->show();
|
||||
|
||||
m_applet->setGhostView(m_applet->containment()->view());
|
||||
if (m_pos == QPointF(0, 0)) {
|
||||
m_pos = pos();
|
||||
}
|
||||
m_pos = m_pos + delta;
|
||||
|
||||
m_topview->move((event->screenPos() - m_mousePos));
|
||||
QRect screenRect = QRect(event->screenPos() - m_mousePos,
|
||||
m_applet->screenRect().size());
|
||||
kDebug() << "screenRect = " << screenRect;
|
||||
//add a 1 pixelmargin to the screenRect so, that when we check
|
||||
//if we are over another view than the source view, we won't
|
||||
//detect the top level view.
|
||||
screenRect.adjust(-1, -1, 1, 1);
|
||||
|
||||
//Are we moving out of the current view?
|
||||
bool toTopLevel = goTopLevel(screenRect.topLeft()) ||
|
||||
goTopLevel(screenRect.topRight()) ||
|
||||
goTopLevel(screenRect.bottomLeft()) ||
|
||||
goTopLevel(screenRect.bottomRight());
|
||||
|
||||
kDebug() << "toTopLevel = " << toTopLevel;
|
||||
if (!toTopLevel) {
|
||||
setPos(m_pos);
|
||||
if (m_topview) {
|
||||
m_topview->hide();
|
||||
delete m_topview;
|
||||
m_topview = 0;
|
||||
m_applet->setGhostView(0);
|
||||
}
|
||||
} else {
|
||||
if (!m_topview) { //create a new toplevel view
|
||||
m_topview = new View(m_applet->containment(), -1, 0);
|
||||
m_topview->setTrackContainmentChanges(false);
|
||||
|
||||
m_topview->setWindowFlags(Qt::Widget | Qt::FramelessWindowHint
|
||||
| Qt::WindowStaysOnTopHint);
|
||||
KWindowSystem::setState(m_topview->winId(), NET::SkipTaskbar | NET::SkipPager);
|
||||
|
||||
m_topview->setWallpaperEnabled(false);
|
||||
|
||||
m_topview->resize(m_applet->screenRect().size());
|
||||
kDebug() << "resizing topview to: " << m_applet->screenRect().size();
|
||||
|
||||
//TODO: when zoomed out, this doesn't work correctly
|
||||
m_topview->setSceneRect(m_applet->sceneBoundingRect());
|
||||
|
||||
m_topview->centerOn(m_applet);
|
||||
//We might have to scale the qgv, because we might be zoomed out.
|
||||
qreal scale = m_applet->screenRect().width() / m_applet->boundingRect().width();
|
||||
kDebug() << "scaling topview with: " << scale;
|
||||
m_topview->scale(scale, scale);
|
||||
|
||||
m_topview->show();
|
||||
|
||||
m_applet->setGhostView(m_applet->containment()->view());
|
||||
}
|
||||
|
||||
|
||||
m_topview->move((event->screenPos() - m_mousePos));
|
||||
}
|
||||
|
||||
} else if (m_pressedButton == RotateButton ||
|
||||
m_pressedButton == ResizeButton) {
|
||||
@ -670,6 +704,7 @@ void AppletHandle::startFading(FadeType anim)
|
||||
m_animId = Animator::self()->customAnimation(40, (int)time, Animator::EaseInOutCurve, this, "fadeAnimation");
|
||||
}
|
||||
|
||||
|
||||
void AppletHandle::forceDisappear()
|
||||
{
|
||||
setAcceptsHoverEvents(false);
|
||||
|
@ -81,6 +81,7 @@ class AppletHandle : public QObject, public QGraphicsItem
|
||||
* @param pos the (scene-relative) position to place it at
|
||||
*/
|
||||
void switchContainment(Containment *containment, const QPointF &pos);
|
||||
bool goTopLevel(const QPoint & pos);
|
||||
|
||||
QRectF m_rect;
|
||||
ButtonType m_pressedButton;
|
||||
@ -100,6 +101,7 @@ class AppletHandle : public QObject, public QGraphicsItem
|
||||
View *m_topview;
|
||||
QPoint m_mousePos; //the position of the mousecursor relative to the
|
||||
//applets position.
|
||||
QPointF m_pos;
|
||||
};
|
||||
|
||||
}
|
||||
|
10
view.cpp
10
view.cpp
@ -232,6 +232,16 @@ bool View::trackContainmentChanges()
|
||||
return d->trackChanges;
|
||||
}
|
||||
|
||||
View * View::topLevelViewAt(const QPoint & pos)
|
||||
{
|
||||
QWidget *w = QApplication::topLevelAt(pos);
|
||||
if (w) {
|
||||
Plasma::View *v = qobject_cast<Plasma::View *>(w);
|
||||
return v;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace Plasma
|
||||
|
||||
|
7
view.h
7
view.h
@ -20,6 +20,7 @@
|
||||
#ifndef VIEW_H
|
||||
#define VIEW_H
|
||||
|
||||
#include <QApplication>
|
||||
#include <QtGui/QGraphicsView>
|
||||
|
||||
#include <KDE/KConfigGroup>
|
||||
@ -135,6 +136,12 @@ public:
|
||||
*/
|
||||
bool trackContainmentChanges();
|
||||
|
||||
/**
|
||||
* @param pos the position in screen coordinates.
|
||||
* @return the Plasma::View that is at position pos.
|
||||
*/
|
||||
static View * topLevelViewAt(const QPoint & pos);
|
||||
|
||||
/**
|
||||
* @return the id of the View set in the constructor
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user