diff options
Diffstat (limited to 'gcc/text-art/widget.cc')
-rw-r--r-- | gcc/text-art/widget.cc | 276 |
1 files changed, 276 insertions, 0 deletions
diff --git a/gcc/text-art/widget.cc b/gcc/text-art/widget.cc new file mode 100644 index 0000000..b64a623 --- /dev/null +++ b/gcc/text-art/widget.cc @@ -0,0 +1,276 @@ +/* Hierarchical diagram elements. + Copyright (C) 2023 Free Software Foundation, Inc. + Contributed by David Malcolm <dmalcolm@redhat.com>. + +This file is part of GCC. + +GCC is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free +Software Foundation; either version 3, or (at your option) any later +version. + +GCC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with GCC; see the file COPYING3. If not see +<http://www.gnu.org/licenses/>. */ + +#include "config.h" +#define INCLUDE_MEMORY +#define INCLUDE_VECTOR +#include "system.h" +#include "coretypes.h" +#include "pretty-print.h" +#include "selftest.h" +#include "make-unique.h" +#include "text-art/selftests.h" +#include "text-art/widget.h" + +using namespace text_art; + +/* class text_art::widget. */ + +canvas +widget::to_canvas (const style_manager &style_mgr) +{ + const canvas::size_t req_size = get_req_size (); + + /* For now we don't constrain the allocation; we give + the widget the full size it requested, and widgets + assume they got their full size request. */ + const canvas::size_t alloc_size = req_size; + + set_alloc_rect (canvas::rect_t (canvas::coord_t (0, 0), alloc_size)); + canvas c (alloc_size, style_mgr); + paint_to_canvas (c); + return c; +} + +/* class text_art::vbox_widget : public text_art::container_widget. */ + +const char * +vbox_widget::get_desc () const +{ + return "vbox_widget"; +} + +canvas::size_t +vbox_widget::calc_req_size () +{ + canvas::size_t result (0, 0); + for (auto &child : m_children) + { + canvas::size_t child_req_size = child->get_req_size(); + result.h += child_req_size.h; + result.w = std::max (result.w, child_req_size.w); + } + return result; +} + +void +vbox_widget::update_child_alloc_rects () +{ + const int x = get_min_x (); + int y = get_min_y (); + for (auto &child : m_children) + { + child->set_alloc_rect + (canvas::rect_t (canvas::coord_t (x, y), + canvas::size_t (get_alloc_w (), + child->get_req_h ()))); + y += child->get_req_h (); + } +} + +/* class text_art::text_widget : public text_art::leaf_widget. */ + +const char * +text_widget::get_desc () const +{ + return "text_widget"; +} + +canvas::size_t +text_widget::calc_req_size () +{ + return canvas::size_t (m_str.size (), 1); +} + +void +text_widget::paint_to_canvas (canvas &canvas) +{ + canvas.paint_text (get_top_left (), m_str); +} + +/* class text_art::canvas_widget : public text_art::leaf_widget. */ + +const char * +canvas_widget::get_desc () const +{ + return "canvas_widget"; +} + +canvas::size_t +canvas_widget::calc_req_size () +{ + return m_canvas.get_size (); +} + +void +canvas_widget::paint_to_canvas (canvas &canvas) +{ + for (int y = 0; y < m_canvas.get_size ().h; y++) + for (int x = 0; x < m_canvas.get_size ().w; x++) + { + canvas::coord_t rel_xy (x, y); + canvas.paint (get_top_left () + rel_xy, + m_canvas.get (rel_xy)); + } +} + +#if CHECKING_P + +namespace selftest { + +/* Concrete widget subclass for writing selftests. + Requests a hard-coded size, and fills its allocated rectangle + with a specific character. */ + +class test_widget : public leaf_widget +{ +public: + test_widget (canvas::size_t size, char ch) + : m_test_size (size), m_ch (ch) + {} + + const char *get_desc () const final override + { + return "test_widget"; + } + canvas::size_t calc_req_size () final override + { + return m_test_size; + } + void paint_to_canvas (canvas &canvas) final override + { + canvas.fill (get_alloc_rect (), canvas::cell_t (m_ch)); + } + +private: + canvas::size_t m_test_size; + char m_ch; +}; + +static void +test_test_widget () +{ + style_manager sm; + test_widget w (canvas::size_t (3, 3), 'A'); + canvas c (w.to_canvas (sm)); + ASSERT_CANVAS_STREQ + (c, false, + ("AAA\n" + "AAA\n" + "AAA\n")); +} + +static void +test_text_widget () +{ + style_manager sm; + text_widget w (styled_string (sm, "hello world")); + canvas c (w.to_canvas (sm)); + ASSERT_CANVAS_STREQ + (c, false, + ("hello world\n")); +} + +static void +test_wrapper_widget () +{ + style_manager sm; + wrapper_widget w (::make_unique<test_widget> (canvas::size_t (3, 3), 'B')); + canvas c (w.to_canvas (sm)); + ASSERT_CANVAS_STREQ + (c, false, + ("BBB\n" + "BBB\n" + "BBB\n")); +} + +static void +test_vbox_1 () +{ + style_manager sm; + vbox_widget w; + for (int i = 0; i < 5; i++) + w.add_child + (::make_unique <text_widget> + (styled_string::from_fmt (sm, nullptr, + "this is line %i", i))); + canvas c (w.to_canvas (sm)); + ASSERT_CANVAS_STREQ + (c, false, + ("this is line 0\n" + "this is line 1\n" + "this is line 2\n" + "this is line 3\n" + "this is line 4\n")); +} + +static void +test_vbox_2 () +{ + style_manager sm; + vbox_widget w; + w.add_child (::make_unique<test_widget> (canvas::size_t (1, 3), 'A')); + w.add_child (::make_unique<test_widget> (canvas::size_t (4, 1), 'B')); + w.add_child (::make_unique<test_widget> (canvas::size_t (1, 2), 'C')); + canvas c (w.to_canvas (sm)); + ASSERT_CANVAS_STREQ + (c, false, + ("AAAA\n" + "AAAA\n" + "AAAA\n" + "BBBB\n" + "CCCC\n" + "CCCC\n")); +} + +static void +test_canvas_widget () +{ + style_manager sm; + canvas inner_canvas (canvas::size_t (5, 3), sm); + inner_canvas.fill (canvas::rect_t (canvas::coord_t (0, 0), + canvas::size_t (5, 3)), + canvas::cell_t ('a')); + canvas_widget cw (std::move (inner_canvas)); + canvas c (cw.to_canvas (sm)); + ASSERT_CANVAS_STREQ + (c, false, + ("aaaaa\n" + "aaaaa\n" + "aaaaa\n")); +} + +/* Run all selftests in this file. */ + +void +text_art_widget_cc_tests () +{ + test_test_widget (); + test_text_widget (); + test_wrapper_widget (); + test_vbox_1 (); + test_vbox_2 (); + test_canvas_widget (); +} + +} // namespace selftest + + +#endif /* #if CHECKING_P */ |