X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Fchat.cpp;h=de7483e22360f45b9b236622f9a786f9f99c36ff;hb=0e0c824ea75a812a99c7d329c3a4862d6beadf3b;hp=2d29d39da77fe1b87381607b392ee920a7732e45;hpb=ced6d20295a8263757d57c02a07ffcb66688a163;p=dragonfireclient.git diff --git a/src/chat.cpp b/src/chat.cpp index 2d29d39da..de7483e22 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; } @@ -381,7 +386,7 @@ s32 ChatBuffer::getBottomScrollPos() const -ChatPrompt::ChatPrompt(std::wstring prompt, u32 history_limit): +ChatPrompt::ChatPrompt(const std::wstring &prompt, u32 history_limit): m_prompt(prompt), m_line(L""), m_history(), @@ -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) { @@ -417,20 +423,13 @@ void ChatPrompt::input(const std::wstring &str) m_nick_completion_end = 0; } -std::wstring ChatPrompt::submit() +void ChatPrompt::addToHistory(std::wstring line) { - std::wstring line = m_line; - m_line.clear(); if (!line.empty()) m_history.push_back(line); if (m_history.size() > m_history_limit) m_history.erase(m_history.begin()); m_history_index = m_history.size(); - m_view = 0; - m_cursor = 0; - m_nick_completion_start = 0; - m_nick_completion_end = 0; - return line; } void ChatPrompt::clear() @@ -442,13 +441,15 @@ void ChatPrompt::clear() m_nick_completion_end = 0; } -void ChatPrompt::replace(std::wstring line) +std::wstring ChatPrompt::replace(std::wstring line) { + std::wstring old_line = m_line; m_line = line; m_view = m_cursor = line.size(); clampView(); m_nick_completion_start = 0; m_nick_completion_end = 0; + return old_line; } void ChatPrompt::historyPrev() @@ -511,7 +512,7 @@ void ChatPrompt::nickCompletion(const std::list& names, bool backwa { std::wstring completion = narrow_to_wide(*i); if (prefix_start == 0) - completion += L":"; + completion += L": "; completions.push_back(completion); } } @@ -541,7 +542,7 @@ void ChatPrompt::nickCompletion(const std::list& names, bool backwa } } } - std::wstring replacement = completions[replacement_index] + L" "; + std::wstring replacement = completions[replacement_index]; if (word_end < m_line.size() && isspace(word_end)) ++word_end; @@ -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()