12 #include "../stdafx.h" 13 #include "../strings_func.h" 14 #include "../blitter/factory.hpp" 15 #include "../console_func.h" 16 #include "../video/video_driver.hpp" 17 #include "../querystring_gui.h" 19 #include "../window_func.h" 20 #include "../toolbar_gui.h" 21 #include "../core/geometry_func.hpp" 26 #include "../widgets/network_chat_widget.h" 28 #include "table/strings.h" 30 #include "../safeguards.h" 68 if (_chatmsg_list[i].
message[0] ==
'\0')
break;
85 va_start(va, message);
92 if (MAX_CHAT_MESSAGES == msg_count) {
93 memmove(&_chatmsg_list[0], &_chatmsg_list[1],
sizeof(_chatmsg_list[0]) * (msg_count - 1));
94 msg_count = MAX_CHAT_MESSAGES - 1;
102 _chatmessage_dirty =
true;
122 _chatmessage_visible =
false;
125 _chatmsg_list[i].
message[0] =
'\0';
143 _cursor.draw_pos.x + _cursor.
draw_size.x >= _chatmsg_box.x &&
144 _cursor.draw_pos.x <= _chatmsg_box.x + _chatmsg_box.width &&
145 _cursor.draw_pos.y + _cursor.
draw_size.y >= _screen.height - _chatmsg_box.y - _chatmsg_box.height &&
146 _cursor.draw_pos.y <= _screen.height - _chatmsg_box.y) {
150 if (_chatmessage_visible) {
152 int x = _chatmsg_box.x;
153 int y = _screen.height - _chatmsg_box.y - _chatmsg_box.height;
154 int width = _chatmsg_box.width;
155 int height = _chatmsg_box.height;
157 height =
max(height + y,
min(_chatmsg_box.height, _screen.height));
160 if (x + width >= _screen.width) {
161 width = _screen.width - x;
163 if (width <= 0 || height <= 0)
return;
165 _chatmessage_visible =
false;
171 _chatmessage_dirty =
true;
180 if (cmsg->
message[0] ==
'\0')
continue;
185 if (i != MAX_CHAT_MESSAGES - 1) memmove(cmsg, cmsg + 1,
sizeof(*cmsg) * (MAX_CHAT_MESSAGES - i - 1));
188 _chatmsg_list[MAX_CHAT_MESSAGES - 1].
message[0] =
'\0';
189 _chatmessage_dirty =
true;
201 if (!_chatmessage_dirty)
return;
210 if (count == 0)
return;
212 int x = _chatmsg_box.x;
213 int y = _screen.height - _chatmsg_box.y - _chatmsg_box.height;
214 int width = _chatmsg_box.width;
215 int height = _chatmsg_box.height;
217 height =
max(height + y,
min(_chatmsg_box.height, _screen.height));
220 if (x + width >= _screen.width) {
221 width = _screen.width - x;
223 if (width <= 0 || height <= 0)
return;
232 int string_height = 0;
233 for (uint i = 0; i < count; i++) {
238 string_height =
min(string_height, MAX_CHAT_MESSAGES * (
FONT_HEIGHT_NORMAL + NETWORK_CHAT_LINE_SPACING));
240 int top = _screen.height - _chatmsg_box.y - string_height - 2;
241 int bottom = _screen.height - _chatmsg_box.y - 2;
243 GfxFillRect(_chatmsg_box.x, top - 2, _chatmsg_box.x + _chatmsg_box.width - 1, bottom,
248 int ypos = bottom - 2;
250 for (
int i = count - 1; i >= 0; i--) {
252 if (ypos < top)
break;
258 _chatmessage_visible =
true;
259 _chatmessage_dirty =
false;
299 static const StringID chat_captions[] = {
300 STR_NETWORK_CHAT_ALL_CAPTION,
301 STR_NETWORK_CHAT_COMPANY_CAPTION,
302 STR_NETWORK_CHAT_CLIENT_CAPTION
304 assert((uint)this->dtype <
lengthof(chat_captions));
305 this->dest_string = chat_captions[this->dtype];
307 this->InitNested(type);
311 _chat_tab_completion_active =
false;
334 static char chat_tab_temp_buffer[64];
341 return ci->client_name;
353 GetString(chat_tab_temp_buffer, STR_TOWN_NAME,
lastof(chat_tab_temp_buffer));
354 return &chat_tab_temp_buffer[0];
368 char *p = strrchr(buf,
' ');
369 if (p ==
nullptr)
return buf;
381 assert(this->message_editbox.text.
max_bytes ==
lengthof(_chat_tab_completion_buf));
383 Textbuf *tb = &this->message_editbox.text;
386 char *tb_buf, *pre_buf;
387 const char *cur_name;
388 bool second_scan =
false;
395 tb_buf = ChatTabCompletionFindText(pre_buf);
396 tb_len = strlen(tb_buf);
398 while ((cur_name = ChatTabCompletionNextItem(&item)) !=
nullptr) {
401 if (_chat_tab_completion_active) {
409 if (tb_buf == pre_buf) {
411 length = (tb->
bytes - 1) - 2;
414 offset = strlen(pre_buf) + 1;
415 length = (tb->
bytes - 1) - offset;
419 if (strlen(cur_name) == length && strncmp(cur_name, tb->
buf + offset, length) == 0) second_scan =
true;
427 len = strlen(cur_name);
428 if (tb_len < len && strncasecmp(cur_name, tb_buf, tb_len) == 0) {
430 if (!second_scan)
seprintf(_chat_tab_completion_buf,
lastof(_chat_tab_completion_buf),
"%s", tb->
buf);
431 _chat_tab_completion_active =
true;
434 if (pre_buf == tb_buf) {
435 this->message_editbox.text.
Print(
"%s: ", cur_name);
437 this->message_editbox.text.
Print(
"%s %s", pre_buf, cur_name);
448 this->message_editbox.text.
Assign(_chat_tab_completion_buf);
449 _chat_tab_completion_active =
false;
489 SendChat(this->message_editbox.text.
buf, this->dtype, this->dest);
501 if (keycode == WKC_TAB) {
510 _chat_tab_completion_active =
false;
520 if (data == this->dest)
delete this;
530 NWidget(
WWT_TEXT, COLOUR_GREY,
WID_NC_DESTINATION),
SetMinimalSize(62, 12),
SetPadding(1, 0, 1, 0),
SetDataTip(STR_NULL, STR_NULL),
531 NWidget(
WWT_EDITBOX, COLOUR_GREY,
WID_NC_TEXTBOX),
SetMinimalSize(100, 12),
SetPadding(1, 0, 1, 0),
SetResize(1, 0),
532 SetDataTip(STR_NETWORK_CHAT_OSKTITLE, STR_NULL),
533 NWidget(
WWT_PUSHTXTBTN, COLOUR_GREY,
WID_NC_SENDBUTTON),
SetMinimalSize(62, 12),
SetPadding(1, 0, 1, 0),
SetDataTip(STR_NETWORK_CHAT_SEND, STR_NULL),
544 _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.
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.
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?
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
static Pool::IterateWrapper< Titem > Iterate(size_t from=0)
Returns an iterable ensemble of all valid Titem.
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.