1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
#include "listwidgetbackend.h"
#include "listformatter.h"
#include "utils.h"
namespace newsboat {
ListWidgetBackend::ListWidgetBackend(const std::string& list_name,
const std::string& context, Stfl::Form& form, RegexManager& rxman)
: list_name(list_name)
, form(form)
, listfmt(&rxman, context)
, num_lines(0)
, scroll_offset(0)
, get_formatted_line({})
{
}
ListWidgetBackend::ListWidgetBackend(const std::string& list_name, Stfl::Form& form)
: list_name(list_name)
, form(form)
, listfmt()
, num_lines(0)
, scroll_offset(0)
, get_formatted_line({})
{
}
void ListWidgetBackend::stfl_replace_list(std::string stfl)
{
num_lines = 0;
scroll_offset = 0;
line_cache.clear();
get_formatted_line = {};
form.modify(list_name, "replace", stfl);
invalidate_list_content(0, {});
on_list_changed();
}
std::uint32_t ListWidgetBackend::get_width()
{
return utils::to_u(form.get(list_name + ":w"));
}
std::uint32_t ListWidgetBackend::get_height()
{
return utils::to_u(form.get(list_name + ":h"));
}
std::uint32_t ListWidgetBackend::get_num_lines()
{
return num_lines;
}
void ListWidgetBackend::invalidate_list_content(std::uint32_t line_count,
std::function<StflRichText(std::uint32_t, std::uint32_t)> get_line_method)
{
line_cache.clear();
get_formatted_line = get_line_method;
num_lines = line_count;
on_list_changed();
render();
}
void ListWidgetBackend::update_position(std::uint32_t pos,
std::uint32_t new_scroll_offset)
{
scroll_offset = new_scroll_offset;
form.set(list_name + "_pos", std::to_string(pos - scroll_offset));
form.set(list_name + "_offset", "0");
render();
}
void ListWidgetBackend::render()
{
const auto viewport_width = get_width();
const auto viewport_height = get_height();
const auto visible_content_lines = std::min(viewport_height, num_lines - scroll_offset);
listfmt.clear();
for (std::uint32_t i = 0; i < visible_content_lines; ++i) {
const std::uint32_t line = scroll_offset + i;
auto formatted_line = StflRichText::from_plaintext("NO FORMATTER DEFINED");
if (line_cache.count(line) >= 1) {
formatted_line = line_cache.at(line);
} else if (get_formatted_line) {
formatted_line = get_formatted_line(line, viewport_width);
line_cache.insert({line, formatted_line});
}
listfmt.add_line(formatted_line);
}
form.modify(list_name, "replace_inner", listfmt.format_list());
}
} // namespace newsboat
|