--- a/sources/interface.cpp Mon Jan 25 04:15:31 2016 +0200 +++ b/sources/interface.cpp Wed Jul 20 12:55:39 2016 +0300 @@ -1,5 +1,5 @@ /* - Copyright 2014, 2015 Teemu Piippo + Copyright 2014 - 2016 Teemu Piippo All rights reserved. Redistribution and use in source and binary forms, with or without @@ -37,20 +37,23 @@ #include "coloredline.h" BEGIN_ZFC_NAMESPACE -static const int g_pageSize = 10; +static const int PAGE_SIZE = 10; // ------------------------------------------------------------------------------------------------- // chtype Interface::color_pair (Color fg, Color bg) { - return COLOR_PAIR (1 + (int (fg) * NUM_COLORS) + int (bg)); + if (fg == DEFAULT && bg == DEFAULT) + return 0; + else + return COLOR_PAIR (1 + (int (fg) * NUM_COLORS) + int (bg)); } // ------------------------------------------------------------------------------------------------- // const String& Interface::current_input() { - return InputHistory[InputCursor]; + return m_inputHistory[m_inputCursor]; } // ------------------------------------------------------------------------------------------------- @@ -59,10 +62,10 @@ // void Interface::detach_input() { - if (InputCursor > 0) + if (m_inputCursor > 0) { - InputHistory[0] = current_input(); - InputCursor = 0; + m_inputHistory[0] = current_input(); + m_inputCursor = 0; } } @@ -72,7 +75,7 @@ String& Interface::mutable_current_input() { detach_input(); - return InputHistory[InputCursor]; + return m_inputHistory[m_inputCursor]; } // ------------------------------------------------------------------------------------------------- @@ -80,19 +83,19 @@ void Interface::move_input_cursor (int delta) { // No input history when inputting addresses or passwords - if (CurrentInputState != INPUTSTATE_NORMAL) + if (m_inputState != INPUTSTATE_NORMAL) { - InputCursor = 0; + m_inputCursor = 0; return; } - int oldcursor = InputCursor; - InputCursor = clamp (InputCursor + delta, 0, InputHistory.size() - 1); + int oldcursor = m_inputCursor; + m_inputCursor = clamp (m_inputCursor + delta, 0, m_inputHistory.size() - 1); - if (InputCursor != oldcursor) + if (m_inputCursor != oldcursor) { - CursorPosition = current_input().length(); - NeedInputRender = true; + m_cursorPosition = current_input().length(); + m_needInputRender = true; } } @@ -102,7 +105,7 @@ { String prompt; - switch (CurrentInputState) + switch (m_inputState) { case INPUTSTATE_NORMAL: prompt = ">"; break; case INPUTSTATE_ADDRESS: prompt = "address:"; break; @@ -119,41 +122,41 @@ { // Clear the input row (unless going to or from confirm state) if (newstate != INPUTSTATE_CONFIRM_DISCONNECTION - and CurrentInputState != INPUTSTATE_CONFIRM_DISCONNECTION) + and m_inputState != INPUTSTATE_CONFIRM_DISCONNECTION) { - InputCursor = 0; + m_inputCursor = 0; mutable_current_input().clear(); } switch (newstate) { case INPUTSTATE_ADDRESS: - if (CurrentAddress.host != 0) - mutable_current_input() = CurrentAddress.to_string (IPAddress::WITH_PORT); + if (m_remoteAddress.host != 0) + mutable_current_input() = m_remoteAddress.to_string (IPAddress::WITH_PORT); break; default: break; } - CurrentInputState = newstate; - NeedInputRender = true; + m_inputState = newstate; + m_needInputRender = true; } // ------------------------------------------------------------------------------------------------- // Interface::Interface() : - InputCursor (0), - CursorPosition (0), - InputPanning (0), - NeedRefresh (false), - NeedStatusBarRender (false), - NeedInputRender (false), - NeedOutputRender (false), - NeedNicklistRender (false), - OutputScroll (0), - CurrentInputState (INPUTSTATE_NORMAL), - DisconnectConfirmFunction (nullptr) + m_inputCursor (0), + m_cursorPosition (0), + m_inputPanning (0), + m_needRefresh (false), + m_needStatusBarRender (false), + m_needInputRender (false), + m_needOutputRender (false), + m_needNicklistRender (false), + m_outputScroll (0), + m_inputState (INPUTSTATE_NORMAL), + m_disconnectCallback (nullptr) { ::initscr(); ::raw(); @@ -161,20 +164,19 @@ ::noecho(); ::refresh(); ::timeout (0); - InputHistory.clear(); - InputHistory << ""; - OutputLines.clear(); - OutputLines << ColoredLine(); - Session.set_interface (this); - Title.sprintf (APPNAME " %s (%s)", full_version_string(), changeset_date_string()); + m_inputHistory.clear(); + m_inputHistory << ""; + m_outputLines.clear(); + m_outputLines << ColoredLine(); + m_session.set_interface (this); + reset_title(); if (::has_colors()) { ::start_color(); - ::use_default_colors(); - - int defaultFg = (use_default_colors() == OK) ? -1 : COLOR_WHITE; - int defaultBg = (use_default_colors() == OK) ? -1 : COLOR_BLACK; + bool hasDefaultColors = (::use_default_colors() == OK); + int defaultFg = hasDefaultColors ? -1 : COLOR_WHITE; + int defaultBg = hasDefaultColors ? -1 : COLOR_BLACK; // Initialize color pairs for (int i = 0; i < NUM_COLORS; ++i) @@ -184,58 +186,57 @@ int fg = (i == DEFAULT) ? defaultFg : i; int bg = (j == DEFAULT) ? defaultBg : j; - if (::init_pair (pairnum, fg, bg) == ERR) - print ("Unable to initialize color pair %d (%d, %d)\n", pairnum, fg, bg); + if (fg != -1 || bg != -1) + { + if (::init_pair (pairnum, fg, bg) == ERR) + print_warning ("Unable to initialize color pair %d (%d, %d)\n", pairnum, fg, bg); + } } } - else - { - print ("This terminal does not appear to support colors.\n"); - } render_full(); refresh(); - NeedRefresh = false; + m_needRefresh = false; } // ------------------------------------------------------------------------------------------------- // void Interface::render_titlebar() { - if (Title.length() <= COLS) + if (m_title.length() <= COLS) { chtype pair = color_pair (WHITE, BLUE); - int startx = (COLS - Title.length()) / 2; - int endx = startx + Title.length(); + int startx = (COLS - m_title.length()) / 2; + int endx = startx + m_title.length(); attron (pair); - mvprintw (0, startx, "%s", Title.chars()); + mvprintw (0, startx, "%s", m_title.chars()); mvhline (0, 0, ' ', startx); mvhline (0, endx, ' ', COLS - endx); attroff (pair); } - NeedRefresh = true; + m_needRefresh = true; } // ------------------------------------------------------------------------------------------------- // void Interface::set_title (const String& title) { - Title = title; + m_title = title; render_titlebar(); } // ------------------------------------------------------------------------------------------------- // -void Interface::safe_disconnect (std::function<void()> afterwards) +void Interface::safe_disconnect (std::function<void(bool)> afterwards) { - if (Session.is_active()) + if (m_session.is_active()) { - DisconnectConfirmFunction = afterwards; + m_disconnectCallback = afterwards; set_input_state (INPUTSTATE_CONFIRM_DISCONNECTION); } else - afterwards(); + afterwards(false); } // ------------------------------------------------------------------------------------------------- @@ -302,15 +303,15 @@ // void Interface::render_output() { - if (OutputLines.size() == 1) + if (m_outputLines.size() == 1) return; - OutputScroll = clamp (OutputScroll, 0, OutputLines.size() - 1); + m_outputScroll = clamp (m_outputScroll, 0, m_outputLines.size() - 1); int height = LINES - 3; int width = COLS - nicklist_width(); int printOffset = 0; - int end = OutputLines.size() - 1 - OutputScroll; + int end = m_outputLines.size() - 1 - m_outputScroll; int start = end; int usedHeight = 0; int y = 1; @@ -319,7 +320,7 @@ // Where to start? while (start > 0) { - int rows = OutputLines[start - 1].rows (width); + int rows = m_outputLines[start - 1].rows (width); if (usedHeight + rows > height) { @@ -335,9 +336,9 @@ // See if there's any more rows to use (end may be too small) if (not tightFit) { - while (end < OutputLines.size()) + while (end < m_outputLines.size()) { - int rows = OutputLines[end].rows (width); + int rows = m_outputLines[end].rows (width); if (usedHeight + rows > height) { @@ -353,7 +354,7 @@ if (start > 0) printOffset = height - usedHeight; - OutputScroll = OutputLines.size() - 1 - end; + m_outputScroll = m_outputLines.size() - 1 - end; if (start < 0 or start == end or printOffset >= height) return; @@ -368,10 +369,10 @@ y += printOffset; for (int i = start; i < end; ++i) - y = render_colorline (y, 0, width, OutputLines[i], true); + y = render_colorline (y, 0, width, m_outputLines[i], true); - NeedOutputRender = false; - NeedRefresh = true; + m_needOutputRender = false; + m_needRefresh = true; } // ------------------------------------------------------------------------------------------------- @@ -390,9 +391,9 @@ { mvhline (y, x, ' ', width); - if (i < PlayerNames.size()) + if (i < m_playerNames.size()) { - String displaynick = PlayerNames[i]; + String displaynick = m_playerNames[i]; if (displaynick.length() > width) { @@ -406,8 +407,8 @@ y++; } - NeedNicklistRender = false; - NeedRefresh = true; + m_needNicklistRender = false; + m_needRefresh = true; } // ------------------------------------------------------------------------------------------------- @@ -418,13 +419,13 @@ // If we're asking the user if they want to disconnect, we don't render any input strings, // just the confirmation message. - if (CurrentInputState == INPUTSTATE_CONFIRM_DISCONNECTION) + if (m_inputState == INPUTSTATE_CONFIRM_DISCONNECTION) { attron (promptColor); mvhline (LINES - 2, 0, ' ', COLS); mvprintw (LINES - 2, 0, "Are you sure you want to disconnect? y/n"); attroff (promptColor); - NeedRefresh = true; + m_needRefresh = true; return; } @@ -434,25 +435,25 @@ int y = LINES - 2; // If we're inputting a password, replace it with asterisks - if (CurrentInputState == INPUTSTATE_PASSWORD) + if (m_inputState == INPUTSTATE_PASSWORD) { for (int i = 0; i < displayString.length(); ++i) displayString[i] = '*'; } // Ensure the cursor is within bounds - CursorPosition = clamp (CursorPosition, 0, displayString.length()); + m_cursorPosition = clamp (m_cursorPosition, 0, displayString.length()); // Ensure that the cursor is always in view, adjust panning if this is not the case - if (CursorPosition > InputPanning + displayLength) - InputPanning = CursorPosition - displayLength; // cursor went too far right - else if (CursorPosition < InputPanning) - InputPanning = CursorPosition; // cursor went past the pan value to the left + if (m_cursorPosition > m_inputPanning + displayLength) + m_inputPanning = m_cursorPosition - displayLength; // cursor went too far right + else if (m_cursorPosition < m_inputPanning) + m_inputPanning = m_cursorPosition; // cursor went past the pan value to the left // What part of the string to draw? - int start = InputPanning; + int start = m_inputPanning; int end = min<int> (displayString.length(), start + displayLength); - assert (CursorPosition >= start and CursorPosition <= end); + assert (m_cursorPosition >= start and m_cursorPosition <= end); // Render the input string mvhline (LINES - 2, 0, ' ', COLS); @@ -465,10 +466,10 @@ // Store in memory where the cursor is now (so that we can re-draw it to position the terminal // cursor). - CursorCharacter.ch = CursorPosition != 0 ? displayString[CursorPosition - 1] : '\0'; - CursorCharacter.x = prompt.length() + (CursorPosition - InputPanning); - NeedRefresh = true; - NeedInputRender = false; + m_cursorCharacter.ch = m_cursorPosition != 0 ? displayString[m_cursorPosition - 1] : '\0'; + m_cursorCharacter.x = prompt.length() + (m_cursorPosition - m_inputPanning); + m_needRefresh = true; + m_needInputRender = false; } // ------------------------------------------------------------------------------------------------- @@ -479,10 +480,10 @@ int y = LINES - 1; attron (color); mvhline (y, 0, ' ', COLS); - mvprintw (y, 0, "%s", StatusBarText.chars()); + mvprintw (y, 0, "%s", m_statusBarText.chars()); attroff (color); - NeedRefresh = true; - NeedStatusBarRender = false; + m_needRefresh = true; + m_needStatusBarRender = false; } // ------------------------------------------------------------------------------------------------- @@ -491,7 +492,7 @@ { String text; - switch (Session.state()) + switch (m_session.state()) { case RCON_DISCONNECTED: text = "Disconnected."; @@ -499,26 +500,26 @@ case RCON_CONNECTING: case RCON_AUTHENTICATING: - text = "Connecting to " + Session.address().to_string (IPAddress::WITH_PORT) + "..."; + text = "Connecting to " + m_session.address().to_string (IPAddress::WITH_PORT) + "..."; break; case RCON_CONNECTED: { String adminText; - if (Session.num_admins() == 0) + if (m_session.num_admins() == 0) { adminText = "No other admins"; } else { - adminText.sprintf ("%d other admin%s", Session.num_admins(), - Session.num_admins() != 1 ? "s" : ""); + adminText.sprintf ("%d other admin%s", m_session.num_admins(), + m_session.num_admins() != 1 ? "s" : ""); } text.sprintf ("%s | %s | %s", - Session.address().to_string (IPAddress::WITH_PORT).chars(), - Session.level().chars(), + m_session.address().to_string (IPAddress::WITH_PORT).chars(), + m_session.level().chars(), adminText.chars()); } break; @@ -527,12 +528,13 @@ if (not text.is_empty()) text += " | "; - text += "Ctrl+N to connect, Ctrl+Q to quit"; + text += "Ctrl+N to connect, Ctrl+Q to "; + text += (m_session.state() == RCON_DISCONNECTED) ? "quit" : "disconnect"; - if (text != StatusBarText) + if (text != m_statusBarText) { - StatusBarText = text; - NeedStatusBarRender = true; + m_statusBarText = text; + m_needStatusBarRender = true; } } @@ -553,13 +555,13 @@ void Interface::position_cursor() { // This is only relevant if the input string is being drawn - if (CurrentInputState == INPUTSTATE_CONFIRM_DISCONNECTION) + if (m_inputState == INPUTSTATE_CONFIRM_DISCONNECTION) return; int y = LINES - 2; - if (CursorCharacter.ch != '\0') - mvprintw (y, CursorCharacter.x, "%c", CursorCharacter.ch); + if (m_cursorCharacter.ch != '\0') + mvprintw (y, m_cursorCharacter.x, "%c", m_cursorCharacter.ch); else mvprintw (y, prompt_string().length(), " "); } @@ -569,7 +571,7 @@ int Interface::find_previous_word() { const String& input = current_input(); - int pos = CursorPosition; + int pos = m_cursorPosition; // Move past whitespace while (pos > 0 and isspace (input[pos - 1])) @@ -587,7 +589,7 @@ int Interface::find_next_word() { const String& input = current_input(); - int pos = CursorPosition; + int pos = m_cursorPosition; // Move past current whitespace while (pos < input.length() and isspace (input[pos])) @@ -607,13 +609,13 @@ if (a >= b) return; - if (CursorPosition > a and CursorPosition <= b) - CursorPosition = a; + if (m_cursorPosition > a and m_cursorPosition <= b) + m_cursorPosition = a; String& input = mutable_current_input(); - PasteBuffer = input.mid (a, b); + m_pasteBuffer = input.mid (a, b); input.remove (a, b - a); - NeedInputRender = true; + m_needInputRender = true; } // ------------------------------------------------------------------------------------------------- @@ -632,7 +634,7 @@ return; } - if (CurrentInputState == INPUTSTATE_CONFIRM_DISCONNECTION) + if (m_inputState == INPUTSTATE_CONFIRM_DISCONNECTION) { if (ch == 'y' or ch == 'Y') disconnected(); @@ -644,23 +646,22 @@ if (ch >= 0x20 and ch <= 0x7E) { - mutable_current_input().insert (CursorPosition++, char (ch)); - NeedInputRender = true; + mutable_current_input().insert (m_cursorPosition++, char (ch)); + m_needInputRender = true; } else switch (ch) { case 'Q' - 'A' + 1: // ^Q - switch (CurrentInputState) + switch (m_inputState) { case INPUTSTATE_CONFIRM_DISCONNECTION: break; case INPUTSTATE_NORMAL: - safe_disconnect ([&]() + safe_disconnect ([&](bool hadsession) { - if (Session.is_active()) + if (hadsession) { - Session.disconnect(); set_input_state (INPUTSTATE_NORMAL); } else @@ -682,19 +683,19 @@ case KEY_LEFT: case 'B' - 'A' + 1: // readline ^B - if (CursorPosition > 0) + if (m_cursorPosition > 0) { - CursorPosition--; - NeedInputRender = true; + m_cursorPosition--; + m_needInputRender = true; } break; case KEY_RIGHT: case 'F' - 'A' + 1: // readline ^F - if (CursorPosition < current_input().length()) + if (m_cursorPosition < current_input().length()) { - CursorPosition++; - NeedInputRender = true; + m_cursorPosition++; + m_needInputRender = true; } break; @@ -705,72 +706,72 @@ case KEY_HOME: case 'A' - 'A' + 1: // readline ^A - if (CursorPosition != 0) + if (m_cursorPosition != 0) { - CursorPosition = 0; - NeedInputRender = true; + m_cursorPosition = 0; + m_needInputRender = true; } break; case KEY_END: case 'E' - 'A' + 1: // readline ^E - if (CursorPosition != current_input().length()) + if (m_cursorPosition != current_input().length()) { - CursorPosition = current_input().length(); - NeedInputRender = true; + m_cursorPosition = current_input().length(); + m_needInputRender = true; } break; case KEY_BACKSPACE: case '\b': - if (CursorPosition > 0) + if (m_cursorPosition > 0) { - mutable_current_input().remove_at (--CursorPosition); - NeedInputRender = true; + mutable_current_input().remove_at (--m_cursorPosition); + m_needInputRender = true; } break; case KEY_DC: case 'D' - 'A' + 1: // readline ^D - if (CursorPosition < current_input().length()) + if (m_cursorPosition < current_input().length()) { - mutable_current_input().remove_at (CursorPosition); - NeedInputRender = true; + mutable_current_input().remove_at (m_cursorPosition); + m_needInputRender = true; } break; case KEY_PPAGE: - OutputScroll += min (g_pageSize, LINES / 2); - NeedOutputRender = true; + m_outputScroll += min (PAGE_SIZE, LINES / 2); + m_needOutputRender = true; break; case KEY_NPAGE: - OutputScroll -= min (g_pageSize, LINES / 2); - NeedOutputRender = true; + m_outputScroll -= min (PAGE_SIZE, LINES / 2); + m_needOutputRender = true; break; case 'U' - 'A' + 1: // readline ^U - delete from start to cursor - if (CursorPosition > 0) + if (m_cursorPosition > 0) { - yank (0, CursorPosition); - CursorPosition = 0; + yank (0, m_cursorPosition); + m_cursorPosition = 0; } break; case 'K' - 'A' + 1: // readline ^K - delete from cursor to end - yank (CursorPosition, mutable_current_input().length()); + yank (m_cursorPosition, mutable_current_input().length()); break; case 'W' - 'A' + 1: // readline ^W - delete from previous word bounary to current - yank (find_previous_word(), CursorPosition); + yank (find_previous_word(), m_cursorPosition); break; case 'Y' - 'A' + 1: // readline ^Y - paste previously deleted text - if (not PasteBuffer.is_empty()) + if (not m_pasteBuffer.is_empty()) { - mutable_current_input().insert (CursorPosition, PasteBuffer); - CursorPosition += PasteBuffer.length(); - NeedInputRender = true; + mutable_current_input().insert (m_cursorPosition, m_pasteBuffer); + m_cursorPosition += m_pasteBuffer.length(); + m_needInputRender = true; } break; @@ -778,12 +779,12 @@ { int space = current_input().find (" "); - if (CurrentInputState == INPUTSTATE_NORMAL - and CursorPosition > 0 - and (space == -1 or space >= CursorPosition)) + if (m_inputState == INPUTSTATE_NORMAL + and m_cursorPosition > 0 + and (space == -1 or space >= m_cursorPosition)) { - String start = current_input().mid (0, CursorPosition); - Session.request_tab_complete (start); + String start = current_input().mid (0, m_cursorPosition); + m_session.request_tab_complete (start); } } break; @@ -791,7 +792,7 @@ case '\n': case '\r': case KEY_ENTER: - switch (CurrentInputState) + switch (m_inputState) { case INPUTSTATE_CONFIRM_DISCONNECTION: break; // handled above @@ -799,7 +800,7 @@ case INPUTSTATE_ADDRESS: try { - CurrentAddress = IPAddress::from_string (current_input()); + m_remoteAddress = IPAddress::from_string (current_input()); } catch (std::exception& e) { @@ -807,18 +808,18 @@ return; } - if (CurrentAddress.port == 0) - CurrentAddress.port = 10666; + if (m_remoteAddress.port == 0) + m_remoteAddress.port = 10666; set_input_state (INPUTSTATE_PASSWORD); break; case INPUTSTATE_PASSWORD: - if (CurrentInputState == INPUTSTATE_PASSWORD and not current_input().is_empty()) + if (m_inputState == INPUTSTATE_PASSWORD and not current_input().is_empty()) { - Session.disconnect(); - Session.set_password (current_input()); - Session.connect (CurrentAddress); + m_session.disconnect(); + m_session.set_password (current_input()); + m_session.connect (m_remoteAddress); set_input_state (INPUTSTATE_NORMAL); } break; @@ -827,21 +828,19 @@ if (current_input()[0] == '/') { handle_command(current_input()); - InputHistory.insert (0, ""); - NeedInputRender = true; + flush_input(); } - else if (Session.send_command (current_input())) + else if (m_session.send_command (current_input())) { - InputHistory.insert (0, ""); - NeedInputRender = true; + flush_input(); } break; } break; case 'N' - 'A' + 1: // ^N - if (CurrentInputState == INPUTSTATE_NORMAL) - safe_disconnect ([&]() {set_input_state (INPUTSTATE_ADDRESS);}); + if (m_inputState == INPUTSTATE_NORMAL) + safe_disconnect ([&](bool){set_input_state (INPUTSTATE_ADDRESS);}); break; case '\x1b': // Escape @@ -855,30 +854,35 @@ case 'b': case 'B': // readline alt-b - move one word to the left - CursorPosition = find_previous_word(); - NeedInputRender = true; + m_cursorPosition = find_previous_word(); + m_needInputRender = true; break; case 'f': case 'F': // readline alt-f - move one word to the right - CursorPosition = find_next_word(); - NeedInputRender = true; + m_cursorPosition = find_next_word(); + m_needInputRender = true; break; case 'd': case 'D': // readline alt-d - delete from here till next word boundary - yank (CursorPosition, find_next_word()); + yank (m_cursorPosition, find_next_word()); + break; + + case KEY_BACKSPACE: // alt+backspace, remove previous word + case '\b': + yank (find_previous_word(), m_cursorPosition); break; } } else { // No alt-key, handle pure escape - if (CurrentInputState == INPUTSTATE_PASSWORD) + if (m_inputState == INPUTSTATE_PASSWORD) set_input_state (INPUTSTATE_ADDRESS); - else if (CurrentInputState == INPUTSTATE_ADDRESS) + else if (m_inputState == INPUTSTATE_ADDRESS) set_input_state (INPUTSTATE_NORMAL); } break; @@ -891,16 +895,16 @@ // void Interface::render() { - if (NeedStatusBarRender) render_statusbar(); - if (NeedInputRender) render_input(); - if (NeedOutputRender) render_output(); - if (NeedNicklistRender) render_nicklist(); + if (m_needStatusBarRender) render_statusbar(); + if (m_needInputRender) render_input(); + if (m_needOutputRender) render_output(); + if (m_needNicklistRender) render_nicklist(); - if (NeedRefresh) + if (m_needRefresh) { position_cursor(); refresh(); - NeedRefresh = false; + m_needRefresh = false; } } @@ -915,10 +919,21 @@ // ------------------------------------------------------------------------------------------------- // +void __cdecl Interface::print_text (const char* fmtstr, ...) +{ + va_list args; + va_start (args, fmtstr); + vprint (fmtstr, args); + va_end (args); +} + +// ------------------------------------------------------------------------------------------------- +// void __cdecl Interface::print (const char* fmtstr, ...) { va_list args; va_start (args, fmtstr); + print_to_console (TEXTCOLOR_BrightBlue); vprint (fmtstr, args); va_end (args); } @@ -931,7 +946,6 @@ va_start (args, fmtstr); print_to_console (TEXTCOLOR_BrightYellow "-!- "); vprint (fmtstr, args); - print_to_console (TEXTCOLOR_Reset); va_end (args); } @@ -943,7 +957,6 @@ va_start (args, fmtstr); print_to_console (TEXTCOLOR_BrightRed "!!! "); vprint (fmtstr, args); - print_to_console (TEXTCOLOR_Reset); va_end (args); } @@ -961,12 +974,12 @@ if (ch == '\n') { - OutputLines.last().finalize(); - OutputLines << ColoredLine(); + m_outputLines.last().finalize(); + m_outputLines << ColoredLine(); continue; } - if (OutputLines.last().length() == 0) + if (m_outputLines.last().length() == 0) { time_t now; time (&now); @@ -974,13 +987,17 @@ strftime (timestamp, sizeof timestamp, "[%H:%M:%S] ", localtime (&now)); for (char* cp = timestamp; *cp != '\0'; ++cp) - OutputLines.last().add_char (*cp); + m_outputLines.last().add_char (*cp); } - OutputLines.last().add_char (ch); + // Remove some lines if there's too many of them. 20,000 should be enough, I hope. + while (m_outputLines.size() > 20000) + m_outputLines.remove_at(0); + + m_outputLines.last().add_char (ch); } - NeedOutputRender = true; + m_needOutputRender = true; } // ------------------------------------------------------------------------------------------------- @@ -989,7 +1006,7 @@ { try { - CurrentAddress = IPAddress::from_string (address); + m_remoteAddress = IPAddress::from_string (address); } catch (std::exception& e) { @@ -997,20 +1014,20 @@ return; } - if (CurrentAddress.port == 0) - CurrentAddress.port = 10666; + if (m_remoteAddress.port == 0) + m_remoteAddress.port = 10666; - Session.disconnect(); - Session.set_password (password); - Session.connect (CurrentAddress); + m_session.disconnect(); + m_session.set_password (password); + m_session.connect (m_remoteAddress); } // ------------------------------------------------------------------------------------------------- // void Interface::set_player_names (const StringList& names) { - PlayerNames = names; - NeedNicklistRender = true; + m_playerNames = names; + m_needNicklistRender = true; } // ------------------------------------------------------------------------------------------------- @@ -1025,21 +1042,13 @@ complete += ' '; input.replace (0, part.length(), complete); - CursorPosition = complete.length(); - NeedInputRender = true; + m_cursorPosition = complete.length(); + m_needInputRender = true; } } // ------------------------------------------------------------------------------------------------- // -void Interface::disconnected() -{ - Session.disconnect(); - set_input_state (INPUTSTATE_NORMAL); -} - -// ------------------------------------------------------------------------------------------------- -// void Interface::handle_command(const String& input) { if (input[0] != '/') @@ -1052,7 +1061,9 @@ if (command == "connect") { if (args.size() != 2) - print_error("Usage: /connect <address> <password>"); + { + print_error("Usage: /connect <address> <password>\n"); + } else { IPAddress address; @@ -1070,21 +1081,25 @@ if (address.port == 0) address.port = 10666; - Session.set_password(args[1]); - Session.disconnect(); - Session.connect(CurrentAddress = address); + m_session.set_password(args[1]); + m_session.disconnect(); + m_session.connect(m_remoteAddress = address); } } + else if (command == "disconnect") + { + m_session.disconnect(); + } else if (command == "quit") { - Session.disconnect(); + m_session.disconnect(); endwin(); throw Exitception(); } else if (command == "watch") { if (not args.is_empty()) - Session.request_watch(args); + m_session.request_watch(args); else print_error("No CVars to watch.\n"); } @@ -1092,4 +1107,29 @@ print_error("Unknown command %s\n", command.chars()); } +// ------------------------------------------------------------------------------------------------- +// +void Interface::disconnected() +{ + print("Disconnected from %s\n", m_session.address().to_string(IPAddress::WITH_PORT).chars()); + reset_title(); + render_full(); +} + +// ------------------------------------------------------------------------------------------------- +// +void Interface::reset_title() +{ + m_title.sprintf ("%s %s (%s)", application_name(), full_version_string(), changeset_date_string()); +} + +// ------------------------------------------------------------------------------------------------- +// +void Interface::flush_input() +{ + m_inputHistory.insert (0, ""); + m_inputCursor = 0; + m_needInputRender = true; +} + END_ZFC_NAMESPACE