Draw the chat message-box */
| 178 | |
| 179 | /** Draw the chat message-box */ |
| 180 | void NetworkDrawChatMessage() |
| 181 | { |
| 182 | Blitter *blitter = BlitterFactory::GetCurrentBlitter(); |
| 183 | if (!_chatmessage_dirty) return; |
| 184 | |
| 185 | const Window *w = FindWindowByClass(WC_SEND_NETWORK_MSG); |
| 186 | bool show_all = (w != nullptr); |
| 187 | |
| 188 | /* First undraw if needed */ |
| 189 | NetworkUndrawChatMessage(); |
| 190 | |
| 191 | if (_iconsole_mode == ICONSOLE_FULL) return; |
| 192 | |
| 193 | /* Check if we have anything to draw at all */ |
| 194 | if (!HaveChatMessages(show_all)) return; |
| 195 | |
| 196 | int x = _chatmsg_box.x; |
| 197 | int y = _screen.height - _chatmsg_box.y - _chatmsg_box.height; |
| 198 | int width = _chatmsg_box.width; |
| 199 | int height = _chatmsg_box.height; |
| 200 | if (y < 0) { |
| 201 | height = std::max(height + y, std::min(_chatmsg_box.height, _screen.height)); |
| 202 | y = 0; |
| 203 | } |
| 204 | if (x + width >= _screen.width) { |
| 205 | width = _screen.width - x; |
| 206 | } |
| 207 | if (width <= 0 || height <= 0) return; |
| 208 | |
| 209 | /* Make a copy of the screen as it is before painting (for undraw) */ |
| 210 | uint8_t *buffer = _chatmessage_backup.Allocate(BlitterFactory::GetCurrentBlitter()->BufferSize(width, height)); |
| 211 | blitter->CopyToBuffer(blitter->MoveTo(_screen.dst_ptr, x, y), buffer, width, height); |
| 212 | |
| 213 | _cur_dpi = &_screen; // switch to _screen painting |
| 214 | |
| 215 | auto now = std::chrono::steady_clock::now(); |
| 216 | int string_height = 0; |
| 217 | for (auto &cmsg : _chatmsg_list) { |
| 218 | if (!show_all && cmsg.remove_time < now) continue; |
| 219 | string_height += GetStringLineCount(GetString(STR_JUST_RAW_STRING, cmsg.message), width - 1) * GetCharacterHeight(FS_NORMAL) + NETWORK_CHAT_LINE_SPACING; |
| 220 | } |
| 221 | |
| 222 | string_height = std::min<uint>(string_height, MAX_CHAT_MESSAGES * (GetCharacterHeight(FS_NORMAL) + NETWORK_CHAT_LINE_SPACING)); |
| 223 | |
| 224 | int top = _screen.height - _chatmsg_box.y - string_height - 2; |
| 225 | int bottom = _screen.height - _chatmsg_box.y - 2; |
| 226 | /* Paint a half-transparent box behind the chat messages */ |
| 227 | GfxFillRect(_chatmsg_box.x, top - 2, _chatmsg_box.x + _chatmsg_box.width - 1, bottom, |
| 228 | PALETTE_TO_TRANSPARENT, FILLRECT_RECOLOUR // black, but with some alpha for background |
| 229 | ); |
| 230 | |
| 231 | /* Paint the chat messages starting with the lowest at the bottom */ |
| 232 | int ypos = bottom - 2; |
| 233 | |
| 234 | for (auto &cmsg : _chatmsg_list) { |
| 235 | if (!show_all && cmsg.remove_time < now) continue; |
| 236 | ypos = DrawStringMultiLine(_chatmsg_box.x + ScaleGUITrad(3), _chatmsg_box.x + _chatmsg_box.width - 1, top, ypos, cmsg.message, cmsg.colour, SA_LEFT | SA_BOTTOM | SA_FORCE) - NETWORK_CHAT_LINE_SPACING; |
| 237 | if (ypos < top) break; |
no test coverage detected