Windows snapped to the mainwindow now move, if the mainwindow is moves
This commit is contained in:
parent
c7531032d7
commit
77f8c332f1
4 changed files with 130 additions and 12 deletions
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue