1/*
2 * Copyright (C) 2020-2022 The opuntiaOS Project Authors.
3 * + Contributed by Nikita Melekhin <nimelehin@gmail.com>
4 *
5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file.
7 */
8
9#include <libg/Color.h>
10#include <libui/Context.h>
11#include <libui/TextView.h>
12#include <utility>
13
14namespace UI {
15
16TextView::TextView(View* superview, const LG::Rect& frame)
17 : ScrollView(superview, frame)
18{
19}
20
21TextView::TextView(View* superview, Window* window, const LG::Rect& frame)
22 : ScrollView(superview, window, frame)
23{
24}
25
26void TextView::display(const LG::Rect& rect)
27{
28 LG::Context ctx = graphics_current_context();
29 ctx.add_clip(rect);
30
31 auto& f = font();
32 const size_t letter_spacing = f.glyph_spacing();
33 const size_t line_height = f.glyph_height();
34
35 int start_x = -content_offset().x();
36 int start_y = -content_offset().y();
37 int cur_x = start_x;
38 int cur_y = start_y;
39
40 for (int i = 0; i < m_text.size(); i++) {
41 if (m_text[i] == '\n') {
42 cur_x = start_x;
43 cur_y += line_height;
44 continue;
45 }
46
47 size_t glyph_width = f.glyph_width(m_text[i]) + letter_spacing;
48 if (bounds().contains(cur_x, cur_y) || bounds().contains(cur_x + glyph_width, cur_y + line_height)) {
49 ctx.draw({ cur_x, cur_y }, f.glyph_bitmap(m_text[i]));
50 }
51 cur_x += glyph_width;
52 }
53
54 display_scroll_indicators(ctx);
55}
56
57void TextView::mouse_entered(const LG::Point<int>& location)
58{
59 set_hovered(true);
60}
61
62void TextView::mouse_exited()
63{
64 set_hovered(false);
65}
66
67void TextView::recalc_text_size()
68{
69 const size_t letter_spacing = font().glyph_spacing();
70 const size_t line_height = font().glyph_height();
71
72 int cur_x = 0;
73 int max_x = 0;
74 int cur_y = 0;
75
76 for (int i = 0; i < m_text.size(); i++) {
77 if (m_text[i] == '\n') {
78 std::max(max_x, cur_x);
79 cur_x = 0;
80 cur_y += line_height;
81 continue;
82 }
83
84 size_t glyph_width = font().glyph_width(m_text[i]) + letter_spacing;
85 cur_x += glyph_width;
86 }
87
88 std::max(max_x, cur_x);
89 content_size().set(LG::Size(cur_x, cur_y + line_height));
90}
91
92} // namespace UI