/* * Copyright (C) 2021 Paul Davis * * This program 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 2 of the License, or * (at your option) any later version. * * This program 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 this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ #ifndef __CANVAS_TABLE_H__ #define __CANVAS_TABLE_H__ #include #include "canvas/rectangle.h" namespace ArdourCanvas { class Rectangle; class LIBCANVAS_API Table : public Rectangle { public: Table (Canvas *); Table (Item *); void set_row_spacing (Distance s); void set_col_spacing (Distance s); void set_padding (FourDimensions const & padding); #if 0 void set_margin (double top, double right = -1.0, double bottom = -1.0, double left = -1.0); /* aliases so that CSS box model terms work */ void set_border_width (double w) { set_outline_width (w); } void set_border_color (Gtkmm2ext::Color c) { set_outline_color (c); } void set_collapse_on_hide (bool); #endif void set_homogenous (bool); void set_row_homogenous (bool); void set_col_homogenous (bool); void compute_bounding_box () const; void size_request (double& w, double& h) const; void size_allocate_children (Rect const & r); struct Index { Index (uint32_t xv, uint32_t yv) : x (xv), y (yv) {} bool operator== (Index const & other) const { return x == other.x && y == other.y; } uint32_t x; uint32_t y; }; /* These three functions cannot be used with Table, and will cause a fatal error if called. */ void add (Item *); void add_front (Item *); void remove (Item *); /* How to place an item in a table */ void attach (Item*, uint32_t upper_left_x, uint32_t upper_left_y, uint32_t lower_right_x, uint32_t lower_right_y, PackOptions row_options = PackOptions (0), PackOptions col_options = PackOptions (0), FourDimensions padding = FourDimensions (0.)); void attach (Item*, uint32_t upper_left_x, uint32_t upper_right_y, PackOptions row_options = PackOptions (0), PackOptions col_options = PackOptions (0), FourDimensions padding = FourDimensions (0.)); void attach_with_span (Item*, uint32_t upper_left_x, uint32_t upper_left_y, uint32_t hspan, uint32_t vspan, PackOptions row_options = PackOptions (0), PackOptions col_options = PackOptions (0), FourDimensions padding = FourDimensions (0.)); // Not implemented, but also not needed thus far // void detach (Item*); void set_row_size (uint32_t row, Distance); void set_col_size (uint32_t row, Distance); protected: void child_changed (bool bbox_changed); private: FourDimensions padding; FourDimensions margin; Distance row_spacing; Distance col_spacing; bool collapse_on_hide; bool row_homogenous; bool col_homogenous; bool draw_hgrid; bool draw_vgrid; mutable bool ignore_child_changes; struct CellInfo { Item* content; PackOptions row_options; PackOptions col_options; Index upper_left; Index lower_right; Duple natural_size; Duple allocate_size; Rect full_size; FourDimensions padding; CellInfo (Item* i, PackOptions ro, PackOptions co, Index const & ul, Index const & lr, FourDimensions const & p) : content (i) , row_options (ro) , col_options (co) , upper_left (ul) , lower_right (lr) , padding (p) {} }; struct index_hash { std::size_t operator() (Table::Index const & i) const { /* use upper left coordinate for hash */ return ((uint64_t) i.x << 32) | i.y; } }; /* cell lookup, indexed by upper left corner only */ typedef std::unordered_map Cells; Cells cells; struct AxisInfo { uint32_t expanders; uint32_t shrinkers; Distance natural_size; Distance expand; Distance shrink; Distance user_size; bool occupied; Distance spacing; AxisInfo() : expanders (0), shrinkers (0), natural_size (0), expand (0), shrink (0), user_size (0), occupied (false), spacing (0) {} void reset () { expanders = 0; shrinkers = 0; natural_size = 0; expand = 0; shrink = 0; /* leave user size alone */ occupied = false; spacing = 0; } }; typedef std::vector AxisInfos; AxisInfos row_info; AxisInfos col_info; void _add (Item *); void _add_front (Item *); void _remove (Item *); void layout (); Duple compute (Rect const &); }; } /* namespace */ #endif /* __CANVAS_TABLE_H__ */