chat.h 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274
  1. /*
  2. Minetest
  3. Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU Lesser General Public License as published by
  6. the Free Software Foundation; either version 2.1 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU Lesser General Public License for more details.
  12. You should have received a copy of the GNU Lesser General Public License along
  13. with this program; if not, write to the Free Software Foundation, Inc.,
  14. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  15. */
  16. #ifndef CHAT_HEADER
  17. #define CHAT_HEADER
  18. #include "irrlichttypes.h"
  19. #include <string>
  20. #include <vector>
  21. #include <list>
  22. // Chat console related classes, only used by the client
  23. struct ChatLine
  24. {
  25. // age in seconds
  26. f32 age;
  27. // name of sending player, or empty if sent by server
  28. std::wstring name;
  29. // message text
  30. std::wstring text;
  31. ChatLine(std::wstring a_name, std::wstring a_text):
  32. age(0.0),
  33. name(a_name),
  34. text(a_text)
  35. {
  36. }
  37. };
  38. struct ChatFormattedFragment
  39. {
  40. // text string
  41. std::wstring text;
  42. // starting column
  43. u32 column;
  44. // formatting
  45. //u8 bold:1;
  46. };
  47. struct ChatFormattedLine
  48. {
  49. // Array of text fragments
  50. std::vector<ChatFormattedFragment> fragments;
  51. // true if first line of one formatted ChatLine
  52. bool first;
  53. };
  54. class ChatBuffer
  55. {
  56. public:
  57. ChatBuffer(u32 scrollback);
  58. ~ChatBuffer();
  59. // Append chat line
  60. // Removes oldest chat line if scrollback size is reached
  61. void addLine(std::wstring name, std::wstring text);
  62. // Remove all chat lines
  63. void clear();
  64. // Get number of lines currently in buffer.
  65. u32 getLineCount() const;
  66. // Get scrollback size, maximum number of lines in buffer.
  67. u32 getScrollback() const;
  68. // Get reference to i-th chat line.
  69. const ChatLine& getLine(u32 index) const;
  70. // Increase each chat line's age by dtime.
  71. void step(f32 dtime);
  72. // Delete oldest N chat lines.
  73. void deleteOldest(u32 count);
  74. // Delete lines older than maxAge.
  75. void deleteByAge(f32 maxAge);
  76. // Get number of columns, 0 if reformat has not been called yet.
  77. u32 getColumns() const;
  78. // Get number of rows, 0 if reformat has not been called yet.
  79. u32 getRows() const;
  80. // Update console size and reformat all formatted lines.
  81. void reformat(u32 cols, u32 rows);
  82. // Get formatted line for a given row (0 is top of screen).
  83. // Only valid after reformat has been called at least once
  84. const ChatFormattedLine& getFormattedLine(u32 row) const;
  85. // Scrolling in formatted buffer (relative)
  86. // positive rows == scroll up, negative rows == scroll down
  87. void scroll(s32 rows);
  88. // Scrolling in formatted buffer (absolute)
  89. void scrollAbsolute(s32 scroll);
  90. // Scroll to bottom of buffer (newest)
  91. void scrollBottom();
  92. // Scroll to top of buffer (oldest)
  93. void scrollTop();
  94. // Format a chat line for the given number of columns.
  95. // Appends the formatted lines to the destination array and
  96. // returns the number of formatted lines.
  97. u32 formatChatLine(const ChatLine& line, u32 cols,
  98. std::vector<ChatFormattedLine>& destination) const;
  99. protected:
  100. s32 getTopScrollPos() const;
  101. s32 getBottomScrollPos() const;
  102. private:
  103. // Scrollback size
  104. u32 m_scrollback;
  105. // Array of unformatted chat lines
  106. std::vector<ChatLine> m_unformatted;
  107. // Number of character columns in console
  108. u32 m_cols;
  109. // Number of character rows in console
  110. u32 m_rows;
  111. // Scroll position (console's top line index into m_formatted)
  112. s32 m_scroll;
  113. // Array of formatted lines
  114. std::vector<ChatFormattedLine> m_formatted;
  115. // Empty formatted line, for error returns
  116. ChatFormattedLine m_empty_formatted_line;
  117. };
  118. class ChatPrompt
  119. {
  120. public:
  121. ChatPrompt(std::wstring prompt, u32 history_limit);
  122. ~ChatPrompt();
  123. // Input character
  124. void input(wchar_t ch);
  125. // Submit, clear and return current line
  126. std::wstring submit();
  127. // Clear the current line
  128. void clear();
  129. // Replace the current line with the given text
  130. void replace(std::wstring line);
  131. // Select previous command from history
  132. void historyPrev();
  133. // Select next command from history
  134. void historyNext();
  135. // Nick completion
  136. void nickCompletion(const std::list<std::string>& names, bool backwards);
  137. // Update console size and reformat the visible portion of the prompt
  138. void reformat(u32 cols);
  139. // Get visible portion of the prompt.
  140. std::wstring getVisiblePortion() const;
  141. // Get cursor position (relative to visible portion). -1 if invalid
  142. s32 getVisibleCursorPosition() const;
  143. // Cursor operations
  144. enum CursorOp {
  145. CURSOROP_MOVE,
  146. CURSOROP_DELETE
  147. };
  148. // Cursor operation direction
  149. enum CursorOpDir {
  150. CURSOROP_DIR_LEFT,
  151. CURSOROP_DIR_RIGHT
  152. };
  153. // Cursor operation scope
  154. enum CursorOpScope {
  155. CURSOROP_SCOPE_CHARACTER,
  156. CURSOROP_SCOPE_WORD,
  157. CURSOROP_SCOPE_LINE
  158. };
  159. // Cursor operation
  160. // op specifies whether it's a move or delete operation
  161. // dir specifies whether the operation goes left or right
  162. // scope specifies how far the operation will reach (char/word/line)
  163. // Examples:
  164. // cursorOperation(CURSOROP_MOVE, CURSOROP_DIR_RIGHT, CURSOROP_SCOPE_LINE)
  165. // moves the cursor to the end of the line.
  166. // cursorOperation(CURSOROP_DELETE, CURSOROP_DIR_LEFT, CURSOROP_SCOPE_WORD)
  167. // deletes the word to the left of the cursor.
  168. void cursorOperation(CursorOp op, CursorOpDir dir, CursorOpScope scope);
  169. protected:
  170. // set m_view to ensure that 0 <= m_view <= m_cursor < m_view + m_cols
  171. // if line can be fully shown, set m_view to zero
  172. // else, also ensure m_view <= m_line.size() + 1 - m_cols
  173. void clampView();
  174. private:
  175. // Prompt prefix
  176. std::wstring m_prompt;
  177. // Currently edited line
  178. std::wstring m_line;
  179. // History buffer
  180. std::vector<std::wstring> m_history;
  181. // History index (0 <= m_history_index <= m_history.size())
  182. u32 m_history_index;
  183. // Maximum number of history entries
  184. u32 m_history_limit;
  185. // Number of columns excluding columns reserved for the prompt
  186. s32 m_cols;
  187. // Start of visible portion (index into m_line)
  188. s32 m_view;
  189. // Cursor (index into m_line)
  190. s32 m_cursor;
  191. // Last nick completion start (index into m_line)
  192. s32 m_nick_completion_start;
  193. // Last nick completion start (index into m_line)
  194. s32 m_nick_completion_end;
  195. };
  196. class ChatBackend
  197. {
  198. public:
  199. ChatBackend();
  200. ~ChatBackend();
  201. // Add chat message
  202. void addMessage(std::wstring name, std::wstring text);
  203. // Parse and add unparsed chat message
  204. void addUnparsedMessage(std::wstring line);
  205. // Get the console buffer
  206. ChatBuffer& getConsoleBuffer();
  207. // Get the recent messages buffer
  208. ChatBuffer& getRecentBuffer();
  209. // Concatenate all recent messages
  210. std::wstring getRecentChat();
  211. // Get the console prompt
  212. ChatPrompt& getPrompt();
  213. // Reformat all buffers
  214. void reformat(u32 cols, u32 rows);
  215. // Clear all recent messages
  216. void clearRecentChat();
  217. // Age recent messages
  218. void step(float dtime);
  219. // Scrolling
  220. void scroll(s32 rows);
  221. void scrollPageDown();
  222. void scrollPageUp();
  223. private:
  224. ChatBuffer m_console_buffer;
  225. ChatBuffer m_recent_buffer;
  226. ChatPrompt m_prompt;
  227. };
  228. #endif