start of making the applet handle a child of the applet, stacked behind. a lot less code, preserves the geometry caches in the scene. also removes a ton of update() calls that aren't necessary these days. result -> a lot snappier/smoother. still some positioning bugs due to the change in parenting in the code, but definitely the direction we need to be going in.
svn path=/trunk/KDE/kdelibs/; revision=1021595
This commit is contained in:
parent
c96119f4ed
commit
85defb5470
@ -54,7 +54,7 @@ QPointF _k_rotatePoint(QPointF in, qreal rotateAngle);
|
|||||||
|
|
||||||
AppletHandle::AppletHandle(Containment *parent, Applet *applet, const QPointF &hoverPos)
|
AppletHandle::AppletHandle(Containment *parent, Applet *applet, const QPointF &hoverPos)
|
||||||
: QObject(),
|
: QObject(),
|
||||||
QGraphicsItem(parent),
|
QGraphicsItem(applet),
|
||||||
m_pressedButton(NoButton),
|
m_pressedButton(NoButton),
|
||||||
m_containment(parent),
|
m_containment(parent),
|
||||||
m_applet(applet),
|
m_applet(applet),
|
||||||
@ -69,35 +69,13 @@ AppletHandle::AppletHandle(Containment *parent, Applet *applet, const QPointF &h
|
|||||||
m_buttonsOnRight(false),
|
m_buttonsOnRight(false),
|
||||||
m_pendingFade(false)
|
m_pendingFade(false)
|
||||||
{
|
{
|
||||||
|
setFlags(flags() | QGraphicsItem::ItemStacksBehindParent);
|
||||||
KColorScheme colorScheme(QPalette::Active, KColorScheme::View,
|
KColorScheme colorScheme(QPalette::Active, KColorScheme::View,
|
||||||
Theme::defaultTheme()->colorScheme());
|
Theme::defaultTheme()->colorScheme());
|
||||||
m_gradientColor = colorScheme.background(KColorScheme::NormalBackground).color();
|
m_gradientColor = colorScheme.background(KColorScheme::NormalBackground).color();
|
||||||
|
|
||||||
m_originalGeom = m_applet->geometry();
|
m_originalGeom = m_applet->geometry();
|
||||||
m_originalTransform = m_applet->transform();
|
m_originalTransform = m_applet->transform();
|
||||||
|
|
||||||
QTransform originalMatrix = m_applet->transform();
|
|
||||||
m_applet->resetTransform();
|
|
||||||
|
|
||||||
QRectF rect(m_applet->contentsRect());
|
|
||||||
QPointF center = rect.center();
|
|
||||||
originalMatrix.translate(center.x(), center.y());
|
|
||||||
|
|
||||||
qreal cosine = originalMatrix.m11();
|
|
||||||
qreal sine = originalMatrix.m12();
|
|
||||||
|
|
||||||
m_angle = _k_pointAngle(QPointF(cosine, sine));
|
|
||||||
|
|
||||||
m_applet->setParentItem(this);
|
|
||||||
|
|
||||||
rect = QRectF(m_applet->pos(), m_applet->size());
|
|
||||||
center = rect.center();
|
|
||||||
QTransform matrix;
|
|
||||||
matrix.translate(center.x(), center.y());
|
|
||||||
matrix.rotateRadians(m_angle);
|
|
||||||
matrix.translate(-center.x(), -center.y());
|
|
||||||
setTransform(matrix);
|
|
||||||
|
|
||||||
m_hoverTimer = new QTimer(this);
|
m_hoverTimer = new QTimer(this);
|
||||||
m_hoverTimer->setSingleShot(true);
|
m_hoverTimer->setSingleShot(true);
|
||||||
m_hoverTimer->setInterval(333);
|
m_hoverTimer->setInterval(333);
|
||||||
@ -116,20 +94,11 @@ AppletHandle::AppletHandle(Containment *parent, Applet *applet, const QPointF &h
|
|||||||
//icons
|
//icons
|
||||||
m_configureIcons = new Svg(this);
|
m_configureIcons = new Svg(this);
|
||||||
m_configureIcons->setImagePath("widgets/configuration-icons");
|
m_configureIcons->setImagePath("widgets/configuration-icons");
|
||||||
//FIXME: this should be of course true, but works only if false
|
|
||||||
m_configureIcons->setContainsMultipleImages(true);
|
m_configureIcons->setContainsMultipleImages(true);
|
||||||
|
|
||||||
m_background = new FrameSvg(this);
|
m_background = new FrameSvg(this);
|
||||||
m_background->setImagePath("widgets/background");
|
m_background->setImagePath("widgets/background");
|
||||||
|
|
||||||
//We got to be able to see the applet while dragging to to another containment,
|
|
||||||
//so we want a high zValue.
|
|
||||||
//FIXME: apparently this doesn't work: sometimes an applet still get's drawn behind
|
|
||||||
//the containment it's being dragged to, sometimes it doesn't.
|
|
||||||
m_zValue = m_applet->zValue() - 1;
|
|
||||||
m_applet->raise();
|
|
||||||
m_applet->installSceneEventFilter(this);
|
m_applet->installSceneEventFilter(this);
|
||||||
setZValue(m_applet->zValue());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AppletHandle::~AppletHandle()
|
AppletHandle::~AppletHandle()
|
||||||
@ -143,7 +112,7 @@ Applet *AppletHandle::applet() const
|
|||||||
return m_applet;
|
return m_applet;
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppletHandle::detachApplet ()
|
void AppletHandle::detachApplet()
|
||||||
{
|
{
|
||||||
if (!m_applet) {
|
if (!m_applet) {
|
||||||
return;
|
return;
|
||||||
@ -153,30 +122,10 @@ void AppletHandle::detachApplet ()
|
|||||||
disconnect(m_leaveTimer, SIGNAL(timeout()), this, SLOT(leaveTimeout()));
|
disconnect(m_leaveTimer, SIGNAL(timeout()), this, SLOT(leaveTimeout()));
|
||||||
m_applet->disconnect(this);
|
m_applet->disconnect(this);
|
||||||
|
|
||||||
m_applet->removeSceneEventFilter(this);
|
|
||||||
|
|
||||||
QRectF appletGeomLocal = m_applet->geometry();
|
|
||||||
QPointF center = mapToParent(appletGeomLocal.center());
|
|
||||||
QPointF appletPos = QPointF(center.x()-appletGeomLocal.width()/2, center.y()-appletGeomLocal.height()/2);
|
|
||||||
m_applet->setPos(appletPos);
|
|
||||||
|
|
||||||
// transform is relative to the applet
|
|
||||||
QTransform t;
|
|
||||||
t.translate(appletGeomLocal.width()/2, appletGeomLocal.height()/2);
|
|
||||||
t.rotateRadians(m_angle);
|
|
||||||
t.translate(-appletGeomLocal.width()/2, -appletGeomLocal.height()/2);
|
|
||||||
m_applet->setTransform(t);
|
|
||||||
|
|
||||||
m_applet->setParentItem(m_containment);
|
|
||||||
|
|
||||||
m_applet->setZValue(m_zValue);
|
|
||||||
|
|
||||||
if (m_applet->geometry() != m_originalGeom || m_applet->transform() != m_originalTransform) {
|
if (m_applet->geometry() != m_originalGeom || m_applet->transform() != m_originalTransform) {
|
||||||
emit m_applet->appletTransformedByUser();
|
emit m_applet->appletTransformedByUser();
|
||||||
}
|
}
|
||||||
|
|
||||||
m_applet->update(); // re-render the background, now we've transformed the applet
|
|
||||||
|
|
||||||
m_applet = 0;
|
m_applet = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -461,12 +410,8 @@ void AppletHandle::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
|||||||
setZValue(m_zValue);
|
setZValue(m_zValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_pressedButton == MoveButton) {
|
|
||||||
m_pos = pos();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_pressedButton == ResizeButton || m_pressedButton == RotateButton) {
|
if (m_pressedButton == ResizeButton || m_pressedButton == RotateButton) {
|
||||||
m_origAppletCenter = mapToScene(m_applet->geometry().center());
|
m_origAppletCenter = m_applet->geometry().center();
|
||||||
m_origAppletSize = QPointF(m_applet->size().width(), m_applet->size().height());
|
m_origAppletSize = QPointF(m_applet->size().width(), m_applet->size().height());
|
||||||
|
|
||||||
// resize
|
// resize
|
||||||
@ -475,17 +420,14 @@ void AppletHandle::mousePressEvent(QGraphicsSceneMouseEvent *event)
|
|||||||
} else {
|
} else {
|
||||||
m_resizeStaticPoint = mapToScene(m_applet->geometry().bottomRight());
|
m_resizeStaticPoint = mapToScene(m_applet->geometry().bottomRight());
|
||||||
}
|
}
|
||||||
m_resizeGrabPoint = mapToScene(event->pos());
|
m_resizeGrabPoint = event->scenePos();
|
||||||
QPointF cursorRelativeToStatic = m_resizeGrabPoint - m_resizeStaticPoint;
|
|
||||||
|
|
||||||
// rotate
|
// rotate
|
||||||
m_rotateAngleOffset = m_angle - _k_pointAngle(mapToScene(event->pos()) - m_origAppletCenter);
|
m_rotateAngleOffset = m_angle - _k_pointAngle(event->scenePos() - m_origAppletCenter);
|
||||||
}
|
}
|
||||||
|
|
||||||
event->accept();
|
event->accept();
|
||||||
|
|
||||||
update();
|
|
||||||
|
|
||||||
//set mousePos to the position in the applet, in screencoords, so it becomes easy
|
//set mousePos to the position in the applet, in screencoords, so it becomes easy
|
||||||
//to reposition the toplevel view to the correct position.
|
//to reposition the toplevel view to the correct position.
|
||||||
if (m_currentView && m_applet) {
|
if (m_currentView && m_applet) {
|
||||||
@ -590,7 +532,7 @@ qreal _k_pointAngle(QPointF in)
|
|||||||
qreal cosine = in.x()/r;
|
qreal cosine = in.x()/r;
|
||||||
qreal sine = in.y()/r;
|
qreal sine = in.y()/r;
|
||||||
|
|
||||||
if (sine>=0) {
|
if (sine >= 0) {
|
||||||
return acos(cosine);
|
return acos(cosine);
|
||||||
} else {
|
} else {
|
||||||
return -acos(cosine);
|
return -acos(cosine);
|
||||||
@ -627,7 +569,6 @@ void AppletHandle::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
|||||||
QPointF deltaScene = event->scenePos() - event->lastScenePos();
|
QPointF deltaScene = event->scenePos() - event->lastScenePos();
|
||||||
|
|
||||||
if (m_pressedButton == MoveButton) {
|
if (m_pressedButton == MoveButton) {
|
||||||
m_pos += deltaScene;
|
|
||||||
if (leaveCurrentView(event->screenPos())) {
|
if (leaveCurrentView(event->screenPos())) {
|
||||||
Plasma::View *v = Plasma::View::topLevelViewAt(event->screenPos());
|
Plasma::View *v = Plasma::View::topLevelViewAt(event->screenPos());
|
||||||
if (v && v != m_currentView) {
|
if (v && v != m_currentView) {
|
||||||
@ -637,14 +578,14 @@ void AppletHandle::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
|||||||
//move there: we have a screenpos, we need a scenepos
|
//move there: we have a screenpos, we need a scenepos
|
||||||
//FIXME how reliable is this transform?
|
//FIXME how reliable is this transform?
|
||||||
switchContainment(c, v->mapToScene(pos));
|
switchContainment(c, v->mapToScene(pos));
|
||||||
} else {
|
|
||||||
setPos(m_pos);
|
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
setPos(m_pos);
|
|
||||||
|
if (m_applet) {
|
||||||
|
m_applet->moveBy(deltaScene.x(), deltaScene.y());
|
||||||
}
|
}
|
||||||
} else if (m_pressedButton == ResizeButton || m_pressedButton == RotateButton) {
|
} else if (m_pressedButton == ResizeButton || m_pressedButton == RotateButton) {
|
||||||
QPointF cursorPoint = mapToScene(event->pos());
|
QPointF cursorPoint = event->scenePos();
|
||||||
|
|
||||||
// the code below will adjust these based on the type of operation
|
// the code below will adjust these based on the type of operation
|
||||||
QPointF newSize;
|
QPointF newSize;
|
||||||
@ -724,32 +665,32 @@ void AppletHandle::mouseMoveEvent(QGraphicsSceneMouseEvent *event)
|
|||||||
|
|
||||||
// move center such that the static corner remains in the same place
|
// move center such that the static corner remains in the same place
|
||||||
if (m_buttonsOnRight) {
|
if (m_buttonsOnRight) {
|
||||||
newCenter = _k_rotatePoint(QPointF(rStaticPoint.x() + newSize.x()/2, rStaticPoint.y() - newSize.y()/2), m_angle);
|
newCenter = _k_rotatePoint(QPointF(rStaticPoint.x() + newSize.x()/2,
|
||||||
|
rStaticPoint.y() - newSize.y()/2), 0);
|
||||||
} else {
|
} else {
|
||||||
newCenter = _k_rotatePoint(QPointF(rStaticPoint.x() - newSize.x()/2, rStaticPoint.y() - newSize.y()/2), m_angle);
|
newCenter = _k_rotatePoint(QPointF(rStaticPoint.x() - newSize.x()/2,
|
||||||
|
rStaticPoint.y() - newSize.y()/2), 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
newAngle = m_angle;
|
newAngle = m_angle;
|
||||||
}
|
}
|
||||||
|
|
||||||
// set position of applet handle
|
if (m_pressedButton == ResizeButton) {
|
||||||
QPointF newHandlePosInScene = newCenter - (m_applet->pos() + newSize/2);
|
|
||||||
QPointF newHandlePos = parentItem()->mapFromScene(newHandlePosInScene);
|
|
||||||
setPos(newHandlePos);
|
|
||||||
|
|
||||||
// set applet size
|
// set applet size
|
||||||
|
kDebug() << newCenter << m_originalGeom.topLeft() << newSize;
|
||||||
|
m_applet->setPos(newCenter - (m_originalGeom.topLeft() + newSize/2));
|
||||||
m_applet->resize(newSize.x(), newSize.y());
|
m_applet->resize(newSize.x(), newSize.y());
|
||||||
|
} else {
|
||||||
// set applet handle rotation - rotate around center of applet
|
// set applet handle rotation - rotate around center of applet
|
||||||
QTransform t;
|
QRectF appletGeomLocal = m_originalGeom;
|
||||||
QPointF appletCenter = m_applet->geometry().center();
|
QTransform at;
|
||||||
t.translate(appletCenter.x(), appletCenter.y());
|
at.translate(appletGeomLocal.width()/2, appletGeomLocal.height()/2);
|
||||||
t.rotateRadians(newAngle);
|
at.rotateRadians(newAngle);
|
||||||
t.translate(-appletCenter.x(), -appletCenter.y());
|
at.translate(-appletGeomLocal.width()/2, -appletGeomLocal.height()/2);
|
||||||
setTransform(t);
|
m_applet->setTransform(at);
|
||||||
m_angle = newAngle;
|
}
|
||||||
|
|
||||||
m_applet->update();
|
m_angle = newAngle;
|
||||||
} else {
|
} else {
|
||||||
QGraphicsItem::mouseMoveEvent(event);
|
QGraphicsItem::mouseMoveEvent(event);
|
||||||
}
|
}
|
||||||
@ -764,19 +705,11 @@ void AppletHandle::switchContainment(Containment *containment, const QPointF &po
|
|||||||
applet->removeSceneEventFilter(this);
|
applet->removeSceneEventFilter(this);
|
||||||
forceDisappear(); //takes care of event filter and killing handle
|
forceDisappear(); //takes care of event filter and killing handle
|
||||||
applet->disconnect(this); //make sure the applet doesn't tell us to do anything
|
applet->disconnect(this); //make sure the applet doesn't tell us to do anything
|
||||||
applet->setZValue(m_zValue);
|
//applet->setZValue(m_zValue);
|
||||||
containment->addApplet(applet, containment->mapFromScene(pos), false);
|
containment->addApplet(applet, containment->mapFromScene(pos), false);
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant AppletHandle::itemChange(GraphicsItemChange change, const QVariant &value)
|
|
||||||
{
|
|
||||||
if (change == ItemPositionHasChanged && m_applet) {
|
|
||||||
m_applet->updateConstraints(Plasma::LocationConstraint);
|
|
||||||
}
|
|
||||||
return QGraphicsItem::itemChange(change, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
void AppletHandle::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
|
void AppletHandle::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
|
||||||
{
|
{
|
||||||
Q_UNUSED(event);
|
Q_UNUSED(event);
|
||||||
@ -902,14 +835,14 @@ void AppletHandle::startFading(FadeType anim, const QPointF &hoverPos, bool pres
|
|||||||
m_buttonsOnRight = m_entryPos.x() > (m_applet->size().width() / 2);
|
m_buttonsOnRight = m_entryPos.x() > (m_applet->size().width() / 2);
|
||||||
}
|
}
|
||||||
calculateSize();
|
calculateSize();
|
||||||
QPolygonF region = mapToParent(m_rect).intersected(parentWidget()->boundingRect());
|
QPolygonF region = m_applet->mapToParent(m_rect).intersected(m_applet->parentWidget()->boundingRect());
|
||||||
//kDebug() << region << m_rect << mapToParent(m_rect) << parentWidget()->boundingRect();
|
//kDebug() << region << m_rect << mapToParent(m_rect) << containmnet->boundingRect();
|
||||||
if (region != mapToParent(m_rect)) {
|
if (region != m_applet->mapToParent(m_rect)) {
|
||||||
// switch sides
|
// switch sides
|
||||||
//kDebug() << "switch sides";
|
//kDebug() << "switch sides";
|
||||||
m_buttonsOnRight = !m_buttonsOnRight;
|
m_buttonsOnRight = !m_buttonsOnRight;
|
||||||
calculateSize();
|
calculateSize();
|
||||||
QPolygonF region2 = mapToParent(m_rect).intersected(parentWidget()->boundingRect());
|
QPolygonF region2 = m_applet->mapToParent(m_rect).intersected(m_applet->parentWidget()->boundingRect());
|
||||||
if (region2 != mapToParent(m_rect)) {
|
if (region2 != mapToParent(m_rect)) {
|
||||||
// ok, both sides failed to be perfect... which one is more perfect?
|
// ok, both sides failed to be perfect... which one is more perfect?
|
||||||
QRectF f1 = region.boundingRect();
|
QRectF f1 = region.boundingRect();
|
||||||
@ -1007,7 +940,7 @@ void AppletHandle::calculateSize()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_rect = m_applet->mapToParent(m_rect).boundingRect();
|
//m_rect = m_applet->mapToParent(m_rect).boundingRect();
|
||||||
m_decorationRect = m_rect.adjusted(-marginLeft, -marginTop, marginRight, marginBottom);
|
m_decorationRect = m_rect.adjusted(-marginLeft, -marginTop, marginRight, marginBottom);
|
||||||
m_totalRect = m_decorationRect.united(m_applet->geometry());
|
m_totalRect = m_decorationRect.united(m_applet->geometry());
|
||||||
}
|
}
|
||||||
|
@ -73,7 +73,6 @@ class AppletHandle : public QObject, public QGraphicsItem
|
|||||||
void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
|
void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
|
||||||
void hoverMoveEvent(QGraphicsSceneHoverEvent *event);
|
void hoverMoveEvent(QGraphicsSceneHoverEvent *event);
|
||||||
void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
|
void hoverLeaveEvent(QGraphicsSceneHoverEvent *event);
|
||||||
QVariant itemChange(GraphicsItemChange change, const QVariant &value);
|
|
||||||
bool sceneEventFilter(QGraphicsItem *watched, QEvent *event);
|
bool sceneEventFilter(QGraphicsItem *watched, QEvent *event);
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
@ -125,7 +124,6 @@ class AppletHandle : public QObject, public QGraphicsItem
|
|||||||
|
|
||||||
QPoint m_mousePos; //mousepos relative to applet
|
QPoint m_mousePos; //mousepos relative to applet
|
||||||
QPointF m_entryPos; //where the hover in event occurred
|
QPointF m_entryPos; //where the hover in event occurred
|
||||||
QPointF m_pos; //current position of applet in sceneCoords
|
|
||||||
qreal m_zValue; //current zValue of the applet, so it can be restored after drag.
|
qreal m_zValue; //current zValue of the applet, so it can be restored after drag.
|
||||||
QRectF m_originalGeom;
|
QRectF m_originalGeom;
|
||||||
QTransform m_originalTransform;
|
QTransform m_originalTransform;
|
||||||
|
Loading…
Reference in New Issue
Block a user