sources/interface.cpp

changeset 47
35b968619b0c
parent 46
19be47c9bab7
child 48
02009f1ec2b7
--- 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<ColoredLine> g_output;;
 static int g_outputScroll = 0;
@@ -60,6 +61,7 @@
 static Function<void (void)> 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;
+}

mercurial