• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Return-To-The-Roots / s25client / 15636286198

13 Jun 2025 01:55PM UTC coverage: 50.483% (+0.02%) from 50.467%
15636286198

Pull #1771

github

web-flow
Merge 136d3fb48 into e6663858b
Pull Request #1771: Fix clang tidy on ci

42 of 53 new or added lines in 22 files covered. (79.25%)

1 existing line in 1 file now uncovered.

22467 of 44504 relevant lines covered (50.48%)

35912.36 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

43.8
/libs/s25main/controls/ctrlChat.cpp
1
// Copyright (C) 2005 - 2024 Settlers Freaks (sf-team at siedler25.org)
2
//
3
// SPDX-License-Identifier: GPL-2.0-or-later
4

5
#include "ctrlChat.h"
6
#include "CollisionDetection.h"
7
#include "FileChecksum.h"
8
#include "ctrlScrollBar.h"
9
#include "driver/MouseCoords.h"
10
#include "ogl/glFont.h"
11
#include "s25util/Log.h"
12

13
/// Breite der Scrollbar
14
static const unsigned short SCROLLBAR_WIDTH = 20;
15

16
/**
17
 *  Konstruktor von @p ctrlChat.
18
 *
19
 *  @param[in] parent Elternfenster
20
 *  @param[in] id     ID des Steuerelements
21
 *  @param[in] x      X-Position
22
 *  @param[in] y      Y-Position
23
 *  @param[in] width  Breite des Controls
24
 *  @param[in] height Höhe des Controls
25
 *  @param[in] tc     Hintergrundtextur
26
 *  @param[in] font   Schriftart
27
 */
28
ctrlChat::ctrlChat(Window* parent, unsigned id, const DrawPoint& pos, const Extent& size, TextureColor tc,
2✔
29
                   const glFont* font)
2✔
30
    : Window(parent, id, pos, size), tc(tc), font(font), time_color(0xFFFFFFFF)
2✔
31
{
32
    // Zeilen pro Seite festlegen errechnen
33
    page_size = (size.y - 4) / (font->getHeight() + 2);
2✔
34

35
    // Scrollbalken hinzufügen
36
    AddScrollBar(0, DrawPoint(size.x - SCROLLBAR_WIDTH, 0), Extent(SCROLLBAR_WIDTH, size.y), SCROLLBAR_WIDTH, tc,
2✔
37
                 page_size);
2✔
38

39
    // Breite der Klammern <> um die Spielernamen berechnen
40
    bracket1_size = font->getWidth("<");
2✔
41
    bracket2_size = font->getWidth("> ");
2✔
42
}
2✔
43

44
ctrlChat::~ctrlChat() = default;
4✔
45

46
/**
47
 *  Größe ändern
48
 */
49
void ctrlChat::Resize(const Extent& newSize)
×
50
{
51
    const bool x_changed = (GetSize().x != newSize.x && !chat_lines.empty());
×
52
    Window::Resize(newSize);
×
53

54
    auto* scroll = GetCtrl<ctrlScrollBar>(0);
×
55
    scroll->SetPos(DrawPoint(newSize.x - SCROLLBAR_WIDTH, 0));
×
56
    scroll->Resize(Extent(SCROLLBAR_WIDTH, newSize.y));
×
57

58
    // Remember some things
59
    const bool was_on_bottom = (scroll->GetScrollPos() + page_size == chat_lines.size());
×
60
    unsigned short position = 0;
×
61
    // Remember the entry on top
62
    for(unsigned short i = 1; i <= scroll->GetScrollPos(); ++i)
×
63
        if(holds_alternative<PrimaryChatLine>(chat_lines[i]))
×
64
            ++position;
×
65

66
    // Rewrap
67
    if(x_changed)
×
68
    {
69
        chat_lines.clear();
×
70
        for(unsigned short i = 0; i < raw_chat_lines.size(); ++i)
×
71
            WrapLine(i);
×
72
    }
73

74
    // Zeilen pro Seite festlegen errechnen
75
    page_size = (newSize.y - 4) / (font->getHeight() + 2);
×
76

77
    scroll->SetPageSize(page_size);
×
78

79
    // If we are were on the last line, keep
80
    if(was_on_bottom)
×
81
    {
82
        scroll->SetScrollPos(((chat_lines.size() > page_size) ? chat_lines.size() - page_size : 0));
×
83
    } else if(x_changed)
×
84
    {
85
        unsigned short i;
86
        for(i = 0; position > 0; ++i)
×
87
            if(holds_alternative<PrimaryChatLine>(chat_lines[i]))
×
88
                --position;
×
89
        scroll->SetScrollPos(i);
×
90
    }
91

92
    // Don't display empty lines at the end if there are this is
93
    // not necessary because of a lack of lines in total
94
    if(chat_lines.size() < page_size)
×
95
        scroll->SetScrollPos(0);
×
96
    else if(scroll->GetScrollPos() + page_size > chat_lines.size())
×
97
        scroll->SetScrollPos(chat_lines.size() - page_size);
×
98
}
×
99

100
/**
101
 *  Zeichnet das Chat-Control.
102
 */
103
void ctrlChat::Draw_()
1✔
104
{
105
    // Box malen
106
    Draw3D(Rect(GetDrawPos(), GetSize()), tc, false);
1✔
107

108
    Window::Draw_();
1✔
109

110
    // Wieviele Linien anzeigen?
111
    unsigned show_lines = (page_size > unsigned(chat_lines.size()) ? unsigned(chat_lines.size()) : page_size);
1✔
112

113
    // Listeneinträge zeichnen
114
    // Add margin
115
    DrawPoint textPos = GetDrawPos() + DrawPoint(2, 2);
1✔
116
    unsigned pos = GetCtrl<ctrlScrollBar>(0)->GetScrollPos();
1✔
117
    for(unsigned i = 0; i < show_lines; ++i)
1✔
118
    {
119
        DrawPoint curTextPos = textPos;
×
NEW
120
        if(auto* line = get_if<PrimaryChatLine>(&chat_lines[i + pos]))
×
121
        {
122
            // Zeit, Spieler und danach Textnachricht
123
            if(!line->time_string.empty())
×
124
            {
125
                font->Draw(curTextPos, line->time_string, FontStyle{}, time_color);
×
126
                curTextPos.x += font->getWidth(line->time_string);
×
127
            }
128

129
            if(!line->player.empty())
×
130
            {
131
                // Klammer 1 (<)
132
                font->Draw(curTextPos, "<", FontStyle{}, line->player_color);
×
133
                curTextPos.x += bracket1_size;
×
134
                // Spielername
135
                font->Draw(curTextPos, line->player, FontStyle{}, line->player_color);
×
136
                curTextPos.x += font->getWidth(line->player);
×
137
                // Klammer 2 (>)
138
                font->Draw(curTextPos, "> ", FontStyle{}, line->player_color);
×
139
                curTextPos.x += bracket2_size;
×
140
            }
141
        }
142
        visit(
×
143
          [this, curTextPos](const auto& line) { // Draw msg
×
144
              this->font->Draw(curTextPos, line.msg, FontStyle{}, line.msg_color);
×
145
          },
×
146
          chat_lines[i + pos]);
×
147
        textPos.y += font->getHeight() + 2;
×
148
    }
149
}
1✔
150

151
void ctrlChat::WrapLine(unsigned short i)
6✔
152
{
153
    const RawChatLine& line = raw_chat_lines[i];
6✔
154

155
    // Breite von Zeitstring und Spielername berechnen (falls vorhanden)
156
    unsigned short prefix_width =
157
      (!line.time_string.empty() ? font->getWidth(line.time_string) : 0)
9✔
158
      + (!line.player.empty() ? (bracket1_size + bracket2_size + font->getWidth(line.player)) : 0);
9✔
159

160
    // Reicht die Breite des Textfeldes noch nichtmal dafür aus?
161
    if(prefix_width > GetSize().x - 2 - SCROLLBAR_WIDTH)
6✔
162
    {
163
        // dann können wir das gleich vergessen
164
        return;
×
165
    }
166

167
    // Zeilen ggf. wrappen, falls der Platz nich reicht und die Zeilenanfanänge in wi speichern
168
    glFont::WrapInfo wi =
169
      font->GetWrapInfo(line.msg, GetSize().x - prefix_width - 2 - SCROLLBAR_WIDTH, GetSize().x - 2 - SCROLLBAR_WIDTH);
12✔
170

171
    // Message-Strings erzeugen aus den WrapInfo
172
    std::vector<std::string> strings = wi.CreateSingleStrings(line.msg);
12✔
173

174
    // Zeilen hinzufügen
175
    for(unsigned i = 0; i < strings.size(); ++i)
12✔
176
    {
177
        if(i == 0)
6✔
178
        {
179
            PrimaryChatLine wrap_line = line;
12✔
180
            wrap_line.msg = strings[i];
6✔
181
            chat_lines.emplace_back(std::move(wrap_line));
6✔
182
        } else
183
        {
184
            chat_lines.emplace_back(SecondaryChatLine{strings[i], line.msg_color});
×
185
        }
186
    }
187
}
188

189
void ctrlChat::AddMessage(const std::string& time_string, const std::string& player, const unsigned player_color,
6✔
190
                          const std::string& msg, const unsigned msg_color)
191
{
192
    RawChatLine line;
12✔
193
    line.time_string = time_string;
6✔
194
    line.player = player;
6✔
195
    line.player_color = player_color;
6✔
196
    line.msg = msg;
6✔
197
    line.msg_color = msg_color;
6✔
198
    raw_chat_lines.emplace_back(std::move(line));
6✔
199

200
    const size_t oldlength = chat_lines.size();
6✔
201

202
    // Loggen
203
    LOG.write("%s <") % time_string;
6✔
204
    LOG.writeColored("%1%", player_color) % player;
6✔
205
    LOG.write(">: ");
6✔
206
    LOG.writeColored("%1%", msg_color) % msg;
6✔
207
    LOG.write("\n");
6✔
208

209
    // Umbrechen
210
    WrapLine(raw_chat_lines.size() - 1);
6✔
211

212
    // Scrollbar Bescheid sagen
213
    auto* scrollbar = GetCtrl<ctrlScrollBar>(0);
6✔
214
    scrollbar->SetRange(unsigned(chat_lines.size()));
6✔
215

216
    // Waren wir am Ende? Dann mit runterscrollen
217
    if(scrollbar->GetScrollPos() + page_size == oldlength)
6✔
218
        scrollbar->SetScrollPos(chat_lines.size() - page_size);
×
219
}
6✔
220

221
bool ctrlChat::Msg_MouseMove(const MouseCoords& mc)
×
222
{
223
    return RelayMouseMessage(&Window::Msg_MouseMove, mc);
×
224
}
225

226
bool ctrlChat::Msg_LeftDown(const MouseCoords& mc)
×
227
{
228
    return RelayMouseMessage(&Window::Msg_LeftDown, mc);
×
229
}
230

231
bool ctrlChat::Msg_LeftUp(const MouseCoords& mc)
×
232
{
233
    return RelayMouseMessage(&Window::Msg_LeftUp, mc);
×
234
}
235

236
bool ctrlChat::Msg_WheelUp(const MouseCoords& mc)
×
237
{
238
    if(IsPointInRect(mc.GetPos(), Rect(GetDrawPos() + DrawPoint(2, 2), GetSize() - Extent(2, 4))))
×
239
    {
240
        auto* scrollbar = GetCtrl<ctrlScrollBar>(0);
×
241
        scrollbar->Scroll(-3);
×
242
        return true;
×
243
    } else
244
        return false;
×
245
}
246

247
bool ctrlChat::Msg_WheelDown(const MouseCoords& mc)
×
248
{
249
    if(IsPointInRect(mc.GetPos(), Rect(GetDrawPos() + DrawPoint(2, 2), GetSize() - Extent(2, 4))))
×
250
    {
251
        auto* scrollbar = GetCtrl<ctrlScrollBar>(0);
×
252
        scrollbar->Scroll(+3);
×
253
        return true;
×
254
    } else
255
        return false;
×
256
}
257

258
unsigned ctrlChat::CalcUniqueColor(const std::string& name)
3✔
259
{
260
    unsigned checksum = CalcChecksumOfBuffer(name.c_str(), name.length()) * name.length();
3✔
261
    unsigned color = checksum | (checksum << 12) | 0xff000000;
3✔
262
    return color;
3✔
263
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc