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