16 #include "../stdafx.h" 17 #include "../strings_func.h" 18 #include "../blitter/factory.hpp" 19 #include "../console_func.h" 20 #include "../video/video_driver.hpp" 21 #include "../querystring_gui.h" 23 #include "../window_func.h" 24 #include "../toolbar_gui.h" 25 #include "../core/geometry_func.hpp" 30 #include "../widgets/network_chat_widget.h" 32 #include "table/strings.h" 34 #include "../safeguards.h" 72 if (_chatmsg_list[i].
message[0] ==
'\0')
break;
89 va_start(va, message);
96 if (MAX_CHAT_MESSAGES == msg_count) {
97 memmove(&_chatmsg_list[0], &_chatmsg_list[1],
sizeof(_chatmsg_list[0]) * (msg_count - 1));
98 msg_count = MAX_CHAT_MESSAGES - 1;
106 _chatmessage_dirty =
true;
126 _chatmessage_visible =
false;
129 _chatmsg_list[i].
message[0] =
'\0';
147 _cursor.draw_pos.x + _cursor.
draw_size.x >= _chatmsg_box.x &&
148 _cursor.draw_pos.x <= _chatmsg_box.x + _chatmsg_box.width &&
149 _cursor.draw_pos.y + _cursor.
draw_size.y >= _screen.height - _chatmsg_box.y - _chatmsg_box.height &&
150 _cursor.draw_pos.y <= _screen.height - _chatmsg_box.y) {
154 if (_chatmessage_visible) {
156 int x = _chatmsg_box.x;
157 int y = _screen.height - _chatmsg_box.y - _chatmsg_box.height;
158 int width = _chatmsg_box.width;
159 int height = _chatmsg_box.height;
161 height =
max(height + y,
min(_chatmsg_box.height, _screen.height));
164 if (x + width >= _screen.width) {
165 width = _screen.width - x;
167 if (width <= 0 || height <= 0)
return;
169 _chatmessage_visible =
false;
175 _chatmessage_dirty =
true;
184 if (cmsg->
message[0] ==
'\0')
continue;
189 if (i != MAX_CHAT_MESSAGES - 1) memmove(cmsg, cmsg + 1,
sizeof(*cmsg) * (MAX_CHAT_MESSAGES - i - 1));
192 _chatmsg_list[MAX_CHAT_MESSAGES - 1].
message[0] =
'\0';
193 _chatmessage_dirty =
true;
205 if (!_chatmessage_dirty)
return;
214 if (count == 0)
return;
216 int x = _chatmsg_box.x;
217 int y = _screen.height - _chatmsg_box.y - _chatmsg_box.height;
218 int width = _chatmsg_box.width;
219 int height = _chatmsg_box.height;
221 height =
max(height + y,
min(_chatmsg_box.height, _screen.height));
224 if (x + width >= _screen.width) {
225 width = _screen.width - x;
227 if (width <= 0 || height <= 0)
return;
236 int string_height = 0;
237 for (uint i = 0; i < count; i++) {
242 string_height =
min(string_height, MAX_CHAT_MESSAGES * (
FONT_HEIGHT_NORMAL + NETWORK_CHAT_LINE_SPACING));
244 int top = _screen.height - _chatmsg_box.y - string_height - 2;
245 int bottom = _screen.height - _chatmsg_box.y - 2;
247 GfxFillRect(_chatmsg_box.x, top - 2, _chatmsg_box.x + _chatmsg_box.width - 1, bottom,
252 int ypos = bottom - 2;
254 for (
int i = count - 1; i >= 0; i--) {
256 if (ypos < top)
break;
262 _chatmessage_visible =
true;
263 _chatmessage_dirty =
false;
303 static const StringID chat_captions[] = {
304 STR_NETWORK_CHAT_ALL_CAPTION,
305 STR_NETWORK_CHAT_COMPANY_CAPTION,
306 STR_NETWORK_CHAT_CLIENT_CAPTION
308 assert((uint)this->dtype <
lengthof(chat_captions));
309 this->dest_string = chat_captions[this->dtype];
311 this->InitNested(type);
315 _chat_tab_completion_active =
false;
338 static char chat_tab_temp_buffer[64];
360 GetString(chat_tab_temp_buffer, STR_TOWN_NAME,
lastof(chat_tab_temp_buffer));
361 return &chat_tab_temp_buffer[0];
375 char *p = strrchr(buf,
' ');
376 if (p == NULL)
return buf;
388 assert(this->message_editbox.text.
max_bytes ==
lengthof(_chat_tab_completion_buf));
390 Textbuf *tb = &this->message_editbox.text;
393 char *tb_buf, *pre_buf;
394 const char *cur_name;
395 bool second_scan =
false;
402 tb_buf = ChatTabCompletionFindText(pre_buf);
403 tb_len = strlen(tb_buf);
405 while ((cur_name = ChatTabCompletionNextItem(&item)) != NULL) {
408 if (_chat_tab_completion_active) {
416 if (tb_buf == pre_buf) {
418 length = (tb->
bytes - 1) - 2;
421 offset = strlen(pre_buf) + 1;
422 length = (tb->
bytes - 1) - offset;
426 if (strlen(cur_name) == length && strncmp(cur_name, tb->
buf + offset, length) == 0) second_scan =
true;
434 len = strlen(cur_name);
435 if (tb_len < len && strncasecmp(cur_name, tb_buf, tb_len) == 0) {
437 if (!second_scan)
seprintf(_chat_tab_completion_buf,
lastof(_chat_tab_completion_buf),
"%s", tb->
buf);
438 _chat_tab_completion_active =
true;
441 if (pre_buf == tb_buf) {
442 this->message_editbox.text.
Print(
"%s: ", cur_name);
444 this->message_editbox.text.
Print(
"%s %s", pre_buf, cur_name);
455 this->message_editbox.text.
Assign(_chat_tab_completion_buf);
456 _chat_tab_completion_active =
false;
496 SendChat(this->message_editbox.text.
buf, this->dtype, this->dest);
508 if (keycode == WKC_TAB) {
517 _chat_tab_completion_active =
false;
527 if (data == this->dest)
delete this;
537 NWidget(
WWT_TEXT, COLOUR_GREY,
WID_NC_DESTINATION),
SetMinimalSize(62, 12),
SetPadding(1, 0, 1, 0),
SetDataTip(STR_NULL, STR_NULL),
538 NWidget(
WWT_EDITBOX, COLOUR_GREY,
WID_NC_TEXTBOX),
SetMinimalSize(100, 12),
SetPadding(1, 0, 1, 0),
SetResize(1, 0),
539 SetDataTip(STR_NETWORK_CHAT_OSKTITLE, STR_NULL),
540 NWidget(
WWT_PUSHTXTBTN, COLOUR_GREY,
WID_NC_SENDBUTTON),
SetMinimalSize(62, 12),
SetPadding(1, 0, 1, 0),
SetDataTip(STR_NETWORK_CHAT_SEND, STR_NULL),
551 _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.
virtual void OnClick(Point pt, int widget, int click_count)
A click with the left mouse button has been made on the window.
int CDECL vseprintf(char *str, const char *last, const char *format, va_list ap)
Safer implementation of vsnprintf; same as vsnprintf except:
virtual Point OnInitialPosition(int16 sm_width, int16 sm_height, int window_number)
Compute the initial position of the window.
Client part of the network protocol.
virtual void OnEditboxChanged(int wid)
The text in an editbox has been edited.
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')
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.
Servers always have this ID.
NetworkChatWindow(WindowDesc *desc, DestType type, int dest)
Create a chat input window.
In-game console is closed.
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.
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.
virtual void DrawWidget(const Rect &r, int widget) const
Draw the contents of a nested widget.
int ok_button
Widget button of parent window to simulate when pressing OK in OSK.
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...
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.
#define lengthof(x)
Return the length of an fixed size array.
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.
virtual void OnInvalidateData(int data=0, bool gui_scope=true)
Some data on this window has become invalid.
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 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.
ClientID
'Unique' identifier to be given to clients
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.
virtual EventState OnKeyPress(WChar key, uint16 keycode)
A key has been pressed.
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'.
virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize)
Update size and resize step of a widget in the window.
static const NWidgetPart _nested_chat_window_widgets[]
The widgets of the chat window.
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 WindowDesc _chat_window_desc(WDP_MANUAL, NULL, 0, 0, WC_SEND_NETWORK_MSG, WC_NONE, 0, _nested_chat_window_widgets, lengthof(_nested_chat_window_widgets))
The description of the chat window.
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.
virtual void FindWindowPlacementAndResize(int def_width, int def_height)
Resize window towards the default size.
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.