14 #include "../stdafx.h" 15 #include "../strings_func.h" 16 #include "../blitter/factory.hpp" 17 #include "../console_func.h" 18 #include "../video/video_driver.hpp" 19 #include "../querystring_gui.h" 21 #include "../window_func.h" 22 #include "../toolbar_gui.h" 23 #include "../core/geometry_func.hpp" 28 #include "../widgets/network_chat_widget.h" 30 #include "table/strings.h" 32 #include "../safeguards.h" 70 if (_chatmsg_list[i].
message[0] ==
'\0')
break;
87 va_start(va, message);
94 if (MAX_CHAT_MESSAGES == msg_count) {
95 memmove(&_chatmsg_list[0], &_chatmsg_list[1],
sizeof(_chatmsg_list[0]) * (msg_count - 1));
96 msg_count = MAX_CHAT_MESSAGES - 1;
104 _chatmessage_dirty =
true;
124 _chatmessage_visible =
false;
127 _chatmsg_list[i].
message[0] =
'\0';
145 _cursor.draw_pos.x + _cursor.
draw_size.x >= _chatmsg_box.x &&
146 _cursor.draw_pos.x <= _chatmsg_box.x + _chatmsg_box.width &&
147 _cursor.draw_pos.y + _cursor.
draw_size.y >= _screen.height - _chatmsg_box.y - _chatmsg_box.height &&
148 _cursor.draw_pos.y <= _screen.height - _chatmsg_box.y) {
152 if (_chatmessage_visible) {
154 int x = _chatmsg_box.x;
155 int y = _screen.height - _chatmsg_box.y - _chatmsg_box.height;
156 int width = _chatmsg_box.width;
157 int height = _chatmsg_box.height;
159 height =
max(height + y,
min(_chatmsg_box.height, _screen.height));
162 if (x + width >= _screen.width) {
163 width = _screen.width - x;
165 if (width <= 0 || height <= 0)
return;
167 _chatmessage_visible =
false;
173 _chatmessage_dirty =
true;
182 if (cmsg->
message[0] ==
'\0')
continue;
187 if (i != MAX_CHAT_MESSAGES - 1) memmove(cmsg, cmsg + 1,
sizeof(*cmsg) * (MAX_CHAT_MESSAGES - i - 1));
190 _chatmsg_list[MAX_CHAT_MESSAGES - 1].
message[0] =
'\0';
191 _chatmessage_dirty =
true;
203 if (!_chatmessage_dirty)
return;
212 if (count == 0)
return;
214 int x = _chatmsg_box.x;
215 int y = _screen.height - _chatmsg_box.y - _chatmsg_box.height;
216 int width = _chatmsg_box.width;
217 int height = _chatmsg_box.height;
219 height =
max(height + y,
min(_chatmsg_box.height, _screen.height));
222 if (x + width >= _screen.width) {
223 width = _screen.width - x;
225 if (width <= 0 || height <= 0)
return;
234 int string_height = 0;
235 for (uint i = 0; i < count; i++) {
240 string_height =
min(string_height, MAX_CHAT_MESSAGES * (
FONT_HEIGHT_NORMAL + NETWORK_CHAT_LINE_SPACING));
242 int top = _screen.height - _chatmsg_box.y - string_height - 2;
243 int bottom = _screen.height - _chatmsg_box.y - 2;
245 GfxFillRect(_chatmsg_box.x, top - 2, _chatmsg_box.x + _chatmsg_box.width - 1, bottom,
250 int ypos = bottom - 2;
252 for (
int i = count - 1; i >= 0; i--) {
254 if (ypos < top)
break;
260 _chatmessage_visible =
true;
261 _chatmessage_dirty =
false;
301 static const StringID chat_captions[] = {
302 STR_NETWORK_CHAT_ALL_CAPTION,
303 STR_NETWORK_CHAT_COMPANY_CAPTION,
304 STR_NETWORK_CHAT_CLIENT_CAPTION
306 assert((uint)this->dtype <
lengthof(chat_captions));
307 this->dest_string = chat_captions[this->dtype];
309 this->InitNested(type);
313 _chat_tab_completion_active =
false;
336 static char chat_tab_temp_buffer[64];
358 GetString(chat_tab_temp_buffer, STR_TOWN_NAME,
lastof(chat_tab_temp_buffer));
359 return &chat_tab_temp_buffer[0];
373 char *p = strrchr(buf,
' ');
374 if (p ==
nullptr)
return buf;
386 assert(this->message_editbox.text.
max_bytes ==
lengthof(_chat_tab_completion_buf));
388 Textbuf *tb = &this->message_editbox.text;
391 char *tb_buf, *pre_buf;
392 const char *cur_name;
393 bool second_scan =
false;
400 tb_buf = ChatTabCompletionFindText(pre_buf);
401 tb_len = strlen(tb_buf);
403 while ((cur_name = ChatTabCompletionNextItem(&item)) !=
nullptr) {
406 if (_chat_tab_completion_active) {
414 if (tb_buf == pre_buf) {
416 length = (tb->
bytes - 1) - 2;
419 offset = strlen(pre_buf) + 1;
420 length = (tb->
bytes - 1) - offset;
424 if (strlen(cur_name) == length && strncmp(cur_name, tb->
buf + offset, length) == 0) second_scan =
true;
432 len = strlen(cur_name);
433 if (tb_len < len && strncasecmp(cur_name, tb_buf, tb_len) == 0) {
435 if (!second_scan)
seprintf(_chat_tab_completion_buf,
lastof(_chat_tab_completion_buf),
"%s", tb->
buf);
436 _chat_tab_completion_active =
true;
439 if (pre_buf == tb_buf) {
440 this->message_editbox.text.
Print(
"%s: ", cur_name);
442 this->message_editbox.text.
Print(
"%s %s", pre_buf, cur_name);
453 this->message_editbox.text.
Assign(_chat_tab_completion_buf);
454 _chat_tab_completion_active =
false;
494 SendChat(this->message_editbox.text.
buf, this->dtype, this->dest);
506 if (keycode == WKC_TAB) {
515 _chat_tab_completion_active =
false;
525 if (data == this->dest)
delete this;
535 NWidget(
WWT_TEXT, COLOUR_GREY,
WID_NC_DESTINATION),
SetMinimalSize(62, 12),
SetPadding(1, 0, 1, 0),
SetDataTip(STR_NULL, STR_NULL),
536 NWidget(
WWT_EDITBOX, COLOUR_GREY,
WID_NC_TEXTBOX),
SetMinimalSize(100, 12),
SetPadding(1, 0, 1, 0),
SetResize(1, 0),
537 SetDataTip(STR_NETWORK_CHAT_OSKTITLE, STR_NULL),
538 NWidget(
WWT_PUSHTXTBTN, COLOUR_GREY,
WID_NC_SENDBUTTON),
SetMinimalSize(62, 12),
SetPadding(1, 0, 1, 0),
SetDataTip(STR_NETWORK_CHAT_SEND, STR_NULL),
549 _nested_chat_window_widgets,
lengthof(_nested_chat_window_widgets)
EventState
State of handling an event.
virtual void MakeDirty(int left, int top, int width, int height)=0
Mark a particular area dirty.
Window to enter the chat message in.
static const PaletteID PALETTE_TO_TRANSPARENT
This sets the sprite to transparent.
Container for all information known about a client.
uint32 _realtime_tick
The real time in the game.
void GfxFillRect(int left, int top, int right, int bottom, int colour, FillRectMode mode)
Applies a certain FillRectMode-operation to a rectangle [left, right] x [top, bottom] on the screen...
High level window description.
TextColour colour
The colour of the message.
uint16 network_chat_box_width_pct
width of the chat box in percent
int CDECL seprintf(char *str, const char *last, const char *format,...)
Safer implementation of snprintf; same as snprintf except:
Offset at top to draw the frame rectangular area.
void NetworkReInitChatBoxSize()
Initialize all font-dependent chat box sizes.
Window * FindWindowById(WindowClass cls, WindowNumber number)
Find a window by its class and window number.
The passed event is not handled.
int CDECL vseprintf(char *str, const char *last, const char *format, va_list ap)
Safer implementation of vsnprintf; same as vsnprintf except:
void OnEditboxChanged(int wid) override
The text in an editbox has been edited.
Client part of the network protocol.
Tindex index
Index of this pool item.
void CDECL Print(const char *format,...) WARN_FORMAT(2
Print a formatted string into the textbuffer.
static const int DRAW_STRING_BUFFER
Size of the buffer used for drawing strings.
Send message/notice to only a certain client (Private)
void ChatTabCompletion()
See if we can auto-complete the current text of the user.
#define lastof(x)
Get the last element of an fixed size array.
Helper/buffer for input fields.
Base core network types and some helper functions to access them.
How all blitters should look like.
uint16 bytes
the current size of the string in bytes (including terminating '\0')
ClientID
'Unique' identifier to be given to clients
static T max(const T a, const T b)
Returns the maximum of two values.
bool visible
cursor is visible
virtual int GetBytesPerPixel()=0
Get how many bytes are needed to store a pixel.
NetworkChatWindow(WindowDesc *desc, DestType type, int dest)
Create a chat input window.
In-game console is closed.
void OnInvalidateData(int data=0, bool gui_scope=true) override
Some data on this window has become invalid.
Force the alignment, i.e. don't swap for RTL languages.
Data structure for an opened window.
Point draw_size
position and size bounding-box for drawing
void SetDParamStr(uint n, const char *str)
This function is used to "bind" a C string to a OpenTTD dparam slot.
void NetworkChatMessageLoop()
Check if a message is expired.
void NetworkDrawChatMessage()
Draw the chat message-box.
void DrawWidget(const Rect &r, int widget) const override
Draw the contents of a nested widget.
uint8 network_chat_box_height
height of the chat box in lines
static size_t GetPoolSize()
Returns first unused index.
char client_name[NETWORK_CLIENT_NAME_LENGTH]
Name of the client.
int ok_button
Widget button of parent window to simulate when pressing OK in OSK.
void OnClick(Point pt, int widget, int click_count) override
A click with the left mouse button has been made on the window.
static uint GetChatMessageCount()
Count the chat messages.
size_t Utf8TrimString(char *s, size_t maxlen)
Properly terminate an UTF8 string to some maximum length.
static char * ChatTabCompletionFindText(char *buf)
Find what text to complete.
#define FONT_HEIGHT_NORMAL
Height of characters in the normal (FS_NORMAL) font.
Data stored about a string that can be modified in the GUI.
ClientSettings _settings_client
The current settings for this game.
Apply a recolour sprite to the screen content.
static bool _chatmessage_dirty
Does the chat message need repainting?
#define FOR_ALL_CLIENT_INFOS_FROM(var, start)
Iterate over all the clients from a given index.
TextColour
Colour of the strings, see _string_colourmap in table/string_colours.h or docs/ottd-colourtext-palett...
int PositionNetworkChatWindow(Window *w)
(Re)position network chat window at the screen.
int dest
The identifier of the destination.
char * stredup(const char *s, const char *last)
Create a duplicate of the given string.
static T * ReallocT(T *t_ptr, size_t num_elements)
Simplified reallocation function that allocates the specified number of elements of the given type...
EventState OnKeyPress(WChar key, uint16 keycode) override
A key has been pressed.
static PointDimension _chatmsg_box
The chatbox grows from the bottom so the coordinates are pixels from the left and pixels from the bot...
static const uint NETWORK_CHAT_LENGTH
The maximum length of a chat message, in bytes including '\0'.
Offset at bottom to draw the frame rectangular area.
static bool _chat_tab_completion_active
Whether tab completion is active.
int DrawString(int left, int right, int top, const char *str, TextColour colour, StringAlignment align, bool underline, FontSize fontsize)
Draw string, possibly truncated to make it fit in its allocated space.
const char * ChatTabCompletionNextItem(uint *item)
Find the next item of the list of things that can be auto-completed.
Basic functions/variables used all over the place.
static ChatMessage * _chatmsg_list
The actual chat message list.
Point OnInitialPosition(int16 sm_width, int16 sm_height, int window_number) override
Compute the initial position of the window.
#define lengthof(x)
Return the length of an fixed size array.
void FindWindowPlacementAndResize(int def_width, int def_height) override
Resize window towards the default size.
static Blitter * GetCurrentBlitter()
Get the current active blitter (always set by calling SelectBlitter).
static T min(const T a, const T b)
Returns the minimum of two values.
int cancel_button
Widget button of parent window to simulate when pressing CANCEL in OSK.
uint32 StringID
Numeric value that represents a string, independent of the selected language.
void DeleteWindowByClass(WindowClass cls)
Delete all windows of a given class.
virtual void CopyToBuffer(const void *video, void *dst, int width, int height)=0
Copy from the screen to a buffer.
void Assign(StringID string)
Render a string into the textbuffer.
void NetworkUndrawChatMessage()
Hide the chatbox.
Dimension GetStringBoundingBox(const char *str, FontSize start_fontsize)
Return the string dimension in pixels.
uint32 remove_time
The time to remove the message.
Dimension maxdim(const Dimension &d1, const Dimension &d2)
Compute bounding box of both dimensions.
No window, redirects to WC_MAIN_WINDOW.
void NetworkInitChatMessage()
Initialize all buffers of the chat visualisation.
virtual int BufferSize(int width, int height)=0
Calculate how much memory there is needed for an image of this size in the video-buffer.
char *const buf
buffer in which text is saved
void NetworkServerSendChat(NetworkAction action, DestType type, int dest, const char *msg, ClientID from_id, int64 data=0, bool from_admin=false)
Send an actual chat message.
StringID dest_string
String representation of the destination.
GUISettings gui
settings related to the GUI
uint16 max_bytes
the maximum size of the buffer in bytes (including terminating '\0')
static WindowDesc _chat_window_desc(WDP_MANUAL, nullptr, 0, 0, WC_SEND_NETWORK_MSG, WC_NONE, 0, _nested_chat_window_widgets, lengthof(_nested_chat_window_widgets))
The description of the chat window.
void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override
Update size and resize step of a widget in the window.
static bool StrEmpty(const char *s)
Check if a string buffer is empty.
int GetStringLineCount(StringID str, int maxw)
Calculates number of lines of string.
Specification of a rectangle with an absolute top-left coordinate and a (relative) width/height...
static VideoDriver * GetInstance()
Get the currently active instance of the video driver.
virtual void CopyFromBuffer(void *video, const void *src, int width, int height)=0
Copy from a buffer to the screen.
static uint8 * _chatmessage_backup
Backup in case text is moved.
QueryString message_editbox
Message editbox.
char * strecpy(char *dst, const char *src, const char *last)
Copies characters from one buffer to another.
void CDECL NetworkAddChatMessage(TextColour colour, uint duration, const char *message,...)
Add a text message to the 'chat window' to be shown.
virtual void * MoveTo(void *video, int x, int y)=0
Move the destination pointer the requested amount x and y, keeping in mind any pitch and bpp of the r...
Statusbar (at the bottom of your screen); Window numbers:
bool _network_server
network-server is active
Coordinates of a point in 2D.
static const uint MAX_CLIENT_SLOTS
The number of slots; must be at least 1 more than MAX_CLIENTS.
static void SendChat(const char *buf, DestType type, int dest)
Send an actual chat message.
Colour value is already a real palette colour index, not an index of a StringColour.
static void free(const void *ptr)
Version of the standard free that accepts const pointers.
virtual void FindWindowPlacementAndResize(int def_width, int def_height)
Resize window towards the default size.
Offset at right to draw the frame rectangular area.
static const uint NETWORK_NAME_LENGTH
The maximum length of the server name and map name, in bytes including '\0'.
static const NWidgetPart _nested_chat_window_widgets[]
The widgets of the chat window.
Servers always have this ID.
static uint MAX_CHAT_MESSAGES
The limit of chat messages to show.
Specification of a rectangle with absolute coordinates of all edges.
The passed event is handled.
char message[DRAW_STRING_BUFFER]
The action message.
Right align the text (must be a single bit).
static const uint NETWORK_CHAT_LINE_SPACING
Spacing between chat lines.
static NetworkClientInfo * GetByClientID(ClientID client_id)
Return the CI given it's client-identifier.
static bool _chatmessage_visible
Is a chat message visible.
Manually align the window (so no automatic location finding)
static NetworkRecvStatus SendChat(NetworkAction action, DestType type, int dest, const char *msg, int64 data)
Send a chat-packet over the network.
uint32 WChar
Type for wide characters, i.e.
Dimensions (a width and height) of a rectangle in 2D.
Offset at left to draw the frame rectangular area.
DestType dtype
The type of destination.
DestType
Destination of our chat messages.
NetworkAction
Actions that can be used for NetworkTextMessage.
void ShowNetworkChatQueryWindow(DestType type, int dest)
Show the chat window.
void InvalidateWindowData(WindowClass cls, WindowNumber number, int data, bool gui_scope)
Mark window data of the window of a given class and specific window number as invalid (in need of re-...
assert_compile((int) DRAW_STRING_BUFFER >=(int) NETWORK_CHAT_LENGTH+NETWORK_NAME_LENGTH+40)
The draw buffer must be able to contain the chat message, client name and the "[All]" message...
int height
Height of the window (number of pixels down in y direction)
News window; Window numbers:
int DrawStringMultiLine(int left, int right, int top, int bottom, const char *str, TextColour colour, StringAlignment align, bool underline, FontSize fontsize)
Draw string, possibly over multiple lines.
static void SetDParam(uint n, uint64 v)
Set a string parameter v at index n in the global string parameter array.