2 Copyright (C) 2024-2025 Free Software Foundation, Inc.
3 Contributed by David Malcolm <dmalcolm@redhat.com>.
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
22 #define INCLUDE_VECTOR
24 #include "coretypes.h"
25 #include "pretty-print.h"
27 #include "make-unique.h"
28 #include "text-art/selftests.h"
29 #include "text-art/tree-widget.h"
30 #include "text-art/dump-widget-info.h"
32 using namespace text_art
;
34 /* class text_art::tree_widget : public text_art::widget. */
36 static const int margin_width
= 3;
38 std::unique_ptr
<tree_widget
>
39 tree_widget::make (styled_string str
, const theme
&theme
, style::id_t style_id
)
41 return ::make_unique
<tree_widget
>
42 (::make_unique
<text_widget
> (std::move (str
)),
47 std::unique_ptr
<tree_widget
>
48 tree_widget::make (const dump_widget_info
&dwi
, pretty_printer
*pp
)
50 return tree_widget::make (styled_string (dwi
.m_sm
, pp_formatted_text (pp
)),
52 dwi
.get_tree_style_id ());
55 std::unique_ptr
<tree_widget
>
56 tree_widget::make (const dump_widget_info
&dwi
, const char *str
)
58 return tree_widget::make (styled_string (dwi
.m_sm
, str
),
60 dwi
.get_tree_style_id ());
63 std::unique_ptr
<tree_widget
>
64 tree_widget::from_fmt (const dump_widget_info
&dwi
,
65 printer_fn format_decoder
,
70 styled_string styled_str
71 (styled_string::from_fmt_va (dwi
.m_sm
, format_decoder
, fmt
, &ap
));
73 return make (std::move (styled_str
), dwi
.m_theme
, dwi
.get_tree_style_id ());
77 tree_widget::get_desc () const
83 tree_widget::calc_req_size ()
85 canvas::size_t result (0, 0);
88 canvas::size_t node_req_size
= m_node
->get_req_size ();
89 result
.h
+= node_req_size
.h
;
90 result
.w
= std::max (result
.w
, node_req_size
.w
);
92 for (auto &child
: m_children
)
94 canvas::size_t child_req_size
= child
->get_req_size ();
95 result
.h
+= child_req_size
.h
;
96 result
.w
= std::max (result
.w
, child_req_size
.w
+ margin_width
);
102 tree_widget::update_child_alloc_rects ()
104 const int x
= get_min_x ();
105 int y
= get_min_y ();
108 m_node
->set_alloc_rect
109 (canvas::rect_t (canvas::coord_t (x
, y
),
110 canvas::size_t (get_alloc_w (),
111 m_node
->get_req_h ())));
112 y
+= m_node
->get_req_h ();
114 for (auto &child
: m_children
)
116 child
->set_alloc_rect
117 (canvas::rect_t (canvas::coord_t (x
+ margin_width
, y
),
118 canvas::size_t (get_alloc_w () - margin_width
,
119 child
->get_req_h ())));
120 y
+= child
->get_req_h ();
125 tree_widget::paint_to_canvas (canvas
&canvas
)
128 m_node
->paint_to_canvas (canvas
);
129 const int min_x
= get_min_x ();
130 const canvas::cell_t cell_child_non_final
131 (m_theme
.get_cell (theme::cell_kind::TREE_CHILD_NON_FINAL
, m_style_id
));
132 const canvas::cell_t cell_child_final
133 (m_theme
.get_cell (theme::cell_kind::TREE_CHILD_FINAL
, m_style_id
));
134 const canvas::cell_t cell_x_connector
135 (m_theme
.get_cell (theme::cell_kind::TREE_X_CONNECTOR
, m_style_id
));
136 const canvas::cell_t cell_y_connector
137 (m_theme
.get_cell (theme::cell_kind::TREE_Y_CONNECTOR
, m_style_id
));
139 for (auto &child
: m_children
)
141 child
->paint_to_canvas (canvas
);
143 const bool last_child
= (++idx
== m_children
.size ());
144 canvas
.paint (canvas::coord_t (min_x
+ 1, child
->get_min_y ()),
146 canvas
.paint (canvas::coord_t (min_x
, child
->get_min_y ()),
147 last_child
? cell_child_final
: cell_child_non_final
);
149 for (int y
= child
->get_min_y () + 1; y
<= child
->get_max_y (); y
++)
150 canvas
.paint (canvas::coord_t (min_x
, y
), cell_y_connector
);
158 static std::unique_ptr
<tree_widget
>
159 make_test_tree_widget (const dump_widget_info
&dwi
)
161 std::unique_ptr
<tree_widget
> w
162 (tree_widget::from_fmt (dwi
, nullptr, "Root"));
163 for (int i
= 0; i
< 3; i
++)
165 std::unique_ptr
<tree_widget
> c
166 (tree_widget::from_fmt (dwi
, nullptr, "Child %i", i
));
167 for (int j
= 0; j
< 3; j
++)
168 c
->add_child (tree_widget::from_fmt (dwi
, nullptr,
169 "Grandchild %i %i", i
, j
));
170 w
->add_child (std::move (c
));
180 style::id_t
default_style_id (sm
.get_or_create_id (style ()));
184 dump_widget_info
dwi (sm
, theme
, default_style_id
);
185 canvas
c (make_test_tree_widget (dwi
)->to_canvas (sm
));
190 "| +- Grandchild 0 0\n"
191 "| +- Grandchild 0 1\n"
192 "| `- Grandchild 0 2\n"
194 "| +- Grandchild 1 0\n"
195 "| +- Grandchild 1 1\n"
196 "| `- Grandchild 1 2\n"
198 " +- Grandchild 2 0\n"
199 " +- Grandchild 2 1\n"
200 " `- Grandchild 2 2\n"));
205 dump_widget_info
dwi (sm
, theme
, default_style_id
);
206 canvas
c (make_test_tree_widget (dwi
)->to_canvas (sm
));
211 "│ ├─ Grandchild 0 0\n"
212 "│ ├─ Grandchild 0 1\n"
213 "│ ╰─ Grandchild 0 2\n"
215 "│ ├─ Grandchild 1 0\n"
216 "│ ├─ Grandchild 1 1\n"
217 "│ ╰─ Grandchild 1 2\n"
219 " ├─ Grandchild 2 0\n"
220 " ├─ Grandchild 2 1\n"
221 " ╰─ Grandchild 2 2\n"));
225 /* Run all selftests in this file. */
228 text_art_tree_widget_cc_tests ()
233 } // namespace selftest
236 #endif /* #if CHECKING_P */