MCPcopy Create free account
hub / github.com/OpenTTD/OpenTTD / GetAutoPlacePosition

Function GetAutoPlacePosition

src/window.cpp:1617–1677  ·  view source on GitHub ↗

* Find a good place for opening a new window of a given width and height. * @param width Width of the new window * @param height Height of the new window * @return Top-left coordinate of the new window */

Source from the content-addressed store, hash-verified

1615 * @return Top-left coordinate of the new window
1616 */
1617static Point GetAutoPlacePosition(int width, int height)
1618{
1619 Point pt;
1620
1621 bool rtl = _current_text_dir == TD_RTL;
1622
1623 /* First attempt, try top-left of the screen */
1624 const Window *main_toolbar = FindWindowByClass(WC_MAIN_TOOLBAR);
1625 const int toolbar_y = main_toolbar != nullptr ? main_toolbar->height : 0;
1626 if (IsGoodAutoPlace1(rtl ? _screen.width - width : 0, toolbar_y, width, height, toolbar_y, pt)) return pt;
1627
1628 /* Second attempt, try around all existing windows.
1629 * The new window must be entirely on-screen, and not overlap with an existing window.
1630 * Eight starting points are tried, two at each corner.
1631 */
1632 for (const Window *w : Window::Iterate()) {
1633 if (w->window_class == WC_MAIN_WINDOW) continue;
1634
1635 if (IsGoodAutoPlace1(w->left + w->width, w->top, width, height, toolbar_y, pt)) return pt;
1636 if (IsGoodAutoPlace1(w->left - width, w->top, width, height, toolbar_y, pt)) return pt;
1637 if (IsGoodAutoPlace1(w->left, w->top + w->height, width, height, toolbar_y, pt)) return pt;
1638 if (IsGoodAutoPlace1(w->left, w->top - height, width, height, toolbar_y, pt)) return pt;
1639 if (IsGoodAutoPlace1(w->left + w->width, w->top + w->height - height, width, height, toolbar_y, pt)) return pt;
1640 if (IsGoodAutoPlace1(w->left - width, w->top + w->height - height, width, height, toolbar_y, pt)) return pt;
1641 if (IsGoodAutoPlace1(w->left + w->width - width, w->top + w->height, width, height, toolbar_y, pt)) return pt;
1642 if (IsGoodAutoPlace1(w->left + w->width - width, w->top - height, width, height, toolbar_y, pt)) return pt;
1643 }
1644
1645 /* Third attempt, try around all existing windows.
1646 * The new window may be partly off-screen, and must not overlap with an existing window.
1647 * Only four starting points are tried.
1648 */
1649 for (const Window *w : Window::Iterate()) {
1650 if (w->window_class == WC_MAIN_WINDOW) continue;
1651
1652 if (IsGoodAutoPlace2(w->left + w->width, w->top, width, height, toolbar_y, pt)) return pt;
1653 if (IsGoodAutoPlace2(w->left - width, w->top, width, height, toolbar_y, pt)) return pt;
1654 if (IsGoodAutoPlace2(w->left, w->top + w->height, width, height, toolbar_y, pt)) return pt;
1655 if (IsGoodAutoPlace2(w->left, w->top - height, width, height, toolbar_y, pt)) return pt;
1656 }
1657
1658 /* Fourth and final attempt, put window at diagonal starting from (0, toolbar_y), try multiples
1659 * of the closebox
1660 */
1661 int left = rtl ? _screen.width - width : 0, top = toolbar_y;
1662 int offset_x = rtl ? -(int)NWidgetLeaf::closebox_dimension.width : (int)NWidgetLeaf::closebox_dimension.width;
1663 int offset_y = std::max<int>(NWidgetLeaf::closebox_dimension.height, GetCharacterHeight(FS_NORMAL) + WidgetDimensions::scaled.captiontext.Vertical());
1664
1665restart:
1666 for (const Window *w : Window::Iterate()) {
1667 if (w->left == left && w->top == top) {
1668 left += offset_x;
1669 top += offset_y;
1670 goto restart;
1671 }
1672 }
1673
1674 pt.x = left;

Callers 1

LocalGetWindowPlacementFunction · 0.85

Calls 5

FindWindowByClassFunction · 0.85
IsGoodAutoPlace1Function · 0.85
IsGoodAutoPlace2Function · 0.85
GetCharacterHeightFunction · 0.85
VerticalMethod · 0.80

Tested by

no test coverage detected