--- 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; } }