diff -r 19be47c9bab7 -r 35b968619b0c sources/interface.cpp --- a/sources/interface.cpp Mon Dec 15 21:59:24 2014 +0200 +++ b/sources/interface.cpp Mon Dec 15 22:35:17 2014 +0200 @@ -52,6 +52,7 @@ static bool g_needStatusBarRender = false; static bool g_needInputRender = false; static bool g_needOutputRender = false; +static bool g_needNicklistRender = false; static struct { char ch; int x; } g_cursorChar; static Vector g_output;; static int g_outputScroll = 0; @@ -60,6 +61,7 @@ static Function g_disconnectConfirmFunction = nullptr; static IPAddress g_address; static String g_statusBarText; +static StringList g_playerNames; // ------------------------------------------------------------------------------------------------- // @@ -247,6 +249,82 @@ // ------------------------------------------------------------------------------------------------- // static FUNCTION +inteface_nicklist_width() -> int +{ + // Allocate at least 12 characters, at most 24 characters, for the nicklist. If we cannot + // afford that (o_O) then we probably shouldn't draw the nicklist at all I think. + int nicklistWidth = COLS / 4; + + if (nicklistWidth < 12) + return 0; + + return min (nicklistWidth, 24); +} + +// ------------------------------------------------------------------------------------------------- +// Renders the given colored line onto the screen. Will wrap if allowWrap is true. Returns the +// 'y' value for the next line. +// +static FUNCTION +interface_render_colorline (int y, int x0, int width, + const ColoredLine& line, bool allowWrap) -> int +{ + int x = x0; + + for (int byte : line.data()) + { + if (x == x0 + width) + { + if (not allowWrap) + return y; + + x = x0; + ++y; + } + + if (isprint (byte)) + { + mvaddch (y, x, char (byte)); + ++x; + } + else switch (byte) + { + case RLINE_ON_BLACK: + case RLINE_ON_GREEN: + case RLINE_ON_YELLOW: + case RLINE_ON_BLUE: + case RLINE_ON_MAGENTA: + case RLINE_ON_CYAN: + case RLINE_ON_WHITE: + attron (interface_color_pair (Color (byte - RLINE_ON_BLACK), DEFAULT)); + break; + + case RLINE_OFF_BLACK: + case RLINE_OFF_GREEN: + case RLINE_OFF_YELLOW: + case RLINE_OFF_BLUE: + case RLINE_OFF_MAGENTA: + case RLINE_OFF_CYAN: + case RLINE_OFF_WHITE: + attroff (interface_color_pair (Color (byte - RLINE_OFF_BLACK), DEFAULT)); + break; + + case RLINE_ON_BOLD: + attron (A_BOLD); + break; + + case RLINE_OFF_BOLD: + attroff (A_BOLD); + break; + } + } + + return y + 1; +} + +// ------------------------------------------------------------------------------------------------- +// +static FUNCTION interface_render_output() -> void { if (g_output.size() == 1) @@ -255,6 +333,7 @@ g_outputScroll = clamp (g_outputScroll, 0, g_output.size() - 1); int height = LINES - 3; + int width = COLS - inteface_nicklist_width(); int printOffset = 0; int end = g_output.size() - 1 - g_outputScroll; int start = end; @@ -265,7 +344,7 @@ // Where to start? while (start > 0) { - int rows = g_output[start - 1].rows (COLS); + int rows = g_output[start - 1].rows (width); if (usedHeight + rows > height) { @@ -283,7 +362,7 @@ { while (end < g_output.size()) { - int rows = g_output[end].rows (COLS); + int rows = g_output[end].rows (width); if (usedHeight + rows > height) { @@ -308,61 +387,52 @@ // Clear the display for (int i = y; i < y + height; ++i) - mvhline (i, 0, ' ', COLS); + mvhline (i, 0, ' ', width); // Print the lines y += printOffset; for (int i = start; i < end; ++i) + y = interface_render_colorline (y, 0, width, g_output[i], true); + + g_needOutputRender = false; + g_needRefresh = true; +} + +// ------------------------------------------------------------------------------------------------- +// +static FUNCTION +interface_render_nicklist() -> void +{ + int width = inteface_nicklist_width(); + int height = LINES- 3; + int y = 1; + int x = COLS - width; + + if (width == 0) + return; + + for (int i = 0; i < height; ++i) { - int x = 0; + mvhline (y, x, ' ', width); - for (int byte : g_output[i].data()) + if (i < g_playerNames.size()) { - if (x == COLS) + String displaynick = g_playerNames[i]; + + if (displaynick.length() > width) { - x = 0; - ++y; + displaynick = displaynick.mid (0, width - 3); + displaynick += "..."; } - if (isprint (byte)) - mvaddch (y, x++, char (byte)); - else switch (byte) - { - case RLINE_ON_BLACK: - case RLINE_ON_GREEN: - case RLINE_ON_YELLOW: - case RLINE_ON_BLUE: - case RLINE_ON_MAGENTA: - case RLINE_ON_CYAN: - case RLINE_ON_WHITE: - attron (interface_color_pair (Color (byte - RLINE_ON_BLACK), DEFAULT)); - break; - - case RLINE_OFF_BLACK: - case RLINE_OFF_GREEN: - case RLINE_OFF_YELLOW: - case RLINE_OFF_BLUE: - case RLINE_OFF_MAGENTA: - case RLINE_OFF_CYAN: - case RLINE_OFF_WHITE: - attroff (interface_color_pair (Color (byte - RLINE_OFF_BLACK), DEFAULT)); - break; - - case RLINE_ON_BOLD: - attron (A_BOLD); - break; - - case RLINE_OFF_BOLD: - attroff (A_BOLD); - break; - } + mvprintw (y, x, "%s", displaynick.chars()); } - ++y; + y++; } - g_needOutputRender = false; + g_needNicklistRender = false; g_needRefresh = true; } @@ -494,6 +564,7 @@ interface_render_output(); interface_render_statusbar(); interface_render_input(); + interface_render_nicklist(); } // ------------------------------------------------------------------------------------------------- @@ -816,6 +887,7 @@ if (g_needStatusBarRender) interface_render_statusbar(); if (g_needInputRender) interface_render_input(); if (g_needOutputRender) interface_render_output(); + if (g_needNicklistRender) interface_render_nicklist(); if (g_needRefresh) { @@ -870,3 +942,12 @@ session->set_password (password); session->connect (g_address); } + +// ------------------------------------------------------------------------------------------------- +// +FUNCTION +Interface::set_player_names (const StringList& names) -> void +{ + g_playerNames = names; + g_needNicklistRender = true; +}