From 972162123678dbf4fb7fcebf1b561b52488d1cb6 Mon Sep 17 00:00:00 2001 From: Simon Rettberg Date: Thu, 2 Aug 2018 18:44:39 +0200 Subject: [server] Show drop position when moving frame around --- src/server/connectionframe/connectionframe.cpp | 50 ++++++++++++++------------ src/server/connectionframe/connectionframe.h | 3 +- src/server/mainwindow/mainwindow.cpp | 34 ++++++++++++++---- src/server/mainwindow/mainwindow.h | 4 ++- 4 files changed, 58 insertions(+), 33 deletions(-) diff --git a/src/server/connectionframe/connectionframe.cpp b/src/server/connectionframe/connectionframe.cpp index e8d8349..c2bba70 100644 --- a/src/server/connectionframe/connectionframe.cpp +++ b/src/server/connectionframe/connectionframe.cpp @@ -60,6 +60,8 @@ static QString style_disconnected( static QIcon *term = nullptr, *cam = nullptr, *eye = nullptr, *lock = nullptr; +static const int START_DRAG_DISTANCE = 40; + bool ConnectionFrame::paintDisabled = false; /** @@ -217,26 +219,6 @@ void ConnectionFrame::updateLabels() calcDesiredThumbSize(this->size()); } -/** - * Handle mouse release event on frame. - * Check if frame was clicked or moved, if not moved enough, the event is handled as click. - * @param event - */ -void ConnectionFrame::mouseReleaseEvent(QMouseEvent* event) -{ - event->accept(); - if (event->button() == Qt::LeftButton) { - QApplication::setOverrideCursor(QCursor(Qt::OpenHandCursor)); - // Only recognize a move if the distance is larger than _startDragDistance - if ((this->pos() - _previousPosition).manhattanLength() > _startDragDistance ) { - emit frameMoved(this); - } else { - move(_previousPosition); - emit clicked(this); - } - } -} - /** * Handle if mouse reaches frame. * @param event @@ -263,18 +245,17 @@ void ConnectionFrame::leaveEvent(QEvent* event) */ void ConnectionFrame::mousePressEvent(QMouseEvent *event) { + event->accept(); if (event->button() == Qt::RightButton) { // Menu... - } else { + } else if (event->button() == Qt::LeftButton) { _clickPoint = event->pos(); _previousPosition = this->pos(); QApplication::setOverrideCursor(QCursor(Qt::ClosedHandCursor)); } // On click, the window has to be on the top-level. - activateWindow(); raise(); update(); - event->accept(); } /** @@ -283,9 +264,32 @@ void ConnectionFrame::mousePressEvent(QMouseEvent *event) */ void ConnectionFrame::mouseMoveEvent(QMouseEvent *event) { + event->accept(); QApplication::setOverrideCursor(QCursor(Qt::ClosedHandCursor)); move(mapToParent(event->pos() - _clickPoint)); + if ((this->pos() - _previousPosition).manhattanLength() > START_DRAG_DISTANCE) { + emit frameMoving(this); + } +} + +/** + * Handle mouse release event on frame. + * Check if frame was clicked or moved, if not moved enough, the event is handled as click. + * @param event + */ +void ConnectionFrame::mouseReleaseEvent(QMouseEvent* event) +{ event->accept(); + QApplication::setOverrideCursor(QCursor(Qt::OpenHandCursor)); + if (event->button() == Qt::LeftButton) { + // Only recognize a move if the distance is larger than _startDragDistance + if ((this->pos() - _previousPosition).manhattanLength() > START_DRAG_DISTANCE) { + emit frameMoved(this); + } else { + move(_previousPosition); + emit clicked(this); + } + } } /** diff --git a/src/server/connectionframe/connectionframe.h b/src/server/connectionframe/connectionframe.h index ba5f235..1d004e6 100644 --- a/src/server/connectionframe/connectionframe.h +++ b/src/server/connectionframe/connectionframe.h @@ -41,8 +41,6 @@ private: bool _isTutor; bool _isFromRoomplan; - static const int _startDragDistance = 40; - void showDefaultThumb(); void calcDesiredThumbSize(const QSize &frameSize); QLabel* addIcon(const QIcon* icon); @@ -85,6 +83,7 @@ protected: void timerEvent(QTimerEvent* event); signals: + void frameMoving(ConnectionFrame* frame); void frameMoved(ConnectionFrame* frame); void doubleClicked(ConnectionFrame* frame); void clicked(ConnectionFrame* frame); diff --git a/src/server/mainwindow/mainwindow.cpp b/src/server/mainwindow/mainwindow.cpp index 15aabd4..6ff8fc3 100644 --- a/src/server/mainwindow/mainwindow.cpp +++ b/src/server/mainwindow/mainwindow.cpp @@ -108,6 +108,9 @@ MainWindow::MainWindow(QWidget* parent) : _examModeLabel->setAlignment(Qt::AlignCenter); _examModeLabel->setFixedHeight(400); ui->toolBar->insertWidget(ui->action_TutorToStudent, _examModeLabel); + _dropMarker = new QLabel(ui->frmRoom); + _dropMarker->setStyleSheet("background-color: #448; border-radius: 2px;"); + _dropMarker->hide(); serverApp->setExam(false); @@ -258,7 +261,7 @@ QPoint MainWindow::closestFreeSlot(QPoint preferredPixels, ConnectionFrame* toIg } } const QSize& clientSize = serverApp->getCurrentRoom()->clientSize; -#define GRID(X,Y) (grid[((X) * _tilesX) + (Y)]) +#define GRID(X,Y) (grid[((X) * _tilesY) + (Y)]) bool *grid = new bool[_tilesX * _tilesY]; memset(grid, 0, sizeof(bool) * size_t(_tilesX * _tilesY)); /* set everything to false */ @@ -282,8 +285,9 @@ QPoint MainWindow::closestFreeSlot(QPoint preferredPixels, ConnectionFrame* toIg for ( int y = 0; y <= _tilesY - clientSize.height(); y++) { /* check if (x,y) is free */ bool isFree = true; - for (int dx = 0; dx < clientSize.width(); dx++) { - for (int dy = 0; dy < clientSize.height(); dy++) { + int dx, dy = 0; + for (dx = 0; dx < clientSize.width(); dx++) { + for (dy = 0; dy < clientSize.height(); dy++) { if (GRID(x + dx, y + dy)) { isFree = false; goto endLoop; // double-break @@ -302,8 +306,11 @@ endLoop: ; endSearch: ; #undef GRID delete[] grid; + if (freePositions.isEmpty() && toIgnore != nullptr) { + return toIgnore->getGridPosition(); + } /* among all the free positions, find the closest */ - int min_distance = 1000000; + int min_distance = 10000000; QPoint bestPosition = QPoint(0, 0); for (QPoint freePos : freePositions) { @@ -341,8 +348,9 @@ ConnectionFrame* MainWindow::createFrame(const QString &computerId, const QPoint cf->setComputerId(computerId); _clientFrames.append(cf); cf->show(); - connect(cf, SIGNAL(frameMoved(ConnectionFrame *)), this, SLOT(onPlaceFrame(ConnectionFrame *))); + connect(cf, SIGNAL(frameMoved(ConnectionFrame *)), this, SLOT(onFrameDropped(ConnectionFrame *))); connect(cf, SIGNAL(clicked(ConnectionFrame *)), this, SLOT(onFrameClicked(ConnectionFrame *))); + connect(cf, SIGNAL(frameMoving(ConnectionFrame *)), this, SLOT(onFrameMoving(ConnectionFrame *))); return cf; } @@ -602,13 +610,24 @@ void MainWindow::reset(bool lock) * Slots */ +void MainWindow::onFrameMoving(ConnectionFrame* connectionFrame) +{ + QPoint slot = closestFreeSlot(connectionFrame->pos(), connectionFrame); + _dropMarker->setGeometry(slot.x() * getTileWidthPx(), slot.y() * getTileHeightPx(), connectionFrame->width(), connectionFrame->height()); + if (!_dropMarker->isVisible()) { + _dropMarker->lower(); + ui->imageLabel->lower(); + _dropMarker->show(); + } +} /** * Place frame to from user specified position. Should be called when a * connectionFrame is dropped during the "drag-n-drop". */ -void MainWindow::onPlaceFrame(ConnectionFrame* connectionFrame) +void MainWindow::onFrameDropped(ConnectionFrame* connectionFrame) { + _dropMarker->hide(); // if (_tilesX <= 0 || _tilesY <= 0) return; const QPoint preferredPixels = connectionFrame->pos(); placeFrameInFreeSlot(connectionFrame, preferredPixels); @@ -622,6 +641,7 @@ void MainWindow::onPlaceFrame(ConnectionFrame* connectionFrame) */ void MainWindow::onFrameClicked(ConnectionFrame* frame) { + _dropMarker->hide(); ConnectionFrame *current = getSelectedFrame(); // If same frame is clicked again,, do nothing if (current == frame) @@ -743,7 +763,7 @@ void MainWindow::reloadCurrentRoom() QPoint pos = it.value(); ConnectionFrame *cf = createFrame(computerId, &pos, true); - onPlaceFrame(cf); + onFrameDropped(cf); if (computerId == room->tutorIP) { qDebug() << "set computer with id " << computerId << " as tutor per configuration"; if (getTutorFrame() != nullptr) { diff --git a/src/server/mainwindow/mainwindow.h b/src/server/mainwindow/mainwindow.h index f42fc73..a8bf974 100644 --- a/src/server/mainwindow/mainwindow.h +++ b/src/server/mainwindow/mainwindow.h @@ -69,6 +69,7 @@ private: int _streamingSource; QList _clientFrames; + QWidget *_dropMarker; ListenServer *_listenServer; DiscoveryListener *_discoveryListener; @@ -125,7 +126,8 @@ protected slots: void onButtonExit(); void onButtonHelp(); // connection frame - void onPlaceFrame(ConnectionFrame* frame); + void onFrameMoving(ConnectionFrame* frame); + void onFrameDropped(ConnectionFrame* frame); void onFrameClicked(ConnectionFrame* frame); // Net void onClientConnected(Client* client); -- cgit v1.2.3-55-g7522