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)
47 self = new Rectangle (this);
48 self->set_outline (false);
49 self->set_fill (false);
53 Box::Box (Item* parent, Duple const & p, Orientation o)
57 , top_padding (0), right_padding (0), bottom_padding (0), left_padding (0)
58 , top_margin (0), right_margin (0), bottom_margin (0), left_margin (0)
60 self = new Rectangle (this);
61 self->set_outline (false);
62 self->set_fill (false);
66 Box::render (Rect const & area, Cairo::RefPtr<Cairo::Context> context) const
68 Item::render_children (area, context);
72 Box::compute_bounding_box () const
74 _bounding_box = boost::none;
77 _bounding_box_dirty = false;
81 add_child_bounding_boxes (!collapse_on_hide);
84 Rect r = _bounding_box.get();
86 _bounding_box = r.expand (top_padding + outline_width() + top_margin,
87 right_padding + outline_width() + right_margin,
88 bottom_padding + outline_width() + bottom_margin,
89 left_padding + outline_width() + left_margin);
92 _bounding_box_dirty = false;
96 Box::set_spacing (double s)
102 Box::set_padding (double t, double r, double b, double l)
111 right_padding = last;
115 bottom_padding = last;
123 Box::set_margin (double t, double r, double b, double l)
134 bottom_margin = last;
144 if (_bounding_box_dirty) {
145 compute_bounding_box ();
148 if (!_bounding_box) {
153 Rect r (_bounding_box.get());
155 /* XXX need to shrink by margin */
161 Box::reposition_children ()
163 Duple previous_edge (0, 0);
164 Distance largest_width = 0;
165 Distance largest_height = 0;
169 for (std::list<Item*>::iterator i = _items.begin(); ++i != _items.end(); ++i) {
170 boost::optional<Rect> bb = (*i)->bounding_box();
172 largest_height = std::max (largest_height, bb.get().height());
173 largest_width = std::max (largest_height, bb.get().width());
178 for (std::list<Item*>::iterator i = _items.begin(); ++i != _items.end(); ++i) {
180 (*i)->set_position (previous_edge);
182 if (orientation == Vertical) {
187 shift = largest_height;
189 boost::optional<Rect> bb = (*i)->bounding_box();
191 if (!(*i)->visible()) {
192 /* invisible child */
193 if (!collapse_on_hide) {
194 /* still add in its size */
196 shift += bb.get().height();
201 shift += bb.get().height();
206 previous_edge = previous_edge.translate (Duple (0, spacing + shift));
212 shift = largest_width;
214 boost::optional<Rect> bb = (*i)->bounding_box();
216 if (!(*i)->visible()) {
217 if (!collapse_on_hide) {
219 shift += bb.get().width();
224 shift += bb.get().width();
229 previous_edge = previous_edge.translate (Duple (0, spacing + shift));
233 _bounding_box_dirty = true;
238 Box::pack_end (Item* i, double extra_padding)
244 /* prepend new child */
246 reposition_children ();
249 Box::pack_start (Item* i, double extra_padding)
255 /* append new child */
257 reposition_children ();
267 Box::child_changed ()
269 /* catch visibility and size changes */
271 Item::child_changed ();
272 reposition_children ();
276 Box::set_collapse_on_hide (bool yn)
278 if (collapse_on_hide != yn) {
279 collapse_on_hide = yn;
280 reposition_children ();
286 VBox::VBox (Canvas* c)
294 VBox::VBox (Item* i, Duple const & position)
295 : Box (i, position, Vertical)
299 HBox::HBox (Canvas* c)
300 : Box (c, Horizontal)
304 : Box (i, Horizontal)
307 HBox::HBox (Item* i, Duple const & position)
308 : Box (i, position, Horizontal)