sources/interface.cpp

changeset 27
089e37c0887e
parent 25
88b41eea08e0
child 28
3cc042af3090
--- a/sources/interface.cpp	Sun Dec 14 23:41:00 2014 +0200
+++ b/sources/interface.cpp	Mon Dec 15 01:41:06 2014 +0200
@@ -50,13 +50,14 @@
 static bool g_needStatusBarRender = false;
 static bool g_needInputRender = false;
 static bool g_needOutputRender = false;
-static String g_statusBarText;
 static struct { char ch; int x; } g_cursorChar;
 static Vector<String> g_output = {""};
 static int g_outputScroll = 0;
 static String g_title;
 static InputState g_inputState = INPUTSTATE_NORMAL;
+static Function<void (void)> g_disconnectConfirmFunction = nullptr;
 static IPAddress g_address;
+static String g_statusBarText;
 
 // -------------------------------------------------------------------------------------------------
 //
@@ -86,6 +87,33 @@
 
 // -------------------------------------------------------------------------------------------------
 //
+static FUNCTION
+set_input_state (InputState newstate) -> void
+{
+	// Clear the input row (unless going to or from confirm state)
+	if (newstate != INPUTSTATE_CONFIRM_DISCONNECTION
+		and g_inputState != INPUTSTATE_CONFIRM_DISCONNECTION)
+	{
+		g_input.clear();
+	}
+
+	switch (newstate)
+	{
+	case INPUTSTATE_ADDRESS:
+		if (g_address.host != 0)
+			g_input = g_address.to_string (IP_WITH_PORT);
+		break;
+
+	default:
+		break;
+	}
+
+	g_inputState = newstate;
+	g_needInputRender = true;
+}
+
+// -------------------------------------------------------------------------------------------------
+//
 FUNCTION
 Interface::initialize() -> void
 {
@@ -111,13 +139,6 @@
 	g_needRefresh = false;
 	print ("Interface initialized.\n");
 }
-// -------------------------------------------------------------------------------------------------
-//
-static FUNCTION
-interface_sessions_width() -> int
-{
-	return COLS / 3;
-}
 
 // -------------------------------------------------------------------------------------------------
 //
@@ -151,6 +172,21 @@
 // -------------------------------------------------------------------------------------------------
 //
 static FUNCTION
+safe_disconnect (Function<void()> afterwards) -> void
+{
+	if (RCONSession::get_session() != nullptr
+		and RCONSession::get_session()->state() != RCON_DISCONNECTED)
+	{
+		g_disconnectConfirmFunction = afterwards;
+		set_input_state (INPUTSTATE_CONFIRM_DISCONNECTION);
+	}
+	else
+		afterwards();
+}
+
+// -------------------------------------------------------------------------------------------------
+//
+static FUNCTION
 interface_render_output() -> void
 {
 	int height = LINES - 3;
@@ -233,20 +269,62 @@
 static FUNCTION
 interface_render_statusbar() -> void
 {
+	int color = interface_color_pair (WHITE, BLUE);
 	int y = LINES - 1;
+	attron (color);
 	mvhline (y, 0, ' ', COLS);
 	mvprintw (y, 0, "%s", g_statusBarText.chars());
+	attroff (color);
 	g_needRefresh = true;
 	g_needStatusBarRender = false;
 }
 
 // -------------------------------------------------------------------------------------------------
 //
-static FUNCTION
-set_statusbar_text (const String& a) -> void
+FUNCTION
+Interface::update_statusbar() -> void
 {
-	g_statusBarText = a;
-	g_needStatusBarRender = true;
+	String text;
+	RCONSession* session = RCONSession::get_session();
+
+	if (session == nullptr)
+	{
+		text = "[DISCONNECTED]";
+	}
+	else
+	{
+		switch (session->state())
+		{
+		case RCON_DISCONNECTED:
+			text = "[DISCONNECTED]";
+			break;
+
+		case RCON_CONNECTING:
+		case RCON_AUTHENTICATING:
+			text = "Connecting to " + session->address().to_string (IP_WITH_PORT) + "...";
+			break;
+
+		case RCON_CONNECTED:
+			{
+				String adminText;
+
+				if (session->num_admins() == 0)
+					adminText = "No other admins";
+				else
+					adminText = format ("%1 other admin%s1", session->num_admins());
+
+				text = format ("%1 | %2 | %3", session->address().to_string (IP_WITH_PORT),
+					session->level(), adminText);
+			}
+			break;
+		}
+	}
+
+	if (text != g_statusBarText)
+	{
+		g_statusBarText = text;
+		g_needStatusBarRender = true;
+	}
 }
 
 // -------------------------------------------------------------------------------------------------
@@ -254,6 +332,7 @@
 FUNCTION
 Interface::render_full() -> void
 {
+	update_statusbar();
 	interface_render_titlebar();
 	interface_render_output();
 	interface_render_statusbar();
@@ -279,43 +358,15 @@
 
 // -------------------------------------------------------------------------------------------------
 //
-static FUNCTION
-set_input_state (InputState newstate) -> void
-{
-	// Clear the input row (unless going to or from confirm state)
-	if (newstate != INPUTSTATE_CONFIRM_DISCONNECTION
-		and g_inputState != INPUTSTATE_CONFIRM_DISCONNECTION)
-	{
-		g_input.clear();
-	}
-
-	switch (newstate)
-	{
-	case INPUTSTATE_ADDRESS:
-		if (g_address.host != 0)
-			g_input = g_address.to_string (IP_WITH_PORT);
-		break;
-
-	default:
-		break;
-	}
-
-	g_inputState = newstate;
-	g_needInputRender = true;
-}
-
-// -------------------------------------------------------------------------------------------------
-//
 FUNCTION
 Interface::handle_input() -> void
 {
 	int ch = ::getch();
-	set_statusbar_text (String::from_number (ch));
 
 	if (g_inputState == INPUTSTATE_CONFIRM_DISCONNECTION)
 	{
 		if (ch == 'y' or ch == 'Y')
-			set_input_state (INPUTSTATE_ADDRESS);
+			g_disconnectConfirmFunction();
 		else if (ch == 'n' or ch == 'N')
 			set_input_state (INPUTSTATE_NORMAL);
 		return;
@@ -328,9 +379,34 @@
 	}
 	else switch (ch)
 	{
-	case KEY_F(1):
-		endwin();
-		exit (EXIT_SUCCESS);
+	case 'Q' - 'A' + 1: // ^Q
+		switch (g_inputState)
+		{
+		case INPUTSTATE_CONFIRM_DISCONNECTION:
+			break;
+
+		case INPUTSTATE_NORMAL:
+			safe_disconnect ([]()
+			{
+				endwin();
+				throw Exitception();
+			});
+			break;
+
+		case INPUTSTATE_PASSWORD:
+			set_input_state (INPUTSTATE_ADDRESS);
+			break;
+
+		case INPUTSTATE_ADDRESS:
+			set_input_state (INPUTSTATE_NORMAL);
+		}
+		break;
+
+	case '\e':
+		if (g_inputState == INPUTSTATE_PASSWORD)
+			set_input_state (INPUTSTATE_ADDRESS);
+		else if (g_inputState == INPUTSTATE_ADDRESS)
+			set_input_state (INPUTSTATE_NORMAL);
 		break;
 
 	case KEY_LEFT:
@@ -438,17 +514,7 @@
 
 	case 'N' - 'A' + 1: // ^N
 		if (g_inputState == INPUTSTATE_NORMAL)
-		{
-			if (RCONSession::get_session() != nullptr
-				and RCONSession::get_session()->state() != RCON_DISCONNECTED)
-			{
-				set_input_state (INPUTSTATE_CONFIRM_DISCONNECTION);
-			}
-			else
-			{
-				set_input_state (INPUTSTATE_ADDRESS);
-			}
-		}
+			safe_disconnect ([]() {set_input_state (INPUTSTATE_ADDRESS);});
 		break;
 	}
 }

mercurial