From 39fffec104c7e9e65baa16c220e9fe4b4a2f56bc Mon Sep 17 00:00:00 2001 From: Maxime Coste Date: Sat, 5 Dec 2015 10:51:46 +0000 Subject: [PATCH] Improve info box placement behaviour in some corner cases --- src/ncurses_ui.cc | 37 ++++++++++++++++++------------------- src/ncurses_ui.hh | 10 +++++++--- 2 files changed, 25 insertions(+), 22 deletions(-) diff --git a/src/ncurses_ui.cc b/src/ncurses_ui.cc index 09298c8e..5f39260f 100644 --- a/src/ncurses_ui.cc +++ b/src/ncurses_ui.cc @@ -735,10 +735,9 @@ static CharCoord compute_needed_size(StringView str) return res; } -static CharCoord compute_pos(CharCoord anchor, CharCoord size, CharCoord scrsize, - CharCoord rect_to_avoid_pos = CharCoord{}, - CharCoord rect_to_avoid_size = CharCoord{}, - bool prefer_above = false) +static CharCoord compute_pos(CharCoord anchor, CharCoord size, + NCursesUI::Rect rect, NCursesUI::Rect to_avoid, + bool prefer_above) { CharCoord pos; if (prefer_above) @@ -747,30 +746,30 @@ static CharCoord compute_pos(CharCoord anchor, CharCoord size, CharCoord scrsize if (pos.line < 0) prefer_above = false; } + auto rect_end = rect.pos + rect.size; if (not prefer_above) { pos = anchor + CharCoord{1_line}; - if (pos.line + size.line >= scrsize.line) - pos.line = max(0_line, anchor.line - size.line); + if (pos.line + size.line > rect_end.line) + pos.line = max(rect.pos.line, anchor.line - size.line); } - if (pos.column + size.column >= scrsize.column) - pos.column = max(0_char, scrsize.column - size.column); + if (pos.column + size.column > rect_end.column) + pos.column = max(rect.pos.column, rect_end.column - size.column); - if (rect_to_avoid_size != CharCoord{}) + if (to_avoid.size != CharCoord{}) { - CharCoord rectbeg = rect_to_avoid_pos; - CharCoord rectend = rectbeg + rect_to_avoid_size; + CharCoord to_avoid_end = to_avoid.pos + to_avoid.size; CharCoord end = pos + size; // check intersection - if (not (end.line < rectbeg.line or end.column < rectbeg.column or - pos.line > rectend.line or pos.column > rectend.column)) + if (not (end.line < to_avoid.pos.line or end.column < to_avoid.pos.column or + pos.line > to_avoid_end.line or pos.column > to_avoid_end.column)) { - pos.line = min(rectbeg.line, anchor.line) - size.line; + pos.line = min(to_avoid.pos.line, anchor.line) - size.line; // if above does not work, try below if (pos.line < 0) - pos.line = max(rectend.line, anchor.line); + pos.line = max(to_avoid_end.line, anchor.line); } } @@ -865,14 +864,14 @@ void NCursesUI::info_show(StringView title, StringView content, } CharCoord size = compute_needed_size(info_box), pos; + const Rect rect = {m_status_on_top ? 1_line : 0_line, m_dimensions}; if (style == InfoStyle::MenuDoc and m_menu) pos = m_menu.pos + CharCoord{0_line, m_menu.size.column}; else - pos = compute_pos(anchor, size, m_dimensions, m_menu.pos, m_menu.size, - style == InfoStyle::InlineAbove); + pos = compute_pos(anchor, size, rect, m_menu, style == InfoStyle::InlineAbove); - // The info window will hide the status line - if (pos.line + size.line > m_dimensions.line) + // The info box does not fit + if (pos < rect.pos or pos + size > rect.pos + rect.size) return; m_info.create(pos, size); diff --git a/src/ncurses_ui.hh b/src/ncurses_ui.hh index 997bb469..59cf8846 100644 --- a/src/ncurses_ui.hh +++ b/src/ncurses_ui.hh @@ -52,6 +52,12 @@ public: CharCoord dimensions() override; static void abort(); + + struct Rect + { + CharCoord pos; + CharCoord size; + }; private: void check_resize(bool force = false); void redraw(); @@ -72,7 +78,7 @@ private: UnorderedMap m_colorpairs; int m_next_color = 16; - struct Window + struct Window : Rect { void create(const CharCoord& pos, const CharCoord& size); void destroy(); @@ -81,8 +87,6 @@ private: explicit operator bool() const { return win; } NCursesWin* win = nullptr; - CharCoord pos; - CharCoord size; }; void mark_dirty(const Window& win);