Improve info box placement behaviour in some corner cases

This commit is contained in:
Maxime Coste 2015-12-05 10:51:46 +00:00
parent eac6d63371
commit 39fffec104
2 changed files with 25 additions and 22 deletions

View File

@ -735,10 +735,9 @@ static CharCoord compute_needed_size(StringView str)
return res; return res;
} }
static CharCoord compute_pos(CharCoord anchor, CharCoord size, CharCoord scrsize, static CharCoord compute_pos(CharCoord anchor, CharCoord size,
CharCoord rect_to_avoid_pos = CharCoord{}, NCursesUI::Rect rect, NCursesUI::Rect to_avoid,
CharCoord rect_to_avoid_size = CharCoord{}, bool prefer_above)
bool prefer_above = false)
{ {
CharCoord pos; CharCoord pos;
if (prefer_above) if (prefer_above)
@ -747,30 +746,30 @@ static CharCoord compute_pos(CharCoord anchor, CharCoord size, CharCoord scrsize
if (pos.line < 0) if (pos.line < 0)
prefer_above = false; prefer_above = false;
} }
auto rect_end = rect.pos + rect.size;
if (not prefer_above) if (not prefer_above)
{ {
pos = anchor + CharCoord{1_line}; pos = anchor + CharCoord{1_line};
if (pos.line + size.line >= scrsize.line) if (pos.line + size.line > rect_end.line)
pos.line = max(0_line, anchor.line - size.line); pos.line = max(rect.pos.line, anchor.line - size.line);
} }
if (pos.column + size.column >= scrsize.column) if (pos.column + size.column > rect_end.column)
pos.column = max(0_char, scrsize.column - size.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 to_avoid_end = to_avoid.pos + to_avoid.size;
CharCoord rectend = rectbeg + rect_to_avoid_size;
CharCoord end = pos + size; CharCoord end = pos + size;
// check intersection // check intersection
if (not (end.line < rectbeg.line or end.column < rectbeg.column or if (not (end.line < to_avoid.pos.line or end.column < to_avoid.pos.column or
pos.line > rectend.line or pos.column > rectend.column)) 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 above does not work, try below
if (pos.line < 0) 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; 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) if (style == InfoStyle::MenuDoc and m_menu)
pos = m_menu.pos + CharCoord{0_line, m_menu.size.column}; pos = m_menu.pos + CharCoord{0_line, m_menu.size.column};
else else
pos = compute_pos(anchor, size, m_dimensions, m_menu.pos, m_menu.size, pos = compute_pos(anchor, size, rect, m_menu, style == InfoStyle::InlineAbove);
style == InfoStyle::InlineAbove);
// The info window will hide the status line // The info box does not fit
if (pos.line + size.line > m_dimensions.line) if (pos < rect.pos or pos + size > rect.pos + rect.size)
return; return;
m_info.create(pos, size); m_info.create(pos, size);

View File

@ -52,6 +52,12 @@ public:
CharCoord dimensions() override; CharCoord dimensions() override;
static void abort(); static void abort();
struct Rect
{
CharCoord pos;
CharCoord size;
};
private: private:
void check_resize(bool force = false); void check_resize(bool force = false);
void redraw(); void redraw();
@ -72,7 +78,7 @@ private:
UnorderedMap<ColorPair, int, MemoryDomain::Faces> m_colorpairs; UnorderedMap<ColorPair, int, MemoryDomain::Faces> m_colorpairs;
int m_next_color = 16; int m_next_color = 16;
struct Window struct Window : Rect
{ {
void create(const CharCoord& pos, const CharCoord& size); void create(const CharCoord& pos, const CharCoord& size);
void destroy(); void destroy();
@ -81,8 +87,6 @@ private:
explicit operator bool() const { return win; } explicit operator bool() const { return win; }
NCursesWin* win = nullptr; NCursesWin* win = nullptr;
CharCoord pos;
CharCoord size;
}; };
void mark_dirty(const Window& win); void mark_dirty(const Window& win);