X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=src%2Fchat.cpp;h=46555b3dcc8f9da920efa2c44cade7e7ca971d6a;hb=7760948b7ca436ce0c7d26140dcd3867e81c99c9;hp=d8cf3efd93268ab07338aee2b9aa47ddcc2f9213;hpb=effa24737d6997dc40508533635accca3ed099e9;p=oweals%2Fminetest.git diff --git a/src/chat.cpp b/src/chat.cpp index d8cf3efd9..46555b3dc 100644 --- a/src/chat.cpp +++ b/src/chat.cpp @@ -19,7 +19,8 @@ with this program; if not, write to the Free Software Foundation, Inc., #include "chat.h" #include "debug.h" -#include "strfnd.h" +#include "config.h" +#include "util/strfnd.h" #include #include #include "util/string.h" @@ -97,6 +98,8 @@ void ChatBuffer::step(f32 dtime) void ChatBuffer::deleteOldest(u32 count) { + bool at_bottom = (m_scroll == getBottomScrollPos()); + u32 del_unformatted = 0; u32 del_formatted = 0; @@ -120,6 +123,11 @@ void ChatBuffer::deleteOldest(u32 count) m_unformatted.erase(m_unformatted.begin(), m_unformatted.begin() + del_unformatted); m_formatted.erase(m_formatted.begin(), m_formatted.begin() + del_formatted); + + if (at_bottom) + m_scroll = getBottomScrollPos(); + else + scrollAbsolute(m_scroll - del_formatted); } void ChatBuffer::deleteByAge(f32 maxAge) @@ -244,8 +252,7 @@ u32 ChatBuffer::formatChatLine(const ChatLine& line, u32 cols, u32 hanging_indentation = 0; // Format the sender name and produce fragments - if (!line.name.empty()) - { + if (!line.name.empty()) { temp_frag.text = L"<"; temp_frag.column = 0; //temp_frag.bold = 0; @@ -260,22 +267,20 @@ u32 ChatBuffer::formatChatLine(const ChatLine& line, u32 cols, next_frags.push_back(temp_frag); } + std::wstring name_sanitized = line.name.c_str(); + // Choose an indentation level - if (line.name.empty()) - { + if (line.name.empty()) { // Server messages hanging_indentation = 0; - } - else if (line.name.size() + 3 <= cols/2) - { + } else if (name_sanitized.size() + 3 <= cols/2) { // Names shorter than about half the console width hanging_indentation = line.name.size() + 3; - } - else - { + } else { // Very long names hanging_indentation = 2; } + //EnrichedString line_text(line.text); next_line.first = true; bool text_processing = false; @@ -331,7 +336,7 @@ u32 ChatBuffer::formatChatLine(const ChatLine& line, u32 cols, while (frag_length < remaining_in_input && frag_length < remaining_in_output) { - if (isspace(line.text[in_pos + frag_length])) + if (isspace(line.text.getString()[in_pos + frag_length])) space_pos = frag_length; ++frag_length; } @@ -390,6 +395,7 @@ ChatPrompt::ChatPrompt(std::wstring prompt, u32 history_limit): m_cols(0), m_view(0), m_cursor(0), + m_cursor_len(0), m_nick_completion_start(0), m_nick_completion_end(0) { @@ -426,11 +432,6 @@ void ChatPrompt::addToHistory(std::wstring line) m_history_index = m_history.size(); } -std::wstring ChatPrompt::getLine() -{ - return m_line; -} - void ChatPrompt::clear() { m_line.clear(); @@ -590,14 +591,12 @@ void ChatPrompt::cursorOperation(CursorOp op, CursorOpDir dir, CursorOpScope sco s32 length = m_line.size(); s32 increment = (dir == CURSOROP_DIR_RIGHT) ? 1 : -1; - if (scope == CURSOROP_SCOPE_CHARACTER) - { + switch (scope) { + case CURSOROP_SCOPE_CHARACTER: new_cursor += increment; - } - else if (scope == CURSOROP_SCOPE_WORD) - { - if (increment > 0) - { + break; + case CURSOROP_SCOPE_WORD: + if (dir == CURSOROP_DIR_RIGHT) { // skip one word to the right while (new_cursor < length && isspace(m_line[new_cursor])) new_cursor++; @@ -605,39 +604,47 @@ void ChatPrompt::cursorOperation(CursorOp op, CursorOpDir dir, CursorOpScope sco new_cursor++; while (new_cursor < length && isspace(m_line[new_cursor])) new_cursor++; - } - else - { + } else { // skip one word to the left while (new_cursor >= 1 && isspace(m_line[new_cursor - 1])) new_cursor--; while (new_cursor >= 1 && !isspace(m_line[new_cursor - 1])) new_cursor--; } - } - else if (scope == CURSOROP_SCOPE_LINE) - { + break; + case CURSOROP_SCOPE_LINE: new_cursor += increment * length; + break; + case CURSOROP_SCOPE_SELECTION: + break; } new_cursor = MYMAX(MYMIN(new_cursor, length), 0); - if (op == CURSOROP_MOVE) - { + switch (op) { + case CURSOROP_MOVE: m_cursor = new_cursor; - } - else if (op == CURSOROP_DELETE) - { - if (new_cursor < old_cursor) - { - m_line.erase(new_cursor, old_cursor - new_cursor); - m_cursor = new_cursor; + m_cursor_len = 0; + break; + case CURSOROP_DELETE: + if (m_cursor_len > 0) { // Delete selected text first + m_line.erase(m_cursor, m_cursor_len); + } else { + m_cursor = MYMIN(new_cursor, old_cursor); + m_line.erase(m_cursor, abs(new_cursor - old_cursor)); } - else if (new_cursor > old_cursor) - { - m_line.erase(old_cursor, new_cursor - old_cursor); - m_cursor = old_cursor; + m_cursor_len = 0; + break; + case CURSOROP_SELECT: + if (scope == CURSOROP_SCOPE_LINE) { + m_cursor = 0; + m_cursor_len = length; + } else { + m_cursor = MYMIN(new_cursor, old_cursor); + m_cursor_len += abs(new_cursor - old_cursor); + m_cursor_len = MYMIN(m_cursor_len, length - m_cursor); } + break; } clampView(); @@ -679,7 +686,7 @@ void ChatBackend::addMessage(std::wstring name, std::wstring text) { // Note: A message may consist of multiple lines, for example the MOTD. WStrfnd fnd(text); - while (!fnd.atend()) + while (!fnd.at_end()) { std::wstring line = fnd.next(L"\n"); m_console_buffer.addLine(name, line); @@ -720,19 +727,22 @@ ChatBuffer& ChatBackend::getRecentBuffer() return m_recent_buffer; } -std::wstring ChatBackend::getRecentChat() +EnrichedString ChatBackend::getRecentChat() { - std::wostringstream stream; + EnrichedString result; for (u32 i = 0; i < m_recent_buffer.getLineCount(); ++i) { const ChatLine& line = m_recent_buffer.getLine(i); if (i != 0) - stream << L"\n"; - if (!line.name.empty()) - stream << L"<" << line.name << L"> "; - stream << line.text; + result += L"\n"; + if (!line.name.empty()) { + result += L"<"; + result += line.name; + result += L"> "; + } + result += line.text; } - return stream.str(); + return result; } ChatPrompt& ChatBackend::getPrompt()