diff --git a/client/dialogs.cpp b/client/dialogs.cpp index b40b737ec7..c89452d940 100644 --- a/client/dialogs.cpp +++ b/client/dialogs.cpp @@ -987,6 +987,7 @@ void popup_notify_dialog(const char *caption, const char *headline, freeciv::report_widget *nd = new freeciv::report_widget( caption, headline, lines, queen()->mapview_wdg); + nd->move(queen()->mapview_wdg->find_place(nd->size())); nd->show(); } diff --git a/client/views/view_map.cpp b/client/views/view_map.cpp index 8ed4d197e2..9ef403bfee 100644 --- a/client/views/view_map.cpp +++ b/client/views/view_map.cpp @@ -59,14 +59,6 @@ extern int last_center_capital; extern int last_center_player_city; extern int last_center_enemy_city; -/** - Check if point x, y is in area (px -> pxe, py - pye) - */ -bool is_point_in_area(int x, int y, int px, int py, int pxe, int pye) -{ - return x >= px && y >= py && x <= pxe && y <= pye; -} - /** Draws calculated trade routes */ @@ -400,105 +392,43 @@ void map_view::wheelEvent(QWheelEvent *event) } /** - Sets new point for new search + * Finds a suitable location for a widget of the given size, avoiding overlap + * with other widgets. */ -void map_view::resume_searching(int pos_x, int pos_y, int &w, int &h, - int wdth, int hght, int recursive_nr, - bool direction) +QPoint map_view::find_place(const QSize &size) const { - int new_pos_x, new_pos_y; + // We scan all possible locations from left to right and from top to + // bottom. At each step we check for overlap with other widgets. We return + // the first point without overlap. + const auto step = 5; - recursive_nr++; - new_pos_x = pos_x; - new_pos_y = pos_y; + // This is the rectangle that would be covered by the widget. + auto candidate = QRect(QPoint(), size); - if (direction) { - if (pos_y + hght + 4 < height() && pos_x < width() / 2) { - new_pos_y = pos_y + 5; - } else if (pos_x > 0 && pos_y > 10) { - new_pos_x = pos_x - 5; - } else if (pos_y > 0) { - new_pos_y = pos_y - 5; - } else if (pos_x + wdth + 4 < this->width()) { - new_pos_x = pos_x + 5; - } - } else { - if (pos_y + hght + 4 < height() && pos_x > width() / 2) { - new_pos_y = pos_y + 5; - } else if (pos_x > 0 && pos_y > 10) { - new_pos_x = pos_x - 5; - } else if (pos_y > 0) { - new_pos_y = pos_y - 5; - } else if (pos_x + wdth + 4 < this->width()) { - new_pos_x = pos_x + 5; + const auto children = findChildren(); + while (candidate.bottom() < height()) { + // Check if the candidate rectangle intersects with another widget + if (!std::any_of(children.begin(), children.end(), + [candidate](const QWidget *child) { + return child->isVisible() + && candidate.intersects(child->rect()); + })) { + // We found a good location + return candidate.topLeft(); } - } - - find_place(new_pos_x, new_pos_y, w, h, wdth, hght, recursive_nr, - direction); -} -/** - Searches place for widget with size w and height h - Starts looking from position pos_x, pos_y, going clockwork - Returns position as (w,h) - Along with resume_searching its recursive function. - direction = false (default) = clockwise - */ -void map_view::find_place(int pos_x, int pos_y, int &w, int &h, int wdth, - int hght, int recursive_nr, bool direction) -{ - int i; - int x, y, xe, ye; - QList widgets = this->findChildren(); - bool cont_searching = false; - - if (recursive_nr >= 1000) { - /** - * give up searching position - */ - return; - } - /** - * try position pos_x, pos_y, - * check middle and borders if aren't above other widget - */ - - for (i = 0; i < widgets.count(); i++) { - if (!widgets[i]->isVisible()) { - continue; - } - x = widgets[i]->pos().x(); - y = widgets[i]->pos().y(); - - if (x == 0 && y == 0) { - continue; - } - xe = widgets[i]->pos().x() + widgets[i]->width(); - ye = widgets[i]->pos().y() + widgets[i]->height(); - - if (is_point_in_area(pos_x, pos_y, x, y, xe, ye)) { - cont_searching = true; - } - if (is_point_in_area(pos_x + wdth, pos_y, x, y, xe, ye)) { - cont_searching = true; - } - if (is_point_in_area(pos_x + wdth, pos_y + hght, x, y, xe, ye)) { - cont_searching = true; - } - if (is_point_in_area(pos_x, pos_y + hght, x, y, xe, ye)) { - cont_searching = true; - } - if (is_point_in_area(pos_x + wdth / 2, pos_y + hght / 2, x, y, xe, ye)) { - cont_searching = true; + // Move the candidate rectangle to the next point + if (candidate.right() + step < width()) { + // Step right + candidate.moveTo(candidate.left() + step, candidate.top()); + } else { + // Next line + candidate.moveTo(0, candidate.top() + step); } } - w = pos_x; - h = pos_y; - if (cont_searching) { - resume_searching(pos_x, pos_y, w, h, wdth, hght, recursive_nr, - direction); - } + + // We didn't find any solution :'( + return QPoint(); } /** diff --git a/client/views/view_map.h b/client/views/view_map.h index f8cddc2ee0..282832146e 100644 --- a/client/views/view_map.h +++ b/client/views/view_map.h @@ -54,10 +54,9 @@ class map_view : public QWidget { public: map_view(); - void find_place(int pos_x, int pos_y, int &w, int &h, int wdth, int hght, - int recursive_nr, bool direction = false); - void resume_searching(int pos_x, int pos_y, int &w, int &h, int wdtht, - int hght, int recursive_nr, bool direction); + + QPoint find_place(const QSize &size) const; + void update_cursor(enum cursor_type); void hide_all_fcwidgets(); @@ -105,6 +104,7 @@ private slots: double m_scale = 1; std::unique_ptr m_origin_animation; std::unique_ptr m_scale_animation; + QPointer m_debugger = nullptr; std::vector> m_hidden_fcwidgets; }; diff --git a/client/widgets/report_widget.cpp b/client/widgets/report_widget.cpp index d2f7525e65..993d9f90ca 100644 --- a/client/widgets/report_widget.cpp +++ b/client/widgets/report_widget.cpp @@ -8,10 +8,8 @@ #include "widgets/report_widget.h" // client -#include "dialogs_g.h" #include "fc_client.h" #include "fonts.h" -#include "page_game.h" #include "views/view_map.h" // Qt @@ -55,12 +53,6 @@ report_widget::report_widget(const QString &caption, const QString &headline, auto cw = new close_widget(this); cw->setFixedSize(12, 12); cw->put_to_corner(); - - auto x = width(); - auto y = height(); - queen()->mapview_wdg->find_place(queen()->mapview_wdg->width() - x - 4, 4, - x, y, x, y, 0); - move(x, y); } /**