2 Copyright (C) 2024 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_MEMORY
23 #define INCLUDE_VECTOR
25 #include "coretypes.h"
26 #include "pretty-print.h"
28 #include "make-unique.h"
29 #include "text-art/selftests.h"
30 #include "text-art/tree-widget.h"
31 #include "text-art/dump-widget-info.h"
33 using namespace text_art
;
35 /* class text_art::tree_widget : public text_art::widget. */
37 static const int margin_width
= 3;
39 std::unique_ptr
<tree_widget
>
40 tree_widget::make (styled_string str
, const theme
&theme
, style::id_t style_id
)
42 return ::make_unique
<tree_widget
>
43 (::make_unique
<text_widget
> (std::move (str
)),
48 std::unique_ptr
<tree_widget
>
49 tree_widget::make (const dump_widget_info
&dwi
, pretty_printer
*pp
)
51 return tree_widget::make (styled_string (dwi
.m_sm
, pp_formatted_text (pp
)),
53 dwi
.get_tree_style_id ());
56 std::unique_ptr
<tree_widget
>
57 tree_widget::make (const dump_widget_info
&dwi
, const char *str
)
59 return tree_widget::make (styled_string (dwi
.m_sm
, str
),
61 dwi
.get_tree_style_id ());
64 std::unique_ptr
<tree_widget
>
65 tree_widget::from_fmt (const dump_widget_info
&dwi
,
66 printer_fn format_decoder
,
71 styled_string styled_str
72 (styled_string::from_fmt_va (dwi
.m_sm
, format_decoder
, fmt
, &ap
));
74 return make (std::move (styled_str
), dwi
.m_theme
, dwi
.get_tree_style_id ());
78 tree_widget::get_desc () const
84 tree_widget::calc_req_size ()
86 canvas::size_t result (0, 0);
89 canvas::size_t node_req_size
= m_node
->get_req_size ();
90 result
.h
+= node_req_size
.h
;
91 result
.w
= std::max (result
.w
, node_req_size
.w
);
93 for (auto &child
: m_children
)
95 canvas::size_t child_req_size
= child
->get_req_size ();
96 result
.h
+= child_req_size
.h
;
97 result
.w
= std::max (result
.w
, child_req_size
.w
+ margin_width
);
103 tree_widget::update_child_alloc_rects ()
105 const int x
= get_min_x ();
106 int y
= get_min_y ();
109 m_node
->set_alloc_rect
110 (canvas::rect_t (canvas::coord_t (x
, y
),
111 canvas::size_t (get_alloc_w (),
112 m_node
->get_req_h ())));
113 y
+= m_node
->get_req_h ();
115 for (auto &child
: m_children
)
117 child
->set_alloc_rect
118 (canvas::rect_t (canvas::coord_t (x
+ margin_width
, y
),
119 canvas::size_t (get_alloc_w () - margin_width
,
120 child
->get_req_h ())));
121 y
+= child
->get_req_h ();
126 tree_widget::paint_to_canvas (canvas
&canvas
)
129 m_node
->paint_to_canvas (canvas
);
130 const int min_x
= get_min_x ();
131 const canvas::cell_t cell_child_non_final
132 (m_theme
.get_cell (theme::cell_kind::TREE_CHILD_NON_FINAL
, m_style_id
));
133 const canvas::cell_t cell_child_final
134 (m_theme
.get_cell (theme::cell_kind::TREE_CHILD_FINAL
, m_style_id
));
135 const canvas::cell_t cell_x_connector
136 (m_theme
.get_cell (theme::cell_kind::TREE_X_CONNECTOR
, m_style_id
));
137 const canvas::cell_t cell_y_connector
138 (m_theme
.get_cell (theme::cell_kind::TREE_Y_CONNECTOR
, m_style_id
));
140 for (auto &child
: m_children
)
142 child
->paint_to_canvas (canvas
);
144 const bool last_child
= (++idx
== m_children
.size ());
145 canvas
.paint (canvas::coord_t (min_x
+ 1, child
->get_min_y ()),
147 canvas
.paint (canvas::coord_t (min_x
, child
->get_min_y ()),
148 last_child
? cell_child_final
: cell_child_non_final
);
150 for (int y
= child
->get_min_y () + 1; y
<= child
->get_max_y (); y
++)
151 canvas
.paint (canvas::coord_t (min_x
, y
), cell_y_connector
);
159 static std::unique_ptr
<tree_widget
>
160 make_test_tree_widget (const dump_widget_info
&dwi
)
162 std::unique_ptr
<tree_widget
> w
163 (tree_widget::from_fmt (dwi
, nullptr, "Root"));
164 for (int i
= 0; i
< 3; i
++)
166 std::unique_ptr
<tree_widget
> c
167 (tree_widget::from_fmt (dwi
, nullptr, "Child %i", i
));
168 for (int j
= 0; j
< 3; j
++)
169 c
->add_child (tree_widget::from_fmt (dwi
, nullptr,
170 "Grandchild %i %i", i
, j
));
171 w
->add_child (std::move (c
));
181 style::id_t
default_style_id (sm
.get_or_create_id (style ()));
185 dump_widget_info
dwi (sm
, theme
, default_style_id
);
186 canvas
c (make_test_tree_widget (dwi
)->to_canvas (sm
));
191 "| +- Grandchild 0 0\n"
192 "| +- Grandchild 0 1\n"
193 "| `- Grandchild 0 2\n"
195 "| +- Grandchild 1 0\n"
196 "| +- Grandchild 1 1\n"
197 "| `- Grandchild 1 2\n"
199 " +- Grandchild 2 0\n"
200 " +- Grandchild 2 1\n"
201 " `- Grandchild 2 2\n"));
206 dump_widget_info
dwi (sm
, theme
, default_style_id
);
207 canvas
c (make_test_tree_widget (dwi
)->to_canvas (sm
));
212 "│ ├─ Grandchild 0 0\n"
213 "│ ├─ Grandchild 0 1\n"
214 "│ ╰─ Grandchild 0 2\n"
216 "│ ├─ Grandchild 1 0\n"
217 "│ ├─ Grandchild 1 1\n"
218 "│ ╰─ Grandchild 1 2\n"
220 " ├─ Grandchild 2 0\n"
221 " ├─ Grandchild 2 1\n"
222 " ╰─ Grandchild 2 2\n"));
226 /* Run all selftests in this file. */
229 text_art_tree_widget_cc_tests ()
234 } // namespace selftest
237 #endif /* #if CHECKING_P */