2 Copyright (C) 2011-2014 Paul Davis
3 Author: Carl Hetherington <cth@carlh.net>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 #include "canvas/box.h"
23 #include "canvas/rectangle.h"
25 using namespace ArdourCanvas;
27 Box::Box (Canvas* canvas, Orientation o)
31 , top_padding (0), right_padding (0), bottom_padding (0), left_padding (0)
32 , top_margin (0), right_margin (0), bottom_margin (0), left_margin (0)
35 self = new Rectangle (this);
36 self->set_outline (false);
37 self->set_fill (false);
40 Box::Box (Item* parent, Orientation o)
44 , top_padding (0), right_padding (0), bottom_padding (0), left_padding (0)
45 , top_margin (0), right_margin (0), bottom_margin (0), left_margin (0)
48 self = new Rectangle (this);
49 self->set_outline (false);
50 self->set_fill (false);
54 Box::Box (Item* parent, Duple const & p, Orientation o)
58 , top_padding (0), right_padding (0), bottom_padding (0), left_padding (0)
59 , top_margin (0), right_margin (0), bottom_margin (0), left_margin (0)
62 self = new Rectangle (this);
63 self->set_outline (false);
64 self->set_fill (false);
68 Box::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) const
70 Item::render_children (area, context);
74 Box::compute_bounding_box () const
76 _bounding_box = Rect();
79 _bounding_box_dirty = false;
83 add_child_bounding_boxes (!collapse_on_hide);
86 Rect r = _bounding_box;
88 _bounding_box = r.expand (top_padding + outline_width() + top_margin,
89 right_padding + outline_width() + right_margin,
90 bottom_padding + outline_width() + bottom_margin,
91 left_padding + outline_width() + left_margin);
94 _bounding_box_dirty = false;
98 Box::set_spacing (double s)
104 Box::set_padding (double t, double r, double b, double l)
113 right_padding = last;
117 bottom_padding = last;
125 Box::set_margin (double t, double r, double b, double l)
136 bottom_margin = last;
146 if (_bounding_box_dirty) {
147 compute_bounding_box ();
150 if (!_bounding_box) {
155 Rect r (_bounding_box);
157 /* XXX need to shrink by margin */
163 Box::reposition_children ()
165 Duple previous_edge (0, 0);
166 Distance largest_width = 0;
167 Distance largest_height = 0;
172 for (std::list<Item*>::iterator i = _items.begin(); ++i != _items.end(); ++i) {
173 Rect bb = (*i)->bounding_box();
175 largest_height = std::max (largest_height, bb.height());
176 largest_width = std::max (largest_width, bb.width());
180 uniform_size = Rect (0, 0, largest_width, largest_height);
183 for (std::list<Item*>::iterator i = _items.begin(); ++i != _items.end(); ++i) {
185 (*i)->set_position (previous_edge);
188 (*i)->size_allocate (uniform_size);
191 if (orientation == Vertical) {
195 Rect bb = (*i)->bounding_box();
197 if (!(*i)->visible()) {
198 /* invisible child */
199 if (!collapse_on_hide) {
200 /* still add in its size */
202 shift += bb.height();
207 shift += bb.height();
211 previous_edge = previous_edge.translate (Duple (0, spacing + shift));
216 Rect bb = (*i)->bounding_box();
218 if (!(*i)->visible()) {
219 if (!collapse_on_hide) {
230 previous_edge = previous_edge.translate (Duple (spacing + shift, 0));
234 _bounding_box_dirty = true;
239 Box::pack_end (Item* i, double extra_padding)
245 /* prepend new child */
247 reposition_children ();
250 Box::pack_start (Item* i, double extra_padding)
256 /* append new child */
258 reposition_children ();
268 Box::child_changed ()
270 /* catch visibility and size changes */
272 Item::child_changed ();
273 reposition_children ();
277 Box::set_collapse_on_hide (bool yn)
279 if (collapse_on_hide != yn) {
280 collapse_on_hide = yn;
281 reposition_children ();
287 VBox::VBox (Canvas* c)
295 VBox::VBox (Item* i, Duple const & position)
296 : Box (i, position, Vertical)
300 HBox::HBox (Canvas* c)
301 : Box (c, Horizontal)
305 : Box (i, Horizontal)
308 HBox::HBox (Item* i, Duple const & position)
309 : Box (i, position, Horizontal)