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

Return-To-The-Roots / s25client / 22797872430

07 Mar 2026 11:05AM UTC coverage: 50.156% (-0.2%) from 50.327%
22797872430

Pull #1890

github

web-flow
Merge 4597ccbf9 into d2a3730c9
Pull Request #1890: Add support for borderless Windows

155 of 626 new or added lines in 44 files covered. (24.76%)

26 existing lines in 9 files now uncovered.

23041 of 45939 relevant lines covered (50.16%)

44513.07 hits per line

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

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

5
#include "ctrlList.h"
6
#include "CollisionDetection.h"
7
#include "ctrlScrollBar.h"
8
#include "driver/MouseCoords.h"
9
#include "ogl/glFont.h"
10

11
ctrlList::ctrlList(Window* parent, unsigned id, const DrawPoint& pos, const Extent& size, TextureColor tc,
58✔
12
                   const glFont* font)
58✔
13
    : Window(parent, id, pos, elMax(size, Extent(22, 4))), tc(tc), font(font)
58✔
14
{
15
    pagesize = (GetSize().y - 4) / font->getHeight();
58✔
16

17
    AddScrollBar(0, DrawPoint(GetSize().x - 20, 0), Extent(20, GetSize().y), 20, tc, pagesize);
58✔
18
}
58✔
19

20
ctrlList::~ctrlList()
116✔
21
{
22
    DeleteAllItems();
58✔
23
}
116✔
24

25
void ctrlList::SetSelection(const boost::optional<unsigned>& selection)
87✔
26
{
27
    if(selection != selection_ && (!selection || *selection < lines.size()))
87✔
28
    {
29
        selection_ = selection;
79✔
30
        if(selection && GetParent())
79✔
31
            GetParent()->Msg_ListSelectItem(GetID(), *selection);
79✔
32
    }
33
}
87✔
34

35
bool ctrlList::Msg_MouseMove(const MouseCoords& mc)
×
36
{
37
    auto* scrollbar = GetCtrl<ctrlScrollBar>(0);
×
38

39
    mouseover_ = GetItemFromPos(mc.pos);
×
40
    // Wenn Maus in der Liste
41
    if(mouseover_)
×
42
    {
43
        const std::string itemTxt = GetItemText(*mouseover_);
×
44
        tooltip_.ShowTooltip((font->getWidth(itemTxt) > GetListDrawArea().getSize().x) ? itemTxt : "");
×
45
        return true;
×
46
    }
47

48
    tooltip_.HideTooltip();
×
49

50
    // Für die Scrollbar weiterleiten
51
    return scrollbar->Msg_MouseMove(mc);
×
52
}
53

54
bool ctrlList::Msg_LeftDown(const MouseCoords& mc)
×
55
{
56
    auto* scrollbar = GetCtrl<ctrlScrollBar>(0);
×
57

58
    const auto itemIdx = GetItemFromPos(mc.pos);
×
59
    if(itemIdx)
×
60
    {
61
        tooltip_.HideTooltip();
×
62
        SetSelection(*itemIdx);
×
63
        return true;
×
64
    }
65

66
    // Für die Scrollbar weiterleiten
67
    return scrollbar->Msg_LeftDown(mc);
×
68
}
69

70
bool ctrlList::Msg_RightDown(const MouseCoords& mc)
×
71
{
72
    auto* scrollbar = GetCtrl<ctrlScrollBar>(0);
×
73

74
    auto itemIdx = GetItemFromPos(mc.pos);
×
75
    if(itemIdx)
×
76
    {
77
        tooltip_.HideTooltip();
×
78
        SetSelection(*itemIdx);
×
79
        return true;
×
80
    }
81

82
    // Für die Scrollbar weiterleiten
83
    return scrollbar->Msg_RightDown(mc);
×
84
}
85

86
bool ctrlList::Msg_LeftUp(const MouseCoords& mc)
×
87
{
88
    auto* scrollbar = GetCtrl<ctrlScrollBar>(0);
×
89

90
    // Wenn Maus in der Liste
91
    if(IsPointInRect(mc.pos, GetListDrawArea()))
×
92
    {
93
        // Doppelklick? Dann noch einen extra Eventhandler aufrufen
94
        if(mc.dbl_click && GetParent() && selection_)
×
95
            GetParent()->Msg_ListChooseItem(GetID(), *selection_);
×
96

97
        return true;
×
98
    }
99

100
    // Für die Scrollbar weiterleiten
101
    return scrollbar->Msg_LeftUp(mc);
×
102
}
103

104
bool ctrlList::Msg_WheelUp(const MouseCoords& mc)
×
105
{
106
    // If mouse in list or scrollbar
107
    if(IsPointInRect(mc.pos, GetFullDrawArea()))
×
108
    {
109
        auto* scrollbar = GetCtrl<ctrlScrollBar>(0);
×
110
        scrollbar->Scroll(-1);
×
111
        return true;
×
112
    }
113

114
    return false;
×
115
}
116

117
bool ctrlList::Msg_WheelDown(const MouseCoords& mc)
×
118
{
119
    // If mouse in list
120
    if(IsPointInRect(mc.pos, GetFullDrawArea()))
×
121
    {
122
        auto* scrollbar = GetCtrl<ctrlScrollBar>(0);
×
123
        scrollbar->Scroll(+1);
×
124
        return true;
×
125
    }
126

127
    return false;
×
128
}
129

UNCOV
130
void ctrlList::Draw_()
×
131
{
132
    if(lines.empty())
×
133
        return;
×
134

135
    // Box malen
136
    Draw3D(Rect(GetDrawPos(), GetSize()), tc, false);
×
137

138
    // Scrolleiste zeichnen
139
    Window::Draw_();
×
140

141
    // Wieviele Linien anzeigen?
142
    const unsigned show_lines = (pagesize > lines.size() ? unsigned(lines.size()) : pagesize);
×
143

144
    const unsigned scrollbarPos = GetCtrl<ctrlScrollBar>(0)->GetScrollPos();
×
145
    DrawPoint curPos = GetDrawPos() + DrawPoint(2, 2);
×
146
    // Listeneinträge zeichnen
147
    for(unsigned i = 0; i < show_lines; ++i)
×
148
    {
149
        // Schwarze Markierung, wenn die Maus drauf ist
150
        if(i + scrollbarPos == mouseover_)
×
151
            DrawRectangle(Rect(curPos, Extent(GetSize().x - 22, font->getHeight())), 0x80000000);
×
152

153
        // Text an sich
154
        font->Draw(curPos, lines[i + scrollbarPos], FontStyle{},
×
155
                   (selection_ == i + scrollbarPos ? 0xFFFFAA00 : COLOR_YELLOW), GetSize().x - 22);
×
156
        curPos.y += font->getHeight();
×
157
    }
158
}
159

160
void ctrlList::AddItem(const std::string& text)
282✔
161
{
162
    // lines-Array ggf vergrößern
163
    lines.push_back(text);
282✔
164

165
    GetCtrl<ctrlScrollBar>(0)->SetRange(static_cast<unsigned short>(lines.size()));
282✔
166
}
282✔
167

NEW
168
void ctrlList::SetItemText(const unsigned id, const std::string& text)
×
169
{
NEW
170
    lines.at(id) = text;
×
171
}
×
172

173
void ctrlList::DeleteAllItems()
59✔
174
{
175
    lines.clear();
59✔
176
    selection_ = boost::none;
59✔
177
}
59✔
178

179
const std::string& ctrlList::GetItemText(unsigned line) const
57✔
180
{
181
    RTTR_Assert(line < lines.size());
57✔
182
    return lines[line];
57✔
183
}
184

185
const std::string& ctrlList::GetSelItemText() const
15✔
186
{
187
    static const std::string EMPTY;
15✔
188
    if(selection_)
30✔
189
        return GetItemText(*selection_);
14✔
190
    else
191
        return EMPTY;
1✔
192
}
193

194
void ctrlList::Resize(const Extent& newSize)
330✔
195
{
196
    auto* scrollbar = GetCtrl<ctrlScrollBar>(0);
330✔
197
    scrollbar->SetPos(DrawPoint(newSize.x - 20, 0));
330✔
198
    scrollbar->Resize(Extent(20, newSize.y));
330✔
199

200
    pagesize = (newSize.y - 4) / font->getHeight();
330✔
201

202
    scrollbar->SetPageSize(pagesize);
330✔
203

204
    // If the size was enlarged we have to check that we don't try to
205
    // display more lines than present
206
    if(newSize.y > GetSize().y)
330✔
207
        while(lines.size() - scrollbar->GetScrollPos() < pagesize && scrollbar->GetScrollPos() > 0)
246✔
208
            scrollbar->SetScrollPos(scrollbar->GetScrollPos() - 1);
×
209

210
    Window::Resize(newSize);
330✔
211
}
330✔
212

UNCOV
213
void ctrlList::Swap(unsigned first, unsigned second)
×
214
{
215
    // Evtl Selection auf das jeweilige Element beibehalten?
216
    if(first == selection_)
×
217
        selection_ = second;
×
218
    else if(second == selection_)
×
219
        selection_ = first;
×
220

221
    // Strings vertauschen
222
    std::swap(lines[first], lines[second]);
×
223
}
×
224

225
void ctrlList::Remove(const unsigned index)
11✔
226
{
227
    if(index < lines.size())
11✔
228
    {
229
        lines.erase(lines.begin() + index);
10✔
230
        if(!selection_)
10✔
231
            return;
×
232

233
        // Keep current item selected
234
        if(*selection_ > index)
10✔
235
            --*selection_;
5✔
236
        else if(*selection_ == index)
5✔
237
        {
238
            // Current item deleted -> clear selection
239
            selection_ = boost::none;
4✔
240
            if(index < GetNumLines())
4✔
241
                SetSelection(index); // select item now at deleted position
2✔
242
            else if(index > 0u)
2✔
243
                SetSelection(index - 1u); // or previous if item at end deleted
1✔
244
        }
245
    }
246
}
247

248
Rect ctrlList::GetListDrawArea() const
×
249
{
250
    // Full area minus scrollbar
251
    Rect result = GetFullDrawArea();
×
252
    Extent size = result.getSize();
×
253
    size.x -= 20;
×
254
    result.setSize(size);
×
255
    return result;
×
256
}
257

258
boost::optional<unsigned> ctrlList::GetItemFromPos(const Position& pos) const
×
259
{
260
    const Rect listDrawArea = GetListDrawArea();
×
261
    if(!IsPointInRect(pos, listDrawArea))
×
262
        return boost::none;
×
263
    const unsigned itemIdx =
264
      (pos.y - listDrawArea.getOrigin().y) / font->getHeight() + GetCtrl<ctrlScrollBar>(0)->GetScrollPos();
×
265
    if(itemIdx >= GetNumLines())
×
266
        return boost::none;
×
267
    return itemIdx;
×
268
}
269

270
Rect ctrlList::GetFullDrawArea() const
×
271
{
272
    return Rect(GetDrawPos() + DrawPoint(2, 2), GetSize() - Extent(2, 4));
×
273
}
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