Windows snapped to the mainwindow now move, if the mainwindow is moves

This commit is contained in:
Thomas Frauendorfer 2008-02-29 15:24:58 +01:00
parent c7531032d7
commit 77f8c332f1
4 changed files with 130 additions and 12 deletions

View file

@ -15,6 +15,7 @@
*/
#include "basewindow.h"
#include "mainwindow.h"
#include <QApplication>
#include <QWidgetList>
@ -25,10 +26,48 @@ BaseWindow::BaseWindow (QWidget *parent) : QMainWindow (parent)
{
}
bool
BaseWindow::touches (QWidget *widget)
{
if (this == widget) {
return true;
}
qint32 left = x ();
qint32 right = left + width ();
qint32 top = y ();
qint32 bottom = top + height ();
qint32 w_left = widget->x ();
qint32 w_right = w_left + widget->width ();
qint32 w_top = widget->y ();
qint32 w_bottom = w_top + widget->height ();
if (( (top <= w_bottom) && (bottom >= w_top) &&
((left == w_right || right == w_left)) ) ||
( (left <= w_right) && (right >= w_left) &&
((top == w_bottom) || (bottom == w_top) ) )) {
return true;
}
return false;
}
MainWindow *
BaseWindow::mw ()
{
//MainWindow is the only BaseWindow without a *parent
if (parent ()) {
return qobject_cast<MainWindow *>(parent ());
} else {
return qobject_cast<MainWindow *>(this);
}
}
void
BaseWindow::mousePressEvent (QMouseEvent *event)
{
if (event->buttons () & Qt::LeftButton) {
if (event->button () == Qt::LeftButton) {
m_diff = event->pos ();
}
}
@ -36,8 +75,9 @@ BaseWindow::mousePressEvent (QMouseEvent *event)
void
BaseWindow::mouseReleaseEvent (QMouseEvent *event)
{
if (event->buttons () & Qt::LeftButton) {
if (event->button () == Qt::LeftButton) {
m_diff = QPoint (0, 0);
mw ()->attachWidgets ();
}
}
@ -52,7 +92,7 @@ BaseWindow::mouseMoveEvent (QMouseEvent *event)
}
QPoint
BaseWindow::snapWindow(QPoint pos)
BaseWindow::snapWindow(QPoint pos, QWidgetList ignore)
{
//TODO: make snapdistance configurable
qint32 snapdistance = 10;
@ -62,9 +102,18 @@ BaseWindow::snapWindow(QPoint pos)
qint32 top = pos.y ();
qint32 bottom = top + height ();
qDebug ("top: %i, bottom: %i, left: %i, right: %i", top, bottom, left, right);
QWidgetList widgets = qApp->topLevelWidgets ();
QWidget *w;
// ignore widgets, MainWindow needs this for attached Widgets
if (!ignore.isEmpty ()) {
foreach (w, ignore) {
int i = widgets.indexOf (w);
if (i >= 0) {
widgets.removeAt (i);
}
}
}
// snap to left or right edge
bool snappedV = false;
bool snappedH = false;

View file

@ -21,20 +21,23 @@
class QMouseEvent;
class QPoint;
class MainWindow;
class BaseWindow : public QMainWindow {
Q_OBJECT
public:
BaseWindow (QWidget *parent);
bool touches (QWidget *);
MainWindow * mw ();
protected:
void mousePressEvent (QMouseEvent *event);
void mouseReleaseEvent (QMouseEvent *event);
void mouseMoveEvent (QMouseEvent *event);
QPoint snapWindow (QPoint pos);
private:
QPoint snapWindow (QPoint pos, QWidgetList ignore = QWidgetList());
QPoint m_diff;
};

View file

@ -31,6 +31,7 @@
#include <QSettings>
#include <QIcon>
#include <QPluginLoader>
#include <QMouseEvent>
#include <qplugin.h>
MainWindow::MainWindow (QWidget *parent) : BaseWindow (parent)
@ -125,6 +126,19 @@ MainWindow::raisePL (void)
m_playlistwin->raise ();
}
void
MainWindow::mouseMoveEvent (QMouseEvent *event)
{
if ((event->buttons () & Qt::LeftButton) && !m_diff.isNull ()) {
QWidgetList ignore;
QWidget *w;
foreach (w, m_attachedWidgets.keys ()) {
ignore.append (w);
}
move (snapWindow (event->globalPos() - m_diff, ignore));
}
}
void
MainWindow::moveEvent (QMoveEvent *event)
{
@ -133,12 +147,60 @@ MainWindow::moveEvent (QMoveEvent *event)
// move all connected windows to their new position
// at the moment connected windows can be m_playlistwin and m_equalizer
if (!m_connectedWidgets.isEmpty ()) {
QMap<QWidget *,QPoint>::const_iterator i
= m_connectedWidgets.constBegin ();
while (i != m_connectedWidgets.constEnd ()) {
if (!m_attachedWidgets.isEmpty ()) {
QMap<BaseWindow *,QPoint>::const_iterator i
= m_attachedWidgets.constBegin ();
while (i != m_attachedWidgets.constEnd ()) {
i.key()->move (pos () + i.value ());
++i;
}
}
}
void
MainWindow::attachWidgets ()
{
m_attachedWidgets.clear ();
QList<BaseWindow *> widgets;
QWidget *w;
foreach (w, qApp->topLevelWidgets ()) {
if (w == this) {
continue;
}
if (w->inherits ("BaseWindow")) {
widgets.append (qobject_cast<BaseWindow *> (w));
}
}
// attach widgets that directly touch MainWindow
BaseWindow *b;
foreach (b, widgets) {
if (b->touches (this)) {
m_attachedWidgets[b] = b->pos ()- pos ();
}
}
// now attach the windows, that indirectly touch mainwindow through an
// attached window
// widgets isn't modified, even if it might be more efficent, because
// that might produce some ugly, hard to trace bugs (modifying the
// base of an iterater while it is in use)
if (!m_attachedWidgets.isEmpty ()) {
bool found = false;
BaseWindow *att;
do {
found = false;
foreach (att, m_attachedWidgets.keys ()) {
foreach (b, widgets) {
if (m_attachedWidgets.contains (b)) {
continue;
}
if (att->touches (b)) {
m_attachedWidgets[b] = b->pos ()- pos ();
found = true;
}
}
}
} while (found);
}
}

View file

@ -20,6 +20,7 @@
#include <QSettings>
class QWidget;
class QMouseEvent;
class MainDisplay;
class ShadedDisplay;
@ -45,8 +46,11 @@ class MainWindow : public BaseWindow
bool isTimemodeReverse(void) { QSettings s; return s.value("MainWindow/timemodereverse").toBool(); }
void setTimemodeReverse(bool b) { QSettings s; return s.setValue("MainWindow/timemodereverse",b); }
void attachWidgets ();
public slots:
void switchDisplay ();
void mouseMoveEvent (QMouseEvent *event);
private:
bool isShaded (void) { QSettings s; return s.value("MainWindow/shaded").toBool(); }
@ -56,7 +60,7 @@ class MainWindow : public BaseWindow
EqualizerWindow *m_equalizer;
PlaylistWindow *m_playlistwin;
QMap<QWidget *,QPoint> m_connectedWidgets;
QMap<BaseWindow *,QPoint> m_attachedWidgets;
};