summaryrefslogtreecommitdiffstats
path: root/src/server/mainwindow/mainwindow.cpp
diff options
context:
space:
mode:
authorChristian Klinger2016-05-23 10:19:36 +0200
committerChristian Klinger2016-05-23 10:19:36 +0200
commit6f06aba6d7e52378d6192c631917f69a1b5d0f2e (patch)
tree12051e894c22e6aa4e9cc0871bc5b05843840d2b /src/server/mainwindow/mainwindow.cpp
parentmoved the camera icon closer to the PVS logo. (diff)
downloadpvs2-6f06aba6d7e52378d6192c631917f69a1b5d0f2e.tar.gz
pvs2-6f06aba6d7e52378d6192c631917f69a1b5d0f2e.tar.xz
pvs2-6f06aba6d7e52378d6192c631917f69a1b5d0f2e.zip
Improved positioning into the grid. (Pixel-precise calculations).
Diffstat (limited to 'src/server/mainwindow/mainwindow.cpp')
-rw-r--r--src/server/mainwindow/mainwindow.cpp119
1 files changed, 51 insertions, 68 deletions
diff --git a/src/server/mainwindow/mainwindow.cpp b/src/server/mainwindow/mainwindow.cpp
index 76f5e00..88ed17d 100644
--- a/src/server/mainwindow/mainwindow.cpp
+++ b/src/server/mainwindow/mainwindow.cpp
@@ -174,53 +174,64 @@ float distance(QPoint a, QPoint b) {
int sum = dx*dx + dy*dy;
return sqrt((float) sum);
}
+
+float distance(QPointF a, QPointF b) {
+ int dx = a.x() - b.x();
+ int dy = a.y() - b.y();
+ int sum = dx*dx + dy*dy;
+ return sqrt(sum);
+}
+
+
+
/***************************************************************************//**
- * Place the frame into a free position that is closest (Euclidean distance) to
- * the preferred point.
+ * \brief: find the closest available frame.
+ *
+ * Closest: smallest Euclidean distance from center to center
*
- * If current position out of range, place frame into the closest free cell.
* 'Algorithm': ideally, go in circles around the preferred point until you find
* a free spot. Lazy way: store all free positions in an array and find later
* there the closest (<- that's what I do)
*
- * @param frame
+ * @param preferred in Pixels!
+ * @param toIgnore, ignore this connectionframe when considering free slots
+ * @return the free slot
*/
-void MainWindow::placeFrameInFreeSlot(ConnectionFrame* frame, QPoint preferred)
-{
+QPoint MainWindow::closestFreeSlot(QPoint preferredPixels, ConnectionFrame* toIgnore) {
const QSize& clientSize = Global::getCurrentRoom()->clientSize;
- /* Get occupied cell of each frame and store status in an array */
bool grid[_tilesX][_tilesY];
- memset(grid, 0, sizeof(bool) * _tilesX * _tilesY); // set everything to false
+ memset(grid, 0, sizeof(bool) * _tilesX * _tilesY); /* set everything to false */
/* fill grid */
- for (QList<ConnectionFrame*>::iterator it(_clientFrames.begin()); it != _clientFrames.end(); ++it)
- {
- const QPoint& position = (*it)->getGridPosition();
-
- for (int x = position.x(); x < position.x() + clientSize.width(); x++) {
- for (int y = position.y(); y < position.y() + clientSize.height(); y++) {
+ for (auto it = _clientFrames.begin(); it != _clientFrames.end(); ++it) {
+
+ if (*it == toIgnore) { continue; }
+
+ const QPoint& p = (*it)->getGridPosition();
+
+ for (int x = p.x(); x < p.x() + clientSize.width(); x++) {
+ for (int y = p.y(); y < p.y() + clientSize.height(); y++) {
grid[x][y] = true;
}
}
}
- /* Now place in next free cell, start looking at current position of frame */
- vector<QPoint> freePositions;
+ QList<QPoint> freePositions;
+ /* check all positions to see if they are available */
for (int x = 0; x <= _tilesX - clientSize.width(); x++) {
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.width(); dy++) {
+ for (int dy = 0; dy < clientSize.height(); dy++) {
if (grid[x + dx][y + dy]) {
isFree = false;
+ goto endLoop; // double-break
}
}
}
- if (isFree) {
- QPoint freePos(x,y);
- freePositions.push_back(freePos);
- }
+endLoop:
+ if (isFree) { freePositions << QPoint(x,y); }
}
}
/* among all the free positions, find the closest */
@@ -228,12 +239,22 @@ void MainWindow::placeFrameInFreeSlot(ConnectionFrame* frame, QPoint preferred)
QPoint bestPosition = QPoint(-1, -1);
for (QPoint freePos : freePositions) {
- float dist = distance(freePos, preferred);
+ QPoint freePosCenter( freePos.x() * getTileWidthPx() + getTileWidthPx() * clientSize.width() / 2,
+ freePos.y() * getTileHeightPx() + getTileHeightPx() * clientSize.height() / 2);
+ float dist = distance(freePosCenter, preferredPixels);
if (dist < min_distance) {
min_distance = dist;
bestPosition = freePos;
}
}
+ return bestPosition;
+}
+
+/* place frame in the cloest available spot */
+void MainWindow::placeFrameInFreeSlot(ConnectionFrame* frame, QPoint preferredPixels) {
+
+ QPoint bestPosition = closestFreeSlot(preferredPixels, frame);
+
frame->setGridPosition(bestPosition);
QPoint freePosPx(bestPosition.x() * getTileWidthPx(), bestPosition.y() * getTileHeightPx());
frame->setCurrentPosition(freePosPx);
@@ -652,56 +673,17 @@ void MainWindow::reset()
/***************************************************************************//**
-* Place Frame to from user specified position.
-* Behaviour: If placed exactly on another frame: replace that frame and place it
-* on the closest free slot. Otherwise: place connectionFrame on the closest free
-* slot.
+* Place frame to from user specified position. Should be called when a
+* connectionFrame is dropped during the "drag-n-drop".
*/
void MainWindow::onPlaceFrame(bool activateTrash, ConnectionFrame* connectionFrame)
{
- if (_tilesX <= 0 || _tilesY <= 0)
- return;
- const QPoint &p = connectionFrame->frameGeometry().center();
- const QSize &s = ui->frmRoom->geometry().size();
- /* round to grid */
- int x = p.x() / getTileWidthPx();
- int y = p.y() / getTileHeightPx();
- if (x < 0) {
- x = 0;
- } else if (x > s.width() - getTileWidthPx()) {
- qDebug() << "oopsie";
- x = (_tilesX - 1);
- }
- if (y < 0) {
- y = 0;
- } else if (y > s.height() - getTileHeightPx()) {
- qDebug() << "oopsie2";
- y = (_tilesY - 1);
- }
- /* --- */
-
- QPoint newPos(x,y);
- connectionFrame->setGridPosition(newPos);
- placeFrameInFreeSlot(connectionFrame, newPos);
-
- /* if there is already a frame at that position, push it away */
- bool replacedFrame = false;
- for (auto it = _clientFrames.begin(); it != _clientFrames.end(); ++it) {
- if (*it == connectionFrame) { continue; }
-
- if ((*it)->getGridPosition() == newPos) {
- connectionFrame->setGridPosition(newPos);
- placeFrameInFreeSlot(*it, newPos); /* place frame in free slot, close to newPos */
- replacedFrame = true;
- break;
- }
- }
- if (!replacedFrame) {
- placeFrameInFreeSlot(connectionFrame, newPos);
- }
- /* update positions */
+ // if (_tilesX <= 0 || _tilesY <= 0) return;
+ const QPoint &preferredPixels = connectionFrame->frameGeometry().center();
+ placeFrameInFreeSlot(connectionFrame, preferredPixels);
- savePosition(connectionFrame); /* save in local config to remember position */
+ /* save in local config to remember position */
+ savePosition(connectionFrame);
resizeEvent(NULL);
}
@@ -724,6 +706,7 @@ void MainWindow::onFrameClicked(ConnectionFrame* frame)
frame->setSelection(true);
qDebug() << "ID of frame: " << frame->computerId();
qDebug() << "ID of selectedFrame: " << getSelectedFrame()->computerId();
+ qDebug() << "position of selectedFrame: " << getSelectedFrame()->getGridPosition();
unlockContextButtons();
}