1 /* Hierarchical diagram elements.
2 Copyright (C) 2023-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/widget.h"
32 using namespace text_art
;
34 /* class text_art::widget. */
37 widget::to_canvas (const style_manager
&style_mgr
)
39 const canvas::size_t req_size
= get_req_size ();
41 /* For now we don't constrain the allocation; we give
42 the widget the full size it requested, and widgets
43 assume they got their full size request. */
44 const canvas::size_t alloc_size
= req_size
;
46 set_alloc_rect (canvas::rect_t (canvas::coord_t (0, 0), alloc_size
));
47 canvas
c (alloc_size
, style_mgr
);
52 /* class text_art::vbox_widget : public text_art::container_widget. */
55 vbox_widget::get_desc () const
61 vbox_widget::calc_req_size ()
63 canvas::size_t result (0, 0);
64 for (auto &child
: m_children
)
66 canvas::size_t child_req_size
= child
->get_req_size();
67 result
.h
+= child_req_size
.h
;
68 result
.w
= std::max (result
.w
, child_req_size
.w
);
74 vbox_widget::update_child_alloc_rects ()
76 const int x
= get_min_x ();
78 for (auto &child
: m_children
)
81 (canvas::rect_t (canvas::coord_t (x
, y
),
82 canvas::size_t (get_alloc_w (),
83 child
->get_req_h ())));
84 y
+= child
->get_req_h ();
88 /* class text_art::text_widget : public text_art::leaf_widget. */
91 text_widget::get_desc () const
97 text_widget::calc_req_size ()
99 return canvas::size_t (m_str
.size (), 1);
103 text_widget::paint_to_canvas (canvas
&canvas
)
105 canvas
.paint_text (get_top_left (), m_str
);
108 /* class text_art::canvas_widget : public text_art::leaf_widget. */
111 canvas_widget::get_desc () const
113 return "canvas_widget";
117 canvas_widget::calc_req_size ()
119 return m_canvas
.get_size ();
123 canvas_widget::paint_to_canvas (canvas
&canvas
)
125 for (int y
= 0; y
< m_canvas
.get_size ().h
; y
++)
126 for (int x
= 0; x
< m_canvas
.get_size ().w
; x
++)
128 canvas::coord_t
rel_xy (x
, y
);
129 canvas
.paint (get_top_left () + rel_xy
,
130 m_canvas
.get (rel_xy
));
138 /* Concrete widget subclass for writing selftests.
139 Requests a hard-coded size, and fills its allocated rectangle
140 with a specific character. */
142 class test_widget
: public leaf_widget
145 test_widget (canvas::size_t size
, char ch
)
146 : m_test_size (size
), m_ch (ch
)
149 const char *get_desc () const final override
151 return "test_widget";
153 canvas::size_t calc_req_size () final override
157 void paint_to_canvas (canvas
&canvas
) final override
159 canvas
.fill (get_alloc_rect (), canvas::cell_t (m_ch
));
163 canvas::size_t m_test_size
;
171 test_widget
w (canvas::size_t (3, 3), 'A');
172 canvas
c (w
.to_canvas (sm
));
184 text_widget
w (styled_string (sm
, "hello world"));
185 canvas
c (w
.to_canvas (sm
));
192 test_wrapper_widget ()
195 wrapper_widget
w (::make_unique
<test_widget
> (canvas::size_t (3, 3), 'B'));
196 canvas
c (w
.to_canvas (sm
));
209 for (int i
= 0; i
< 5; i
++)
211 (::make_unique
<text_widget
>
212 (styled_string::from_fmt (sm
, nullptr,
213 "this is line %i", i
)));
214 canvas
c (w
.to_canvas (sm
));
221 "this is line 4\n"));
229 w
.add_child (::make_unique
<test_widget
> (canvas::size_t (1, 3), 'A'));
230 w
.add_child (::make_unique
<test_widget
> (canvas::size_t (4, 1), 'B'));
231 w
.add_child (::make_unique
<test_widget
> (canvas::size_t (1, 2), 'C'));
232 canvas
c (w
.to_canvas (sm
));
244 test_canvas_widget ()
247 canvas
inner_canvas (canvas::size_t (5, 3), sm
);
248 inner_canvas
.fill (canvas::rect_t (canvas::coord_t (0, 0),
249 canvas::size_t (5, 3)),
250 canvas::cell_t ('a'));
251 canvas_widget
cw (std::move (inner_canvas
));
252 canvas
c (cw
.to_canvas (sm
));
260 /* Run all selftests in this file. */
263 text_art_widget_cc_tests ()
267 test_wrapper_widget ();
270 test_canvas_widget ();
273 } // namespace selftest
276 #endif /* #if CHECKING_P */