diff --git a/libs/canvas/canvas/constrained_item.h b/libs/canvas/canvas/constrained_item.h deleted file mode 100644 index 41066354cc..0000000000 --- a/libs/canvas/canvas/constrained_item.h +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright (C) 2020 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_CONSTRAINED_ITEM_H__ -#define __CANVAS_CONSTRAINED_ITEM_H__ - -#include "kiwi/kiwi.h" - -#include "canvas/types.h" -#include "canvas/visibility.h" - -namespace ArdourCanvas -{ - -class Item; -class ConstraintPacker; - - -class /* LIBCANVAS_API */ ConstrainedItem -{ - public: - ConstrainedItem (Item& i); - virtual ~ConstrainedItem (); - - Item& item() { return _item; } - - kiwi::Variable& left () { return _left; } - kiwi::Variable& right () { return _right; } - kiwi::Variable& top () { return _top; } - kiwi::Variable& bottom () { return _bottom; } - kiwi::Variable& width () { return _width; } - kiwi::Variable& height () { return _height; } - kiwi::Variable& center_x () { return _center_x; } - kiwi::Variable& center_y () { return _center_y; } - - kiwi::Variable const & left () const { return _left; } - kiwi::Variable const & right () const { return _right; } - kiwi::Variable const & top () const { return _top; } - kiwi::Variable const & bottom () const { return _bottom; } - kiwi::Variable const & width () const { return _width; } - kiwi::Variable const & height () const { return _height; } - kiwi::Variable const & center_x () const { return _center_x; } - kiwi::Variable const & center_y () const { return _center_y; } - - kiwi::Variable& left_padding () { return _left_padding; } - kiwi::Variable& right_padding () { return _right_padding; } - kiwi::Variable& top_padding () { return _top_padding; } - kiwi::Variable& bottom_padding () { return _bottom_padding; } - - void constrained (ConstraintPacker const & parent); - virtual bool involved (kiwi::Constraint const &) const; - - std::vector const & constraints() const { return _constraints; } - void add_constraint (kiwi::Constraint const & c) { _constraints.push_back (c); } - - ConstrainedItem& at (Duple const &); - ConstrainedItem& size (Duple const &); - ConstrainedItem& box (Rect const &); - - ConstrainedItem& left_of (ConstrainedItem const &, Distance pad = 0); - ConstrainedItem& right_of (ConstrainedItem const &, Distance pad = 0); - ConstrainedItem& above (ConstrainedItem const &, Distance pad = 0); - ConstrainedItem& below (ConstrainedItem const &, Distance pad = 0); - ConstrainedItem& x_centered (ConstrainedItem const &, Distance offset = 0); - ConstrainedItem& y_centered (ConstrainedItem const &, Distance offset = 0); - ConstrainedItem& centered_on (ConstrainedItem const &, Distance xoffset = 0, Distance yoffset = 0); - ConstrainedItem& top_aligned_with (ConstrainedItem const &, Distance offset = 0); - ConstrainedItem& bottom_aligned_with (ConstrainedItem const &, Distance offset = 0); - ConstrainedItem& left_aligned_with (ConstrainedItem const &, Distance offset = 0); - ConstrainedItem& right_aligned_with (ConstrainedItem const &, Distance offset = 0); - ConstrainedItem& same_size_as (ConstrainedItem const &, Distance wdelta = 0, Distance hdelta = 0); - ConstrainedItem& same_width_as (ConstrainedItem const &, Distance delta = 0); - ConstrainedItem& same_height_as (ConstrainedItem const &, Distance delta = 0); - - virtual void dump (std::ostream&); - - protected: - Item& _item; - std::vector _constraints; - - kiwi::Variable _left; - kiwi::Variable _right; - kiwi::Variable _top; - kiwi::Variable _bottom; - kiwi::Variable _width; - kiwi::Variable _height; - kiwi::Variable _left_padding; - kiwi::Variable _right_padding; - kiwi::Variable _top_padding; - kiwi::Variable _bottom_padding; - - /* derived */ - - kiwi::Variable _center_x; - kiwi::Variable _center_y; -}; - -class /* LIBCANVAS_API */ BoxConstrainedItem : public ConstrainedItem -{ - public: - BoxConstrainedItem (Item& i, PackOptions primary_axis_opts, PackOptions secondary_axis_opts); - ~BoxConstrainedItem (); - - virtual bool involved (kiwi::Constraint const &) const; - - kiwi::Variable& left_margin () { return _left_margin; } - kiwi::Variable& right_margin () { return _right_margin; } - kiwi::Variable& top_margin () { return _top_margin; } - kiwi::Variable& bottom_margin () { return _bottom_margin; } - - PackOptions primary_axis_pack_options() const { return _primary_axis_pack_options; } - PackOptions secondary_axis_pack_options() const { return _secondary_axis_pack_options; } - - void dump (std::ostream&); - - private: - kiwi::Variable _left_margin; - kiwi::Variable _right_margin; - kiwi::Variable _top_margin; - kiwi::Variable _bottom_margin; - - PackOptions _primary_axis_pack_options; - PackOptions _secondary_axis_pack_options; -}; - -} - -#endif diff --git a/libs/canvas/canvas/constraint_packer.h b/libs/canvas/canvas/constraint_packer.h deleted file mode 100644 index 2871d51863..0000000000 --- a/libs/canvas/canvas/constraint_packer.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (C) 2020 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_CONSTRAINT_PACKER_H__ -#define __CANVAS_CONSTRAINT_PACKER_H__ - -#include -#include - -#include "canvas/container.h" -#include "kiwi/kiwi.h" - -namespace ArdourCanvas -{ - -class Rectangle; -class ConstrainedItem; -class BoxConstrainedItem; - -class LIBCANVAS_API ConstraintPacker : public Container -{ -public: - ConstraintPacker (Canvas *, Orientation o = Horizontal); - ConstraintPacker (Item *, Orientation o = Horizontal); - - void set_spacing (double s); - void set_padding (double top, double right = -1.0, double bottom = -1.0, double left = -1.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 add (Item *); - void add_front (Item *); - void remove (Item *); - void constrain (kiwi::Constraint const &); - - BoxConstrainedItem* pack_start (Item*, PackOptions primary_axis_packing = PackOptions (0), PackOptions secondary_axis_packing = PackOptions (PackExpand|PackFill)); - BoxConstrainedItem* pack_end (Item*, PackOptions primary_axis_packing = PackOptions (0), PackOptions secondary_axis_packing = PackOptions (PackExpand|PackFill)); - - virtual ConstrainedItem* add_constrained (Item* item); - - void solve (); - void apply (kiwi::Solver*); - - void compute_bounding_box () const; - - void _size_allocate (Rect const &); - void size_request (Distance& w, Distance& h) const; - - void render (Rect const & area, Cairo::RefPtr context) const; - - kiwi::Variable width; - kiwi::Variable height; - - protected: - void child_changed (bool bbox_changed); - - Orientation _orientation; - double _spacing; - double _top_padding; - double _bottom_padding; - double _left_padding; - double _right_padding; - double _top_margin; - double _bottom_margin; - double _left_margin; - double _right_margin; - - kiwi::Variable expanded_item_size; - - typedef std::map ConstrainedItemMap; - ConstrainedItemMap constrained_map; - typedef std::list ConstraintList; - ConstraintList constraint_list; - kiwi::Solver _solver; - bool in_alloc; - bool _need_constraint_update; - - void add_constrained_internal (Item*, ConstrainedItem*); - - void add_constraints (kiwi::Solver&, ConstrainedItem*) const; - - void non_const_size_request (Distance& w, Distance& h); - virtual void update_constraints (); - - void add_vertical_box_constraints (kiwi::Solver& solver, BoxConstrainedItem* ci, BoxConstrainedItem* prev, double main_dimenion, double second_dimension, kiwi::Variable& alloc_var); - void add_horizontal_box_constraints (kiwi::Solver& solver, BoxConstrainedItem* ci, BoxConstrainedItem* prev, double main_dimenion, double second_dimension, kiwi::Variable& alloc_var); - - private: - typedef std::list BoxPackedItems; - BoxPackedItems packed; - - BoxConstrainedItem* pack (Item*, PackOptions primary_axis_packing, PackOptions secondary_axis_packing); - void box_size_request (Distance& w, Distance& h) const; -}; - -} - -#endif diff --git a/libs/canvas/constrained_item.cc b/libs/canvas/constrained_item.cc deleted file mode 100644 index 4ba10d721a..0000000000 --- a/libs/canvas/constrained_item.cc +++ /dev/null @@ -1,273 +0,0 @@ -/* - * Copyright (C) 2020 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. - */ - -#include - -#include "canvas/item.h" -#include "canvas/types.h" -#include "canvas/constrained_item.h" - -using namespace ArdourCanvas; - -using std::cerr; -using std::endl; -using kiwi::Constraint; -using kiwi::Variable; - -ConstrainedItem::ConstrainedItem (Item& i) - : _item (i) - , _left (_item.name + " left") - , _right (_item.name + " right") - , _top (_item.name + " top") - , _bottom (_item.name + " bottom") - , _width (_item.name + " width") - , _height (_item.name + " height") - , _left_padding (_item.name + " left_padding") - , _right_padding (_item.name + " right_padding") - , _top_padding (_item.name + " top_padding") - , _bottom_padding (_item.name + " bottom_padding") - , _center_x (_item.name + " center_x") - , _center_y (_item.name + " center_y") -{ - /* setup center_{x,y} variables in case calling/using - * code wants to use them for additional constraints - */ - - _constraints.push_back (center_x() == left() + (width() / 2.)); - _constraints.push_back (center_y() == top() + (height() / 2.)); - - _constraints.push_back (_right == _left + _width); - _constraints.push_back (_bottom == _top + _height); -} - -ConstrainedItem::~ConstrainedItem () -{ -} - -void -ConstrainedItem::constrained (ConstraintPacker const & parent) -{ - /* our variables should be set. Deliver computed size to item */ - - Rect r (_left.value(), _top.value(), _right.value(), _bottom.value()); - //dump (cerr); - // cerr << _item.whoami() << " constrained-alloc " << r << endl; - - _item.size_allocate (r); -} - -void -ConstrainedItem::dump (std::ostream& out) -{ - out << _item.name << " value dump:\n" - << '\t' << "left: " << _left.value() << '\n' - << '\t' << "right: " << _right.value() << '\n' - << '\t' << "top: " << _top.value() << '\n' - << '\t' << "bottom: " << _bottom.value() << '\n' - << '\t' << "width: " << _width.value() << '\n' - << '\t' << "height: " << _height.value() << '\n' - << '\t' << "right_padding: " << _right_padding.value() << '\n' - << '\t' << "left_padding: " << _left_padding.value() << '\n' - << '\t' << "top_padding: " << _top_padding.value() << '\n' - << '\t' << "bottom_padding: " << _bottom_padding.value() << '\n' - << '\t' << "center_x: " << _center_x.value() << '\n' - << '\t' << "center_y: " << _center_y.value() << '\n'; -} - -bool -ConstrainedItem::involved (Constraint const & c) const -{ - if (c.involves (_left) || - c.involves (_right) || - c.involves (_top) || - c.involves (_bottom) || - c.involves (_width) || - c.involves (_height) || - c.involves (_center_x) || - c.involves (_center_y)) { - return true; - } - - return false; -} - -/*** BoxConstrainedItem */ - -BoxConstrainedItem::BoxConstrainedItem (Item& parent, PackOptions primary_axis_opts, PackOptions secondary_axis_opts) - : ConstrainedItem (parent) - , _left_margin (_item.name + " left_margin") - , _right_margin (_item.name + " right_margin") - , _top_margin (_item.name + " top_margin") - , _bottom_margin (_item.name + " bottom_margin") - , _primary_axis_pack_options (primary_axis_opts) - , _secondary_axis_pack_options (secondary_axis_opts) -{ -} - -BoxConstrainedItem::~BoxConstrainedItem () -{ -} - -bool -BoxConstrainedItem::involved (Constraint const & c) const -{ - if (ConstrainedItem::involved (c)) { - return true; - } - - if (c.involves (_left_margin) || - c.involves (_right_margin) || - c.involves (_top_margin) || - c.involves (_bottom_margin)) { - return true; - } - - return false; -} - -void -BoxConstrainedItem::dump (std::ostream& out) -{ - ConstrainedItem::dump (out); - - out << '\t' << "left_margin: " << _left_margin.value() << '\n' - << '\t' << "right_margin: " << _right_margin.value() << '\n' - << '\t' << "top_margin: " << _top_margin.value() << '\n' - << '\t' << "bottom_margin: " << _bottom_margin.value() << '\n'; -} - -ConstrainedItem& -ConstrainedItem::at (Duple const & d) -{ - _constraints.push_back (_left == d.x); - _constraints.push_back (_top == d.y); - - return *this; -} - -ConstrainedItem& -ConstrainedItem::size (Duple const & d) -{ - _constraints.push_back (_width == d.x); - _constraints.push_back (_height == d.y); - - return *this; -} - -ConstrainedItem& -ConstrainedItem::box (Rect const & r) -{ - _constraints.push_back (_left == r.x0); - _constraints.push_back (_top == r.y0); - _constraints.push_back (_width == r.width()); - _constraints.push_back (_height == r.height()); - - return *this; -} - - -ConstrainedItem& -ConstrainedItem::left_of (ConstrainedItem const & other, Distance by) -{ - _constraints.push_back (_right_padding == by); - _constraints.push_back (_right == other.left() + _right_padding); - return *this; -} - -ConstrainedItem& -ConstrainedItem::right_of (ConstrainedItem const & other, Distance by) -{ - _constraints.push_back (_left_padding == by); - _constraints.push_back (_left == other.right() + _left_padding); - return *this; -} - -ConstrainedItem& -ConstrainedItem::above (ConstrainedItem const & other, Distance by) -{ - _constraints.push_back (_bottom_padding == by); - _constraints.push_back (_bottom == other.top() + _bottom_padding); - return *this; -} - -ConstrainedItem& -ConstrainedItem::below (ConstrainedItem const & other, Distance by) -{ - _constraints.push_back (_top_padding == by); - _constraints.push_back (_top == other.bottom() + _top_padding); - return *this; -} - -ConstrainedItem& -ConstrainedItem::centered_on (ConstrainedItem const & other, Distance xoffset, Distance yoffset) -{ - _constraints.push_back (_center_x == other.center_x() + xoffset); - _constraints.push_back (_center_y == other.center_y() + yoffset); - return *this; -} - -ConstrainedItem& -ConstrainedItem::top_aligned_with (ConstrainedItem const & other, Distance offset) -{ - _constraints.push_back (_top == other.top() + offset); - return *this; -} - -ConstrainedItem& -ConstrainedItem::bottom_aligned_with (ConstrainedItem const & other, Distance offset) -{ - _constraints.push_back (_bottom == other.bottom() + offset); - return *this; -} - -ConstrainedItem& -ConstrainedItem::left_aligned_with (ConstrainedItem const & other, Distance offset) -{ - _constraints.push_back (_left == other.left() + offset); - return *this; -} - -ConstrainedItem& -ConstrainedItem::right_aligned_with (ConstrainedItem const & other, Distance offset) -{ - _constraints.push_back (_right == other.right() + offset); - return *this; -} - -ConstrainedItem& -ConstrainedItem::same_size_as (ConstrainedItem const & other, Distance wdelta, Distance hdelta) -{ - _constraints.push_back (_width == other.width() + wdelta); - _constraints.push_back (_height == other.height() + hdelta); - return *this; -} - -ConstrainedItem& -ConstrainedItem::same_width_as (ConstrainedItem const & other, Distance delta) -{ - _constraints.push_back (_width == other.width() + delta); - return *this; -} - -ConstrainedItem& -ConstrainedItem::same_height_as (ConstrainedItem const & other, Distance delta) -{ - _constraints.push_back (_height == other.height() + delta); - return *this; -} - diff --git a/libs/canvas/constraint_packer.cc b/libs/canvas/constraint_packer.cc deleted file mode 100644 index 96cdadc8d2..0000000000 --- a/libs/canvas/constraint_packer.cc +++ /dev/null @@ -1,769 +0,0 @@ -/* - * Copyright (C) 2020 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. - */ - -#include - -#include "pbd/i18n.h" -#include "pbd/unwind.h" -#include "pbd/stacktrace.h" - -#include "kiwi/kiwi.h" - -#include "canvas/canvas.h" -#include "canvas/constraint_packer.h" -#include "canvas/constrained_item.h" -#include "canvas/item.h" -#include "canvas/rectangle.h" - -using namespace ArdourCanvas; - -using std::cerr; -using std::endl; -using std::vector; -using kiwi::Constraint; -using namespace kiwi; - -ConstraintPacker::ConstraintPacker (Canvas* canvas, Orientation o) - : Container (canvas) - , width (X_("packer width")) - , height (X_("packer height")) - , _orientation (o) - , _spacing (0) - , _top_padding (0) - , _bottom_padding (0) - , _left_padding (0) - , _right_padding (0) - , _top_margin (0) - , _bottom_margin (0) - , _left_margin (0) - , _right_margin (0) - , in_alloc (false) - , _need_constraint_update (false) -{ - set_fill (false); - set_outline (false); - set_layout_sensitive (true); - - _solver.addEditVariable (width, kiwi::strength::strong); - _solver.addEditVariable (height, kiwi::strength::strong); -} - -ConstraintPacker::ConstraintPacker (Item* parent, Orientation o) - : Container (parent) - , width (X_("packer width")) - , height (X_("packer height")) - , _orientation (o) - , _spacing (0) - , _top_padding (0) - , _bottom_padding (0) - , _left_padding (0) - , _right_padding (0) - , _top_margin (0) - , _bottom_margin (0) - , _left_margin (0) - , _right_margin (0) - , in_alloc (false) - , _need_constraint_update (false) -{ - set_fill (false); - set_outline (false); - set_layout_sensitive (true); - - _solver.addEditVariable (width, kiwi::strength::strong); - _solver.addEditVariable (height, kiwi::strength::strong); -} - -void -ConstraintPacker::compute_bounding_box () const -{ - _bounding_box = _allocation; - bb_clean (); -} - -void -ConstraintPacker::child_changed (bool bbox_changed) -{ - Item::child_changed (bbox_changed); - - if (in_alloc || !bbox_changed) { - return; - } -#if 0 - cerr << "CP, child bbox changed\n"; - - for (ConstrainedItemMap::iterator x = constrained_map.begin(); x != constrained_map.end(); ++x) { - - Duple i; - x->first->size_request (i.x, i.y); - - if (r) { - - // cerr << x->first->whatami() << '/' << x->first->name << " has instrinsic size " << r << endl; - - kiwi::Variable& w (x->second->intrinsic_width()); - if (!r.width()) { - if (_solver.hasEditVariable (w)) { - _solver.removeEditVariable (w); - cerr << "\tremoved inttrinsic-width edit var\n"; - } - } else { - if (!_solver.hasEditVariable (w)) { - cerr << "\tadding intrinsic width constraints\n"; - _solver.addEditVariable (w, kiwi::strength::strong); - _solver.addConstraint (Constraint {x->second->width() >= w } | kiwi::strength::strong); - _solver.addConstraint (Constraint (x->second->width() <= w) | kiwi::strength::weak); - } - } - - kiwi::Variable& h (x->second->intrinsic_height()); - if (!r.height()) { - if (_solver.hasEditVariable (h)) { - _solver.removeEditVariable (h); - cerr << "\tremoved inttrinsic-height edit var\n"; - } - } else { - if (!_solver.hasEditVariable (h)) { - cerr << "\tadding intrinsic height constraints\n"; - _solver.addEditVariable (h, kiwi::strength::strong); - _solver.addConstraint (Constraint {x->second->height() >= h } | kiwi::strength::strong); - _solver.addConstraint (Constraint (x->second->height() <= h) | kiwi::strength::weak); - } - } - } - } -#endif -} - -void -ConstraintPacker::constrain (kiwi::Constraint const &c) -{ - constraint_list.push_back (c); - _need_constraint_update = true; -} - -void -ConstraintPacker::box_size_request (Distance& w, Distance& h) const -{ - BoxPackedItems::size_type n_expanding = 0; - BoxPackedItems::size_type n_nonexpanding = 0; - BoxPackedItems::size_type total = 0; - Distance non_expanding_used = 0; - Distance largest = 0; - Distance largest_opposite = 0; - Distance width; - Distance height; - - for (BoxPackedItems::const_iterator o = packed.begin(); o != packed.end(); ++o) { - - (*o)->item().size_request (width, height); - - // cerr << '\t' << (*o)->item().whoami() << " min " << i_min << " nat " << i_natural << endl; - - if ((*o)->primary_axis_pack_options() & PackExpand) { - n_expanding++; - - if (_orientation == Vertical) { - if (height > largest) { - largest = height; - } - } else { - if (width > largest) { - largest = width;; - } - if (height > largest) { - largest_opposite = height; - } - } - - } else { - n_nonexpanding++; - - if (_orientation == Vertical) { - non_expanding_used += height; - } else { - non_expanding_used += width; - } - } - - /* determine the maximum size for the opposite axis. All items - * will be this size or less on this axis - */ - - if (_orientation == Vertical) { - if (width > largest_opposite) { - largest_opposite = width; - } - } else { - if (height > largest_opposite) { - largest_opposite = height; - } - } - - total++; - } - - Duple r; - - if (_orientation == Vertical) { - // cerr << "+++ vertical box, neu = " << non_expanding_used << " neuo " << non_expanding_used_opposite << " largest = " << largest << " opp " << largest_opposite << " total " << total << endl; - height = non_expanding_used + (n_expanding * largest) + _top_margin + _bottom_margin + ((total - 1) * _spacing); - width= largest_opposite + _left_margin + _right_margin; - } else { - // cerr << "+++ horiz box, neu = " << non_expanding_used << " neuo " << non_expanding_used_opposite << " largest = " << largest << " opp " << largest_opposite << " total " << total << endl; - width = non_expanding_used + (n_expanding * largest) + _left_margin + _right_margin + ((total - 1) * _spacing); - height = largest_opposite + _top_margin + _bottom_margin; - - } -} - -void -ConstraintPacker::size_request (Distance& w, Distance& h) const -{ - const_cast(this)->non_const_size_request (w, h); -} - -void -ConstraintPacker::non_const_size_request (Distance& w, Distance& h) -{ - /* our parent wants to know how big we are. - - We may have some intrinsic size (i.e. "everything in this constraint - layout should fit into WxH". Just add two constraints on our width - and height, and solve. - - We may have one intrinsic dimension (i.e. "everything in this - constraint layout should fit into this (width|height). Ask all of - our children for the size-given-(W|H). Add constraints to represent - those values, and solve. - - We may have no intrinsic dimensions at all. This is the tricky one. - */ - - if (packed.size() == constrained_map.size()) { - /* All child items were packed using ::pack() */ - box_size_request (w, h); - return; - } - - if (_requested_width < 0 && _requested_height < 0) { - w = 100; - h = 100; - return; - } - - if (_need_constraint_update) { - const_cast(this)->update_constraints (); - } - - if (_requested_width > 0) { - _solver.suggestValue (width, _requested_width); - } else if (_requested_height > 0) { - _solver.suggestValue (height, _requested_height); - } - - _solver.updateVariables (); - apply (0); - - Rect bb (bounding_box()); - - w = std::max (bb.width(), _requested_width); - h = std::max (bb.height(), _requested_width); - - /* put solver back to default state */ - - _solver.reset (); - _need_constraint_update = true; -} - -void -ConstraintPacker::_size_allocate (Rect const & r) -{ - PBD::Unwinder uw (in_alloc, true); - double expanded_size; - - if (_layout_sensitive) { - _position = Duple (r.x0, r.y0); - _allocation = r; - } - - if (!packed.empty()) { - - BoxPackedItems::size_type n_expanding = 0; - BoxPackedItems::size_type n_nonexpanding = 0; - BoxPackedItems::size_type total = 0; - Distance non_expanding_used = 0; - - for (BoxPackedItems::iterator o = packed.begin(); o != packed.end(); ++o) { - if ((*o)->primary_axis_pack_options() & PackExpand) { - n_expanding++; - } else { - n_nonexpanding++; - - Distance w, h; - - (*o)->item().size_request (w, h); - - if (_orientation == Vertical) { - non_expanding_used += h; - } else { - non_expanding_used += w; - } - - } - total++; - } - - if (_orientation == Vertical) { - expanded_size = (r.height() - _top_margin - _bottom_margin - ((total - 1) * _spacing) - non_expanding_used) / n_expanding; - } else { - expanded_size = (r.width() - _left_margin - _right_margin - ((total - 1) * _spacing) - non_expanding_used) / n_expanding; - } - } - - if (_need_constraint_update) { - update_constraints (); - } - - _solver.suggestValue (width, r.width()); - _solver.suggestValue (height, r.height()); - - if (!packed.empty()) { - _solver.suggestValue (expanded_item_size, expanded_size); - } - - _solver.updateVariables (); - -#if 0 - // PBD::stacktrace (cerr, 100); - _canvas->dump (cerr); - _solver.dump (cerr); - - for (ConstrainedItemMap::const_iterator o = constrained_map.begin(); o != constrained_map.end(); ++o) { - o->second->dump (cerr); - } -#endif - - apply (0); - - _bounding_box_dirty = true; -} - -void -ConstraintPacker::add (Item* item) -{ - (void) add_constrained (item); -} - -void -ConstraintPacker::add_front (Item* item) -{ - (void) add_constrained (item); -} - -void -ConstraintPacker::add_constraints (Solver& s, ConstrainedItem* ci) const -{ - /* add any constraints inherent to this item */ - - vector const & vc (ci->constraints()); - - for (vector::const_iterator x = vc.begin(); x != vc.end(); ++x) { - s.addConstraint (*x); - } -} - -ConstrainedItem* -ConstraintPacker::add_constrained (Item* item) -{ - ConstrainedItem* ci = new ConstrainedItem (*item); - add_constrained_internal (item, ci); - return ci; -} - -void -ConstraintPacker::add_constrained_internal (Item* item, ConstrainedItem* ci) -{ - Item::add (item); - item->set_layout_sensitive (true); - constrained_map.insert (std::make_pair (item, ci)); - _need_constraint_update = true; - child_changed (true); -} - -void -ConstraintPacker::remove (Item* item) -{ - Item::remove (item); - - for (ConstrainedItemMap::iterator x = constrained_map.begin(); x != constrained_map.end(); ++x) { - - if (x->first == item) { - - /* remove any non-builtin constraints for this item */ - - for (ConstraintList::iterator c = constraint_list.begin(); c != constraint_list.end(); ++c) { - if (x->second->involved (*c)) { - constraint_list.erase (c); - } - } - - item->set_layout_sensitive (false); - - /* clean up */ - - delete x->second; - constrained_map.erase (x); - break; - } - - } - - for (BoxPackedItems::iterator t = packed.begin(); t != packed.end(); ++t) { - if (&(*t)->item() == item) { - packed.erase (t); - break; - } - } - - _need_constraint_update = true; -} - -void -ConstraintPacker::apply (Solver* s) -{ - for (ConstrainedItemMap::iterator x = constrained_map.begin(); x != constrained_map.end(); ++x) { - x->second->constrained (*this); - } -} - -void -ConstraintPacker::update_constraints () -{ - _solver.reset (); - _solver.addEditVariable (width, kiwi::strength::strong); - _solver.addEditVariable (height, kiwi::strength::strong); - - if (!packed.empty()) { - _solver.addEditVariable (expanded_item_size, kiwi::strength::strong); - } - - try { - - /* First handle box-packed items */ - - BoxPackedItems::iterator prev = packed.end(); - - for (BoxPackedItems::iterator o = packed.begin(); o != packed.end(); ++o) { - - Distance w, h; - - (*o)->item().size_request (w,h); - - if (_orientation == Vertical) { - add_vertical_box_constraints (_solver, *o, prev == packed.end() ? 0 : *prev, h, w, width); - } else { - add_horizontal_box_constraints (_solver, *o, prev == packed.end() ? 0 : *prev, w, h, height); - } - - prev = o; - } - - /* Now handle all other items (exclude those already dealt with */ - - for (ConstrainedItemMap::iterator x = constrained_map.begin(); x != constrained_map.end(); ++x) { - - if (std::find (packed.begin(), packed.end(), x->second) != packed.end()) { - add_constraints (_solver, x->second); - continue; - } - - Distance w, h; - ConstrainedItem* ci = x->second; - - x->first->size_request (w, h); - - _solver.addConstraint ((ci->width() == w) | kiwi::strength::medium); - _solver.addConstraint ((ci->height() == h) | kiwi::strength::medium); - - add_constraints (_solver, ci); - } - - /* Now add packer-level constraints */ - - for (ConstraintList::const_iterator c = constraint_list.begin(); c != constraint_list.end(); ++c) { - _solver.addConstraint (*c); - } - - _need_constraint_update = false; - - } catch (std::exception& e) { - cerr << "Setting up sovler failed: " << e.what() << endl; - } -} - -BoxConstrainedItem* -ConstraintPacker::pack_start (Item* item, PackOptions primary_axis_opts, PackOptions secondary_axis_opts) -{ - return pack (item, PackOptions (primary_axis_opts|PackFromStart), secondary_axis_opts); -} - -BoxConstrainedItem* -ConstraintPacker::pack_end (Item* item, PackOptions primary_axis_opts, PackOptions secondary_axis_opts) -{ - return pack (item, PackOptions (primary_axis_opts|PackFromEnd), secondary_axis_opts); -} - -BoxConstrainedItem* -ConstraintPacker::pack (Item* item, PackOptions primary_axis_opts, PackOptions secondary_axis_opts) -{ - BoxConstrainedItem* ci = new BoxConstrainedItem (*item, primary_axis_opts, secondary_axis_opts); - - add_constrained_internal (item, ci); - packed.push_back (ci); - - return ci; -} - - -/* It would be nice to do this with templates or even by passing ptr-to-method, - * but both of them interfere with the similarly meta-programming-ish nature of - * the way that kiwi builds Constraint objects from expressions. So a macro it - * is ... - */ - -#define add_box_constraints(\ - solver, \ - bci, \ - prev, \ - natural_main_dimension, \ - natural_second_dimension, \ - alloc_var, \ - m_main_dimension, \ - m_second_dimension, \ - m_trailing, \ - m_leading, \ - m_trailing_padding, \ - m_leading_padding, \ - m_second_trailing, \ - m_second_leading, \ - m_second_trailing_padding, \ - m_second_leading_padding, \ - m_trailing_margin, \ - m_leading_margin, \ - m_second_trailing_margin, \ - m_second_leading_margin) \ - \ - /* Add constraints that will size the item within this box */ \ - \ - /* set up constraints for expand/fill options, done by \ - * adjusting height and margins of each item \ - */ \ - \ - if (bci->primary_axis_pack_options() & PackExpand) { \ - \ - /* item will take up more than it's natural \ - * size, if space is available \ - */ \ - \ - if (bci->primary_axis_pack_options() & PackFill) { \ - \ - /* item is expanding to fill all \ - * available space and wants that space \ - * for itself. \ - */ \ - \ - solver.addConstraint ({(bci->m_main_dimension() == expanded_item_size) | kiwi::strength::strong}); \ - solver.addConstraint ({(bci->m_trailing_padding() == 0. ) | kiwi::strength::strong}); \ - solver.addConstraint ({(bci->m_leading_padding() == 0. ) | kiwi::strength::strong}); \ - \ - } else { \ - \ - /* item is expanding to fill all \ - * available space and wants that space \ - * as padding \ - */ \ - \ - solver.addConstraint ({bci->m_main_dimension() == natural_main_dimension}); \ - solver.addConstraint ({(bci->m_trailing_padding() + bci->m_leading_padding() + bci->m_main_dimension() == expanded_item_size) | kiwi::strength::strong}); \ - solver.addConstraint ({(bci->m_leading_padding() == bci->m_trailing_padding()) | kiwi::strength::strong}); \ - } \ - \ - } else { \ - \ - /* item is not going to expand to fill \ - * available space. just give it's preferred \ - * height. \ - */ \ - \ - /* cerr << bci->item().whoami() << " will usenatural height of " << natural.height() << endl; */ \ - \ - solver.addConstraint ({bci->m_main_dimension() == natural_main_dimension}); \ - solver.addConstraint ({bci->m_trailing_padding() == 0.}); \ - solver.addConstraint ({bci->m_leading_padding() == 0.}); \ - } \ - \ - /* now set upper upper edge of the item */ \ - \ - if (prev == 0) { \ - \ - /* first item */ \ - \ - solver.addConstraint ({(bci->m_trailing() == m_trailing_margin + bci->m_trailing_padding()) | kiwi::strength::strong}); \ - \ - } else { \ - /* subsequent items */ \ - \ - solver.addConstraint ({(bci->m_trailing() == prev->m_leading() + prev->m_leading_padding() + bci->m_trailing_padding() + _spacing) | kiwi::strength::strong}); \ - } \ - \ - solver.addConstraint ({bci->m_leading() == bci->m_trailing() + bci->m_main_dimension()}); \ - \ - /* set the side-effect variables and/or constants */ \ - \ - solver.addConstraint ({(bci->m_second_trailing_padding() == 0) | kiwi::strength::weak}); \ - solver.addConstraint ({(bci->m_second_leading_padding() == 0) | kiwi::strength::weak}); \ - \ - solver.addConstraint ({bci->m_second_trailing() + bci->m_second_dimension() == bci->m_second_leading()}); \ - solver.addConstraint ({(bci->m_second_trailing() == m_second_trailing_margin + bci->m_second_trailing_padding()) | kiwi::strength::strong}); \ - \ - if (!(bci->secondary_axis_pack_options() & PackExpand) && natural_second_dimension > 0) { \ - solver.addConstraint ({bci->m_second_dimension() == natural_second_dimension}); \ - } else { \ - solver.addConstraint ({(bci->m_second_dimension() == alloc_var - (m_second_trailing_margin + m_second_leading_margin + bci->m_second_leading_padding())) | kiwi::strength::strong}); \ - } - - -void -ConstraintPacker::add_vertical_box_constraints (kiwi::Solver& solver, BoxConstrainedItem* ci, BoxConstrainedItem* prev, double main_dimension, double second_dimension, kiwi::Variable & alloc_var) -{ - add_box_constraints (solver, ci, prev, main_dimension, second_dimension, alloc_var, - height, width, - top, bottom, top_padding, bottom_padding, - left, right, left_padding, right_padding, - _top_margin, _bottom_margin, _left_margin, _right_margin); - -} - -void -ConstraintPacker::add_horizontal_box_constraints (kiwi::Solver& solver, BoxConstrainedItem* ci, BoxConstrainedItem* prev, double main_dimension, double second_dimension, kiwi::Variable& alloc_var) -{ - add_box_constraints (solver, ci, prev, main_dimension, second_dimension, alloc_var, - width, height, - left, right, left_padding, right_padding, - top, bottom, top_padding, bottom_padding, - _left_margin, _right_margin, _top_margin, _bottom_margin); -} - -void -ConstraintPacker::set_spacing (double s) -{ - _spacing = s; -} - -void -ConstraintPacker::set_padding (double top, double right, double bottom, double left) -{ - double last = top; - - _top_padding = last; - - if (right >= 0) { - last = right; - } - _right_padding = last; - - if (bottom >= 0) { - last = bottom; - } - _bottom_padding = last; - - if (left >= 0) { - last = left; - } - _left_padding = last; -} - -void -ConstraintPacker::set_margin (double top, double right, double bottom, double left) -{ - double last = top; - - _top_margin = last; - - if (right >= 0) { - last = right; - } - _right_margin = last; - - if (bottom >= 0) { - last = bottom; - } - _bottom_margin = last; - - if (left >= 0) { - last = left; - } - _left_margin = last; -} - -void -ConstraintPacker::render (Rect const & area, Cairo::RefPtr context) const -{ - if ((fill() || outline()) && _allocation) { - - Rect contents = _allocation; - - /* allocation will have been left with (x0,y0) as given by the - * parent, but _position is set to the same value and will - * be taken into account by item_to_window() - */ - - double width = contents.width() - (_left_margin + _top_margin); - double height = contents.height() - (_top_margin + _bottom_margin); - - contents.x0 = _left_margin; - contents.y0 = _top_margin; - - contents.x1 = contents.x0 + width; - contents.y1 = contents.y0 + height; - - Rect self (item_to_window (contents, false)); - const Rect draw = self.intersection (area); - - if (fill()) { - - setup_fill_context (context); - context->rectangle (draw.x0, draw.y0, draw.width(), draw.height()); - if (outline()) { - context->fill_preserve (); - } else { - context->fill (); - } - } - - if (outline()) { - if (!fill()) { - context->rectangle (draw.x0, draw.y0, draw.width(), draw.height()); - } - setup_outline_context (context); - context->stroke (); - } - } - - Item::render_children (area, context); -} diff --git a/libs/canvas/item.cc b/libs/canvas/item.cc index 1f330dae3f..572fe78e90 100644 --- a/libs/canvas/item.cc +++ b/libs/canvas/item.cc @@ -24,7 +24,6 @@ #include "pbd/convert.h" #include "canvas/canvas.h" -#include "canvas/constraint_packer.h" #include "canvas/debug.h" #include "canvas/item.h" #include "canvas/scroll_group.h" diff --git a/libs/canvas/kiwi/AssocVector.h b/libs/canvas/kiwi/AssocVector.h deleted file mode 100644 index 2a50924166..0000000000 --- a/libs/canvas/kiwi/AssocVector.h +++ /dev/null @@ -1,356 +0,0 @@ -//////////////////////////////////////////////////////////////////////////////// -// The Loki Library -// Copyright (c) 2001 by Andrei Alexandrescu -// This code accompanies the book: -// Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design -// Patterns Applied". Copyright (c) 2001. Addison-Wesley. -// Permission to use, copy, modify, distribute and sell this software for any -// purpose is hereby granted without fee, provided that the above copyright -// notice appear in all copies and that both that copyright notice and this -// permission notice appear in supporting documentation. -// The author or Addison-Wesley Longman make no representations about the -// suitability of this software for any purpose. It is provided "as is" -// without express or implied warranty. -//////////////////////////////////////////////////////////////////////////////// -// Updated 2019 by Matthieu Dartiailh for C++11 compliancy -//////////////////////////////////////////////////////////////////////////////// -#pragma once - -// $Id: AssocVector.h 765 2006-10-18 13:55:32Z syntheticpp $ - - -#include -#include -#include -#include - -namespace Loki -{ -//////////////////////////////////////////////////////////////////////////////// -// class template AssocVectorCompare -// Used by AssocVector -//////////////////////////////////////////////////////////////////////////////// - - namespace Private - { - template - class AssocVectorCompare : public C - { - typedef std::pair - Data; - typedef typename C::first_argument_type first_argument_type; - - public: - AssocVectorCompare() - {} - - AssocVectorCompare(const C& src) : C(src) - {} - - bool operator()(const first_argument_type& lhs, - const first_argument_type& rhs) const - { return C::operator()(lhs, rhs); } - - bool operator()(const Data& lhs, const Data& rhs) const - { return operator()(lhs.first, rhs.first); } - - bool operator()(const Data& lhs, - const first_argument_type& rhs) const - { return operator()(lhs.first, rhs); } - - bool operator()(const first_argument_type& lhs, - const Data& rhs) const - { return operator()(lhs, rhs.first); } - }; - } - -//////////////////////////////////////////////////////////////////////////////// -// class template AssocVector -// An associative vector built as a syntactic drop-in replacement for std::map -// BEWARE: AssocVector doesn't respect all map's guarantees, the most important -// being: -// * iterators are invalidated by insert and erase operations -// * the complexity of insert/erase is O(N) not O(log N) -// * value_type is std::pair not std::pair -// * iterators are random -//////////////////////////////////////////////////////////////////////////////// - - - template - < - class K, - class V, - class C = std::less, - class A = std::allocator< std::pair > - > - class AssocVector - : private std::vector< std::pair, A > - , private Private::AssocVectorCompare - { - typedef std::vector, A> Base; - typedef Private::AssocVectorCompare MyCompare; - - public: - typedef K key_type; - typedef V mapped_type; - typedef typename Base::value_type value_type; - - typedef C key_compare; - typedef A allocator_type; - typedef typename A::reference reference; - typedef typename A::const_reference const_reference; - typedef typename Base::iterator iterator; - typedef typename Base::const_iterator const_iterator; - typedef typename Base::size_type size_type; - typedef typename Base::difference_type difference_type; - typedef typename A::pointer pointer; - typedef typename A::const_pointer const_pointer; - typedef typename Base::reverse_iterator reverse_iterator; - typedef typename Base::const_reverse_iterator const_reverse_iterator; - - class value_compare - : public std::function - , private key_compare - { - friend class AssocVector; - - protected: - value_compare(key_compare pred) : key_compare(pred) - {} - - public: - bool operator()(const value_type& lhs, const value_type& rhs) const - { return key_compare::operator()(lhs.first, rhs.first); } - }; - - // 23.3.1.1 construct/copy/destroy - - explicit AssocVector(const key_compare& comp = key_compare(), - const A& alloc = A()) - : Base(alloc), MyCompare(comp) - {} - - template - AssocVector(InputIterator first, InputIterator last, - const key_compare& comp = key_compare(), - const A& alloc = A()) - : Base(first, last, alloc), MyCompare(comp) - { - MyCompare& me = *this; - std::sort(begin(), end(), me); - } - - AssocVector& operator=(const AssocVector& rhs) - { - AssocVector(rhs).swap(*this); - return *this; - } - - // iterators: - // The following are here because MWCW gets 'using' wrong - iterator begin() { return Base::begin(); } - const_iterator begin() const { return Base::begin(); } - iterator end() { return Base::end(); } - const_iterator end() const { return Base::end(); } - reverse_iterator rbegin() { return Base::rbegin(); } - const_reverse_iterator rbegin() const { return Base::rbegin(); } - reverse_iterator rend() { return Base::rend(); } - const_reverse_iterator rend() const { return Base::rend(); } - - // capacity: - bool empty() const { return Base::empty(); } - size_type size() const { return Base::size(); } - size_type max_size() { return Base::max_size(); } - - // 23.3.1.2 element access: - mapped_type& operator[](const key_type& key) - { return insert(value_type(key, mapped_type())).first->second; } - - // modifiers: - std::pair insert(const value_type& val) - { - bool found(true); - iterator i(lower_bound(val.first)); - - if (i == end() || this->operator()(val.first, i->first)) - { - i = Base::insert(i, val); - found = false; - } - return std::make_pair(i, !found); - } - //Section [23.1.2], Table 69 - //http://developer.apple.com/documentation/DeveloperTools/gcc-3.3/libstdc++/23_containers/howto.html#4 - iterator insert(iterator pos, const value_type& val) - { - if( (pos == begin() || this->operator()(*(pos-1),val)) && - (pos == end() || this->operator()(val, *pos)) ) - { - return Base::insert(pos, val); - } - return insert(val).first; - } - - template - void insert(InputIterator first, InputIterator last) - { for (; first != last; ++first) insert(*first); } - - void erase(iterator pos) - { Base::erase(pos); } - - size_type erase(const key_type& k) - { - iterator i(find(k)); - if (i == end()) return 0; - erase(i); - return 1; - } - - void erase(iterator first, iterator last) - { Base::erase(first, last); } - - void swap(AssocVector& other) - { - Base::swap(other); - MyCompare& me = *this; - MyCompare& rhs = other; - std::swap(me, rhs); - } - - void clear() - { Base::clear(); } - - // observers: - key_compare key_comp() const - { return *this; } - - value_compare value_comp() const - { - const key_compare& comp = *this; - return value_compare(comp); - } - - // 23.3.1.3 map operations: - iterator find(const key_type& k) - { - iterator i(lower_bound(k)); - if (i != end() && this->operator()(k, i->first)) - { - i = end(); - } - return i; - } - - const_iterator find(const key_type& k) const - { - const_iterator i(lower_bound(k)); - if (i != end() && this->operator()(k, i->first)) - { - i = end(); - } - return i; - } - - size_type count(const key_type& k) const - { return find(k) != end(); } - - iterator lower_bound(const key_type& k) - { - MyCompare& me = *this; - return std::lower_bound(begin(), end(), k, me); - } - - const_iterator lower_bound(const key_type& k) const - { - const MyCompare& me = *this; - return std::lower_bound(begin(), end(), k, me); - } - - iterator upper_bound(const key_type& k) - { - MyCompare& me = *this; - return std::upper_bound(begin(), end(), k, me); - } - - const_iterator upper_bound(const key_type& k) const - { - const MyCompare& me = *this; - return std::upper_bound(begin(), end(), k, me); - } - - std::pair equal_range(const key_type& k) - { - MyCompare& me = *this; - return std::equal_range(begin(), end(), k, me); - } - - std::pair equal_range( - const key_type& k) const - { - const MyCompare& me = *this; - return std::equal_range(begin(), end(), k, me); - } - - template - friend bool operator==(const AssocVector& lhs, - const AssocVector& rhs); - - bool operator<(const AssocVector& rhs) const - { - const Base& me = *this; - const Base& yo = rhs; - return me < yo; - } - - template - friend bool operator!=(const AssocVector& lhs, - const AssocVector& rhs); - - template - friend bool operator>(const AssocVector& lhs, - const AssocVector& rhs); - - template - friend bool operator>=(const AssocVector& lhs, - const AssocVector& rhs); - - template - friend bool operator<=(const AssocVector& lhs, - const AssocVector& rhs); - }; - - template - inline bool operator==(const AssocVector& lhs, - const AssocVector& rhs) - { - const std::vector, A>& me = lhs; - return me == rhs; - } - - template - inline bool operator!=(const AssocVector& lhs, - const AssocVector& rhs) - { return !(lhs == rhs); } - - template - inline bool operator>(const AssocVector& lhs, - const AssocVector& rhs) - { return rhs < lhs; } - - template - inline bool operator>=(const AssocVector& lhs, - const AssocVector& rhs) - { return !(lhs < rhs); } - - template - inline bool operator<=(const AssocVector& lhs, - const AssocVector& rhs) - { return !(rhs < lhs); } - - - // specialized algorithms: - template - void swap(AssocVector& lhs, AssocVector& rhs) - { lhs.swap(rhs); } - -} // namespace Loki diff --git a/libs/canvas/kiwi/constraint.h b/libs/canvas/kiwi/constraint.h deleted file mode 100644 index 9b4617b120..0000000000 --- a/libs/canvas/kiwi/constraint.h +++ /dev/null @@ -1,148 +0,0 @@ -/*----------------------------------------------------------------------------- - | Copyright (c) 2013-2017, Nucleic Development Team. - | - | Distributed under the terms of the Modified BSD License. - | - | The full license is in the file LICENSE, distributed with this software. - |----------------------------------------------------------------------------*/ -#pragma once -#include -#include -#include -#include "expression.h" -#include "shareddata.h" -#include "strength.h" -#include "term.h" -#include "variable.h" - -namespace kiwi -{ - -enum RelationalOperator -{ - OP_LE, - OP_GE, - OP_EQ -}; - -static std::ostream& operator<< (std::ostream& o, RelationalOperator op) -{ - switch (op) { - case OP_LE: - o << "<="; - break; - case OP_GE: - o << ">="; - break; - case OP_EQ: - o << "=="; - break; - } - return o; -} - -class Constraint -{ - - public: - Constraint() : m_data(0) {} - - Constraint(const Expression &expr, - RelationalOperator op, - double strength = strength::required) : m_data(new ConstraintData(expr, op, strength)) {} - - Constraint(const Constraint &other, double strength) : m_data(new ConstraintData(other, strength)) {} - - ~Constraint() {} - - const Expression &expression() const - { - return m_data->m_expression; - } - - RelationalOperator op() const - { - return m_data->m_op; - } - - double strength() const - { - return m_data->m_strength; - } - - bool operator!() const - { - return !m_data; - } - - bool involves (Variable const & v) const { - if (expression().involves (v)) { - return true; - } - return false; - } - - private: - static Expression reduce(const Expression &expr) - { - std::map vars; - typedef std::vector::const_iterator iter_t; - iter_t end = expr.terms().end(); - for (iter_t it = expr.terms().begin(); it != end; ++it) - vars[it->variable()] += it->coefficient(); - std::vector terms(vars.begin(), vars.end()); - return Expression(terms, expr.constant()); - } - - class ConstraintData : public SharedData - { - - public: - ConstraintData(const Expression &expr, - RelationalOperator op, - double strength) : SharedData(), - m_expression(reduce(expr)), - m_strength(strength::clip(strength)), - m_op(op) {} - - ConstraintData(const Constraint &other, double strength) : SharedData(), - m_expression(other.expression()), - m_strength(strength::clip(strength)), - m_op(other.op()) {} - - ~ConstraintData() {} - - Expression m_expression; - double m_strength; - RelationalOperator m_op; - - private: - ConstraintData(const ConstraintData &other); - - ConstraintData &operator=(const ConstraintData &other); - }; - - SharedDataPtr m_data; - - friend bool operator<(const Constraint &lhs, const Constraint &rhs) - { - return lhs.m_data < rhs.m_data; - } - - friend bool operator==(const Constraint &lhs, const Constraint &rhs) - { - return lhs.m_data == rhs.m_data; - } - - friend bool operator!=(const Constraint &lhs, const Constraint &rhs) - { - return lhs.m_data != rhs.m_data; - } -}; - -static std::ostream& operator<< (std::ostream& o, kiwi::Constraint const & c) -{ - return o << c.expression() << " OP " << c.op(); -} - -} // namespace kiwi diff --git a/libs/canvas/kiwi/debug.h b/libs/canvas/kiwi/debug.h deleted file mode 100644 index 0d86091b25..0000000000 --- a/libs/canvas/kiwi/debug.h +++ /dev/null @@ -1,200 +0,0 @@ -/*----------------------------------------------------------------------------- -| Copyright (c) 2013-2017, Nucleic Development Team. -| -| Distributed under the terms of the Modified BSD License. -| -| The full license is in the file LICENSE, distributed with this software. -|----------------------------------------------------------------------------*/ -#pragma once -#include -#include -#include -#include "constraint.h" -#include "solverimpl.h" -#include "term.h" - -namespace kiwi -{ - -namespace impl -{ - -class DebugHelper -{ - -public: - static void dump(const SolverImpl &solver, std::ostream &out) - { - out << "Objective" << std::endl; - out << "---------" << std::endl; - dump(*solver.m_objective, out); - out << std::endl; - out << "Tableau" << std::endl; - out << "-------" << std::endl; - dump(solver.m_rows, out); - out << std::endl; - out << "Infeasible" << std::endl; - out << "----------" << std::endl; - dump(solver.m_infeasible_rows, out); - out << std::endl; - out << "Variables" << std::endl; - out << "---------" << std::endl; - dump(solver.m_vars, out); - out << std::endl; - out << "Edit Variables" << std::endl; - out << "--------------" << std::endl; - dump(solver.m_edits, out); - out << std::endl; - out << "Constraints" << std::endl; - out << "-----------" << std::endl; - dump(solver.m_cns, out); - out << std::endl; - out << std::endl; - } - - static void dump(const SolverImpl::RowMap &rows, std::ostream &out) - { - typedef SolverImpl::RowMap::const_iterator iter_t; - iter_t end = rows.end(); - for (iter_t it = rows.begin(); it != end; ++it) - { - dump(it->first, out); - out << " | "; - dump(*it->second, out); - } - } - - static void dump(const std::vector &symbols, std::ostream &out) - { - typedef std::vector::const_iterator iter_t; - iter_t end = symbols.end(); - for (iter_t it = symbols.begin(); it != end; ++it) - { - dump(*it, out); - out << std::endl; - } - } - - static void dump(const SolverImpl::VarMap &vars, std::ostream &out) - { - typedef SolverImpl::VarMap::const_iterator iter_t; - iter_t end = vars.end(); - for (iter_t it = vars.begin(); it != end; ++it) - { - out << it->first.name() << " = "; - dump(it->second, out); - out << std::endl; - } - } - - static void dump(const SolverImpl::CnMap &cns, std::ostream &out) - { - typedef SolverImpl::CnMap::const_iterator iter_t; - iter_t end = cns.end(); - for (iter_t it = cns.begin(); it != end; ++it) - dump(it->first, out); - } - - static void dump(const SolverImpl::EditMap &edits, std::ostream &out) - { - typedef SolverImpl::EditMap::const_iterator iter_t; - iter_t end = edits.end(); - for (iter_t it = edits.begin(); it != end; ++it) - out << it->first.name() << std::endl; - } - - static void dump(const Row &row, std::ostream &out) - { - typedef Row::CellMap::const_iterator iter_t; - out << row.constant(); - iter_t end = row.cells().end(); - for (iter_t it = row.cells().begin(); it != end; ++it) - { - out << " + " << it->second << " * "; - dump(it->first, out); - } - out << std::endl; - } - - static void dump(const Symbol &symbol, std::ostream &out) - { - switch (symbol.type()) - { - case Symbol::Invalid: - out << "i"; - break; - case Symbol::External: - out << "v"; - break; - case Symbol::Slack: - out << "s"; - break; - case Symbol::Error: - out << "e"; - break; - case Symbol::Dummy: - out << "d"; - break; - default: - break; - } - out << symbol.id(); - } - - static void dump(const Constraint &cn, std::ostream &out) - { - typedef std::vector::const_iterator iter_t; - iter_t begin = cn.expression().terms().begin(); - iter_t end = cn.expression().terms().end(); - for (iter_t it = begin; it != end; ++it) - { - out << it->coefficient() << " * "; - out << it->variable().name() << " + "; - } - out << cn.expression().constant(); - switch (cn.op()) - { - case OP_LE: - out << " <= 0 "; - break; - case OP_GE: - out << " >= 0 "; - break; - case OP_EQ: - out << " == 0 "; - break; - default: - break; - } - out << " | strength = " << cn.strength() << std::endl; - } -}; - -} // namespace impl - -namespace debug -{ - -template -void dump(const T &value) -{ - impl::DebugHelper::dump(value, std::cout); -} - -template -void dump(const T &value, std::ostream &out) -{ - impl::DebugHelper::dump(value, out); -} - -template -std::string dumps(const T &value) -{ - std::stringstream stream; - impl::DebugHelper::dump(value, stream); - return stream.str(); -} - -} // namespace debug - -} // namespace kiwi diff --git a/libs/canvas/kiwi/errors.h b/libs/canvas/kiwi/errors.h deleted file mode 100644 index eb54560f4e..0000000000 --- a/libs/canvas/kiwi/errors.h +++ /dev/null @@ -1,162 +0,0 @@ -/*----------------------------------------------------------------------------- -| Copyright (c) 2013-2017, Nucleic Development Team. -| -| Distributed under the terms of the Modified BSD License. -| -| The full license is in the file LICENSE, distributed with this software. -|----------------------------------------------------------------------------*/ -#pragma once -#include -#include -#include "constraint.h" -#include "variable.h" - -namespace kiwi -{ - -class UnsatisfiableConstraint : public std::exception -{ - -public: - UnsatisfiableConstraint(const Constraint &constraint) : m_constraint(constraint) {} - - ~UnsatisfiableConstraint() throw() {} - - const char *what() const throw() - { - return "The constraint can not be satisfied."; - } - - const Constraint &constraint() const - { - return m_constraint; - } - -private: - Constraint m_constraint; -}; - -class UnknownConstraint : public std::exception -{ - -public: - UnknownConstraint(const Constraint &constraint) : m_constraint(constraint) {} - - ~UnknownConstraint() throw() {} - - const char *what() const throw() - { - return "The constraint has not been added to the solver."; - } - - const Constraint &constraint() const - { - return m_constraint; - } - -private: - Constraint m_constraint; -}; - -class DuplicateConstraint : public std::exception -{ - -public: - DuplicateConstraint(const Constraint &constraint) : m_constraint(constraint) {} - - ~DuplicateConstraint() throw() {} - - const char *what() const throw() - { - return "The constraint has already been added to the solver."; - } - - const Constraint &constraint() const - { - return m_constraint; - } - -private: - Constraint m_constraint; -}; - -class UnknownEditVariable : public std::exception -{ - -public: - UnknownEditVariable(const Variable &variable) : m_variable(variable) {} - - ~UnknownEditVariable() throw() {} - - const char *what() const throw() - { - return "The edit variable has not been added to the solver."; - } - - const Variable &variable() const - { - return m_variable; - } - -private: - Variable m_variable; -}; - -class DuplicateEditVariable : public std::exception -{ - -public: - DuplicateEditVariable(const Variable &variable) : m_variable(variable) {} - - ~DuplicateEditVariable() throw() {} - - const char *what() const throw() - { - return "The edit variable has already been added to the solver."; - } - - const Variable &variable() const - { - return m_variable; - } - -private: - Variable m_variable; -}; - -class BadRequiredStrength : public std::exception -{ - -public: - BadRequiredStrength() {} - - ~BadRequiredStrength() throw() {} - - const char *what() const throw() - { - return "A required strength cannot be used in this context."; - } -}; - -class InternalSolverError : public std::exception -{ - -public: - InternalSolverError() : m_msg("An internal solver error ocurred.") {} - - InternalSolverError(const char *msg) : m_msg(msg) {} - - InternalSolverError(const std::string &msg) : m_msg(msg) {} - - ~InternalSolverError() throw() {} - - const char *what() const throw() - { - return m_msg.c_str(); - } - -private: - std::string m_msg; -}; - -} // namespace kiwi diff --git a/libs/canvas/kiwi/expression.h b/libs/canvas/kiwi/expression.h deleted file mode 100644 index eac318c09b..0000000000 --- a/libs/canvas/kiwi/expression.h +++ /dev/null @@ -1,72 +0,0 @@ -/*----------------------------------------------------------------------------- - | Copyright (c) 2013-2017, Nucleic Development Team. - | - | Distributed under the terms of the Modified BSD License. - | - | The full license is in the file LICENSE, distributed with this software. - |----------------------------------------------------------------------------*/ -#pragma once -#include -#include -#include "term.h" - -namespace kiwi -{ - -class Expression -{ - - public: - Expression(double constant = 0.0) : m_constant(constant) {} - - Expression(const Term &term, double constant = 0.0) : m_terms(1, term), m_constant(constant) {} - - Expression(const std::vector &terms, double constant = 0.0) : m_terms(terms), m_constant(constant) {} - - ~Expression() {} - - const std::vector &terms() const - { - return m_terms; - } - - double constant() const - { - return m_constant; - } - - double value() const - { - typedef std::vector::const_iterator iter_t; - double result = m_constant; - iter_t end = m_terms.end(); - for (iter_t it = m_terms.begin(); it != end; ++it) - result += it->value(); - return result; - } - - bool involves (Variable const & v) const { - for (std::vector::const_iterator it = m_terms.begin(); it != m_terms.end(); ++it) { - if (it->variable().equals (v)) { - return true; - } - } - return false; - } - - private: - std::vector m_terms; - double m_constant; -}; - -static std::ostream& operator<<(std::ostream& o, kiwi::Expression const &e) -{ - o << e.constant() << " + "; - for (std::vector::const_iterator it = e.terms().begin(); it != e.terms().end(); ++it) { - o << (*it) << ' '; - } - return o; -} - -} // namespace kiwi - diff --git a/libs/canvas/kiwi/kiwi.h b/libs/canvas/kiwi/kiwi.h deleted file mode 100644 index 77bb6a8ec2..0000000000 --- a/libs/canvas/kiwi/kiwi.h +++ /dev/null @@ -1,19 +0,0 @@ -/*----------------------------------------------------------------------------- -| Copyright (c) 2013-2017, Nucleic Development Team. -| -| Distributed under the terms of the Modified BSD License. -| -| The full license is in the file LICENSE, distributed with this software. -|----------------------------------------------------------------------------*/ -#pragma once -#include "constraint.h" -#include "debug.h" -#include "errors.h" -#include "expression.h" -#include "shareddata.h" -#include "solver.h" -#include "strength.h" -#include "symbolics.h" -#include "term.h" -#include "variable.h" -#include "version.h" diff --git a/libs/canvas/kiwi/maptype.h b/libs/canvas/kiwi/maptype.h deleted file mode 100644 index 9b19a21734..0000000000 --- a/libs/canvas/kiwi/maptype.h +++ /dev/null @@ -1,37 +0,0 @@ -/*----------------------------------------------------------------------------- -| Copyright (c) 2013-2019, Nucleic Development Team. -| -| Distributed under the terms of the Modified BSD License. -| -| The full license is in the file LICENSE, distributed with this software. -|----------------------------------------------------------------------------*/ -#pragma once -#include -#include -#include -#include -#include "AssocVector.h" - -namespace kiwi -{ - -namespace impl -{ - -template < - typename K, - typename V, - typename C = std::less, - typename A = std::allocator>> -using MapType = Loki::AssocVector; - -// template< -// typename K, -// typename V, -// typename C = std::less, -// typename A = std::allocator< std::pair > > -// using MapType = std::map; - -} // namespace impl - -} // namespace kiwi diff --git a/libs/canvas/kiwi/row.h b/libs/canvas/kiwi/row.h deleted file mode 100644 index 29b25135bb..0000000000 --- a/libs/canvas/kiwi/row.h +++ /dev/null @@ -1,188 +0,0 @@ -/*----------------------------------------------------------------------------- -| Copyright (c) 2013-2017, Nucleic Development Team. -| -| Distributed under the terms of the Modified BSD License. -| -| The full license is in the file LICENSE, distributed with this software. -|----------------------------------------------------------------------------*/ -#pragma once -#include "maptype.h" -#include "symbol.h" -#include "util.h" - -namespace kiwi -{ - -namespace impl -{ - -class Row -{ - -public: - typedef MapType CellMap; - - Row() : m_constant(0.0) {} - - Row(double constant) : m_constant(constant) {} - - Row(const Row &other) : m_cells(other.m_cells), m_constant(other.m_constant) {} - - ~Row() {} - - const CellMap &cells() const - { - return m_cells; - } - - double constant() const - { - return m_constant; - } - - /* Add a constant value to the row constant. - - The new value of the constant is returned. - - */ - double add(double value) - { - return m_constant += value; - } - - /* Insert a symbol into the row with a given coefficient. - - If the symbol already exists in the row, the coefficient will be - added to the existing coefficient. If the resulting coefficient - is zero, the symbol will be removed from the row. - - */ - void insert(const Symbol &symbol, double coefficient = 1.0) - { - if (nearZero(m_cells[symbol] += coefficient)) - m_cells.erase(symbol); - } - - /* Insert a row into this row with a given coefficient. - - The constant and the cells of the other row will be multiplied by - the coefficient and added to this row. Any cell with a resulting - coefficient of zero will be removed from the row. - - */ - void insert(const Row &other, double coefficient = 1.0) - { - typedef CellMap::const_iterator iter_t; - m_constant += other.m_constant * coefficient; - iter_t end = other.m_cells.end(); - for (iter_t it = other.m_cells.begin(); it != end; ++it) - { - double coeff = it->second * coefficient; - if (nearZero(m_cells[it->first] += coeff)) - m_cells.erase(it->first); - } - } - - /* Remove the given symbol from the row. - - */ - void remove(const Symbol &symbol) - { - CellMap::iterator it = m_cells.find(symbol); - if (it != m_cells.end()) - m_cells.erase(it); - } - - /* Reverse the sign of the constant and all cells in the row. - - */ - void reverseSign() - { - typedef CellMap::iterator iter_t; - m_constant = -m_constant; - iter_t end = m_cells.end(); - for (iter_t it = m_cells.begin(); it != end; ++it) - it->second = -it->second; - } - - /* Solve the row for the given symbol. - - This method assumes the row is of the form a * x + b * y + c = 0 - and (assuming solve for x) will modify the row to represent the - right hand side of x = -b/a * y - c / a. The target symbol will - be removed from the row, and the constant and other cells will - be multiplied by the negative inverse of the target coefficient. - - The given symbol *must* exist in the row. - - */ - void solveFor(const Symbol &symbol) - { - typedef CellMap::iterator iter_t; - double coeff = -1.0 / m_cells[symbol]; - m_cells.erase(symbol); - m_constant *= coeff; - iter_t end = m_cells.end(); - for (iter_t it = m_cells.begin(); it != end; ++it) - it->second *= coeff; - } - - /* Solve the row for the given symbols. - - This method assumes the row is of the form x = b * y + c and will - solve the row such that y = x / b - c / b. The rhs symbol will be - removed from the row, the lhs added, and the result divided by the - negative inverse of the rhs coefficient. - - The lhs symbol *must not* exist in the row, and the rhs symbol - *must* exist in the row. - - */ - void solveFor(const Symbol &lhs, const Symbol &rhs) - { - insert(lhs, -1.0); - solveFor(rhs); - } - - /* Get the coefficient for the given symbol. - - If the symbol does not exist in the row, zero will be returned. - - */ - double coefficientFor(const Symbol &symbol) const - { - CellMap::const_iterator it = m_cells.find(symbol); - if (it == m_cells.end()) - return 0.0; - return it->second; - } - - /* Substitute a symbol with the data from another row. - - Given a row of the form a * x + b and a substitution of the - form x = 3 * y + c the row will be updated to reflect the - expression 3 * a * y + a * c + b. - - If the symbol does not exist in the row, this is a no-op. - - */ - void substitute(const Symbol &symbol, const Row &row) - { - typedef CellMap::iterator iter_t; - iter_t it = m_cells.find(symbol); - if (it != m_cells.end()) - { - double coefficient = it->second; - m_cells.erase(it); - insert(row, coefficient); - } - } - -private: - CellMap m_cells; - double m_constant; -}; - -} // namespace impl - -} // namespace kiwi diff --git a/libs/canvas/kiwi/shareddata.h b/libs/canvas/kiwi/shareddata.h deleted file mode 100644 index 9b1bc2c012..0000000000 --- a/libs/canvas/kiwi/shareddata.h +++ /dev/null @@ -1,151 +0,0 @@ -/*----------------------------------------------------------------------------- -| Copyright (c) 2013-2017, Nucleic Development Team. -| -| Distributed under the terms of the Modified BSD License. -| -| The full license is in the file LICENSE, distributed with this software. -|----------------------------------------------------------------------------*/ -#pragma once - -namespace kiwi -{ - -class SharedData -{ - -public: - SharedData() : m_refcount(0) {} - - SharedData(const SharedData &other) : m_refcount(0) {} - - int m_refcount; - -private: - SharedData &operator=(const SharedData &other); -}; - -template -class SharedDataPtr -{ - -public: - typedef T Type; - - SharedDataPtr() : m_data(0) {} - - explicit SharedDataPtr(T *data) : m_data(data) - { - incref(m_data); - } - - ~SharedDataPtr() - { - decref(m_data); - } - - T *data() - { - return m_data; - } - - const T *data() const - { - return m_data; - } - - operator T *() - { - return m_data; - } - - operator const T *() const - { - return m_data; - } - - T *operator->() - { - return m_data; - } - - const T *operator->() const - { - return m_data; - } - - T &operator*() - { - return *m_data; - } - - const T &operator*() const - { - return *m_data; - } - - bool operator!() const - { - return !m_data; - } - - bool operator<(const SharedDataPtr &other) const - { - return m_data < other.m_data; - } - - bool operator==(const SharedDataPtr &other) const - { - return m_data == other.m_data; - } - - bool operator!=(const SharedDataPtr &other) const - { - return m_data != other.m_data; - } - - SharedDataPtr(const SharedDataPtr &other) : m_data(other.m_data) - { - incref(m_data); - } - - SharedDataPtr &operator=(const SharedDataPtr &other) - { - if (m_data != other.m_data) - { - T *temp = m_data; - m_data = other.m_data; - incref(m_data); - decref(temp); - } - return *this; - } - - SharedDataPtr &operator=(T *other) - { - if (m_data != other) - { - T *temp = m_data; - m_data = other; - incref(m_data); - decref(temp); - } - return *this; - } - -private: - static void incref(T *data) - { - if (data) - ++data->m_refcount; - } - - static void decref(T *data) - { - if (data && --data->m_refcount == 0) - delete data; - } - - T *m_data; -}; - -} // namespace kiwi diff --git a/libs/canvas/kiwi/solver.h b/libs/canvas/kiwi/solver.h deleted file mode 100644 index 678df8ac75..0000000000 --- a/libs/canvas/kiwi/solver.h +++ /dev/null @@ -1,178 +0,0 @@ -/*----------------------------------------------------------------------------- -| Copyright (c) 2013-2017, Nucleic Development Team. -| -| Distributed under the terms of the Modified BSD License. -| -| The full license is in the file LICENSE, distributed with this software. -|----------------------------------------------------------------------------*/ -#pragma once -#include "constraint.h" -#include "debug.h" -#include "solverimpl.h" -#include "strength.h" -#include "variable.h" - - -namespace kiwi -{ - -class Solver -{ - -public: - - Solver() {} - - ~Solver() {} - - /* Add a constraint to the solver. - - Throws - ------ - DuplicateConstraint - The given constraint has already been added to the solver. - - UnsatisfiableConstraint - The given constraint is required and cannot be satisfied. - - */ - void addConstraint( const Constraint& constraint ) - { - m_impl.addConstraint( constraint ); - } - - /* Remove a constraint from the solver. - - Throws - ------ - UnknownConstraint - The given constraint has not been added to the solver. - - */ - void removeConstraint( const Constraint& constraint ) - { - m_impl.removeConstraint( constraint ); - } - - /* Test whether a constraint has been added to the solver. - - */ - bool hasConstraint( const Constraint& constraint ) const - { - return m_impl.hasConstraint( constraint ); - } - - /* Add an edit variable to the solver. - - This method should be called before the `suggestValue` method is - used to supply a suggested value for the given edit variable. - - Throws - ------ - DuplicateEditVariable - The given edit variable has already been added to the solver. - - BadRequiredStrength - The given strength is >= required. - - */ - void addEditVariable( const Variable& variable, double strength ) - { - m_impl.addEditVariable( variable, strength ); - } - - /* Remove an edit variable from the solver. - - Throws - ------ - UnknownEditVariable - The given edit variable has not been added to the solver. - - */ - void removeEditVariable( const Variable& variable ) - { - m_impl.removeEditVariable( variable ); - } - - /* Test whether an edit variable has been added to the solver. - - */ - bool hasEditVariable( const Variable& variable ) const - { - return m_impl.hasEditVariable( variable ); - } - - /* Suggest a value for the given edit variable. - - This method should be used after an edit variable as been added to - the solver in order to suggest the value for that variable. After - all suggestions have been made, the `solve` method can be used to - update the values of all variables. - - Throws - ------ - UnknownEditVariable - The given edit variable has not been added to the solver. - - */ - void suggestValue( const Variable& variable, double value ) - { - m_impl.suggestValue( variable, value ); - } - - /* Update the values of the external solver variables. - - */ - void updateVariables() - { - m_impl.updateVariables(); - } - - /* Reset the solver to the empty starting condition. - - This method resets the internal solver state to the empty starting - condition, as if no constraints or edit variables have been added. - This can be faster than deleting the solver and creating a new one - when the entire system must change, since it can avoid unecessary - heap (de)allocations. - - */ - void reset() - { - m_impl.reset(); - } - - /* Dump a representation of the solver internals to stdout. - - */ - void dump() - { - debug::dump( m_impl ); - } - - /* Dump a representation of the solver internals to a stream. - - */ - void dump( std::ostream& out ) - { - debug::dump( m_impl, out ); - } - - /* Dump a representation of the solver internals to a string. - - */ - std::string dumps() - { - return debug::dumps( m_impl ); - } - -private: - - Solver( const Solver& ); - - Solver& operator=( const Solver& ); - - impl::SolverImpl m_impl; -}; - -} // namespace kiwi diff --git a/libs/canvas/kiwi/solverimpl.h b/libs/canvas/kiwi/solverimpl.h deleted file mode 100644 index bb6690aeb8..0000000000 --- a/libs/canvas/kiwi/solverimpl.h +++ /dev/null @@ -1,840 +0,0 @@ -/*----------------------------------------------------------------------------- -| Copyright (c) 2013-2017, Nucleic Development Team. -| -| Distributed under the terms of the Modified BSD License. -| -| The full license is in the file LICENSE, distributed with this software. -|----------------------------------------------------------------------------*/ -#pragma once -#include -#include -#include -#include -#include "constraint.h" -#include "errors.h" -#include "expression.h" -#include "maptype.h" -#include "row.h" -#include "symbol.h" -#include "term.h" -#include "util.h" -#include "variable.h" - - -namespace kiwi -{ - -namespace impl -{ - -class SolverImpl -{ - friend class DebugHelper; - - struct Tag - { - Symbol marker; - Symbol other; - }; - - struct EditInfo - { - Tag tag; - Constraint constraint; - double constant; - }; - - typedef MapType VarMap; - - typedef MapType RowMap; - - typedef MapType CnMap; - - typedef MapType EditMap; - - struct DualOptimizeGuard - { - DualOptimizeGuard( SolverImpl& impl ) : m_impl( impl ) {} - ~DualOptimizeGuard() { m_impl.dualOptimize(); } - SolverImpl& m_impl; - }; - -public: - - SolverImpl() : m_objective( new Row() ), m_id_tick( 1 ) {} - - ~SolverImpl() { clearRows(); } - - /* Add a constraint to the solver. - - Throws - ------ - DuplicateConstraint - The given constraint has already been added to the solver. - - UnsatisfiableConstraint - The given constraint is required and cannot be satisfied. - - */ - void addConstraint( const Constraint& constraint ) - { - if( m_cns.find( constraint ) != m_cns.end() ) - throw DuplicateConstraint( constraint ); - - // Creating a row causes symbols to be reserved for the variables - // in the constraint. If this method exits with an exception, - // then its possible those variables will linger in the var map. - // Since its likely that those variables will be used in other - // constraints and since exceptional conditions are uncommon, - // i'm not too worried about aggressive cleanup of the var map. - Tag tag; - std::unique_ptr rowptr( createRow( constraint, tag ) ); - Symbol subject( chooseSubject( *rowptr, tag ) ); - - // If chooseSubject could not find a valid entering symbol, one - // last option is available if the entire row is composed of - // dummy variables. If the constant of the row is zero, then - // this represents redundant constraints and the new dummy - // marker can enter the basis. If the constant is non-zero, - // then it represents an unsatisfiable constraint. - if( subject.type() == Symbol::Invalid && allDummies( *rowptr ) ) - { - if( !nearZero( rowptr->constant() ) ) - throw UnsatisfiableConstraint( constraint ); - else - subject = tag.marker; - } - - // If an entering symbol still isn't found, then the row must - // be added using an artificial variable. If that fails, then - // the row represents an unsatisfiable constraint. - if( subject.type() == Symbol::Invalid ) - { - if( !addWithArtificialVariable( *rowptr ) ) - throw UnsatisfiableConstraint( constraint ); - } - else - { - rowptr->solveFor( subject ); - substitute( subject, *rowptr ); - m_rows[ subject ] = rowptr.release(); - } - - m_cns[ constraint ] = tag; - - // Optimizing after each constraint is added performs less - // aggregate work due to a smaller average system size. It - // also ensures the solver remains in a consistent state. - optimize( *m_objective ); - } - - /* Remove a constraint from the solver. - - Throws - ------ - UnknownConstraint - The given constraint has not been added to the solver. - - */ - void removeConstraint( const Constraint& constraint ) - { - CnMap::iterator cn_it = m_cns.find( constraint ); - if( cn_it == m_cns.end() ) - throw UnknownConstraint( constraint ); - - Tag tag( cn_it->second ); - m_cns.erase( cn_it ); - - // Remove the error effects from the objective function - // *before* pivoting, or substitutions into the objective - // will lead to incorrect solver results. - removeConstraintEffects( constraint, tag ); - - // If the marker is basic, simply drop the row. Otherwise, - // pivot the marker into the basis and then drop the row. - RowMap::iterator row_it = m_rows.find( tag.marker ); - if( row_it != m_rows.end() ) - { - std::unique_ptr rowptr( row_it->second ); - m_rows.erase( row_it ); - } - else - { - row_it = getMarkerLeavingRow( tag.marker ); - if( row_it == m_rows.end() ) - throw InternalSolverError( "failed to find leaving row" ); - Symbol leaving( row_it->first ); - std::unique_ptr rowptr( row_it->second ); - m_rows.erase( row_it ); - rowptr->solveFor( leaving, tag.marker ); - substitute( tag.marker, *rowptr ); - } - - // Optimizing after each constraint is removed ensures that the - // solver remains consistent. It makes the solver api easier to - // use at a small tradeoff for speed. - optimize( *m_objective ); - } - - /* Test whether a constraint has been added to the solver. - - */ - bool hasConstraint( const Constraint& constraint ) const - { - return m_cns.find( constraint ) != m_cns.end(); - } - - /* Add an edit variable to the solver. - - This method should be called before the `suggestValue` method is - used to supply a suggested value for the given edit variable. - - Throws - ------ - DuplicateEditVariable - The given edit variable has already been added to the solver. - - BadRequiredStrength - The given strength is >= required. - - */ - void addEditVariable( const Variable& variable, double strength ) - { - if( m_edits.find( variable ) != m_edits.end() ) - throw DuplicateEditVariable( variable ); - strength = strength::clip( strength ); - if( strength == strength::required ) - throw BadRequiredStrength(); - Constraint cn( Expression( variable ), OP_EQ, strength ); - addConstraint( cn ); - EditInfo info; - info.tag = m_cns[ cn ]; - info.constraint = cn; - info.constant = 0.0; - m_edits[ variable ] = info; - } - - /* Remove an edit variable from the solver. - - Throws - ------ - UnknownEditVariable - The given edit variable has not been added to the solver. - - */ - void removeEditVariable( const Variable& variable ) - { - EditMap::iterator it = m_edits.find( variable ); - if( it == m_edits.end() ) - throw UnknownEditVariable( variable ); - removeConstraint( it->second.constraint ); - m_edits.erase( it ); - } - - /* Test whether an edit variable has been added to the solver. - - */ - bool hasEditVariable( const Variable& variable ) const - { - return m_edits.find( variable ) != m_edits.end(); - } - - /* Suggest a value for the given edit variable. - - This method should be used after an edit variable as been added to - the solver in order to suggest the value for that variable. - - Throws - ------ - UnknownEditVariable - The given edit variable has not been added to the solver. - - */ - void suggestValue( const Variable& variable, double value ) - { - EditMap::iterator it = m_edits.find( variable ); - if( it == m_edits.end() ) - throw UnknownEditVariable( variable ); - - DualOptimizeGuard guard( *this ); - EditInfo& info = it->second; - double delta = value - info.constant; - info.constant = value; - - // Check first if the positive error variable is basic. - RowMap::iterator row_it = m_rows.find( info.tag.marker ); - if( row_it != m_rows.end() ) - { - if( row_it->second->add( -delta ) < 0.0 ) - m_infeasible_rows.push_back( row_it->first ); - return; - } - - // Check next if the negative error variable is basic. - row_it = m_rows.find( info.tag.other ); - if( row_it != m_rows.end() ) - { - if( row_it->second->add( delta ) < 0.0 ) - m_infeasible_rows.push_back( row_it->first ); - return; - } - - // Otherwise update each row where the error variables exist. - RowMap::iterator end = m_rows.end(); - for( row_it = m_rows.begin(); row_it != end; ++row_it ) - { - double coeff = row_it->second->coefficientFor( info.tag.marker ); - if( coeff != 0.0 && - row_it->second->add( delta * coeff ) < 0.0 && - row_it->first.type() != Symbol::External ) - m_infeasible_rows.push_back( row_it->first ); - } - } - - /* Update the values of the external solver variables. - - */ - void updateVariables() - { - typedef RowMap::iterator row_iter_t; - typedef VarMap::iterator var_iter_t; - row_iter_t row_end = m_rows.end(); - var_iter_t var_end = m_vars.end(); - for( var_iter_t var_it = m_vars.begin(); var_it != var_end; ++var_it ) - { - Variable& var( const_cast( var_it->first ) ); - row_iter_t row_it = m_rows.find( var_it->second ); - if( row_it == row_end ) - var.setValue( 0.0 ); - else - var.setValue( row_it->second->constant() ); - } - } - - /* Reset the solver to the empty starting condition. - - This method resets the internal solver state to the empty starting - condition, as if no constraints or edit variables have been added. - This can be faster than deleting the solver and creating a new one - when the entire system must change, since it can avoid unecessary - heap (de)allocations. - - */ - void reset() - { - clearRows(); - m_cns.clear(); - m_vars.clear(); - m_edits.clear(); - m_infeasible_rows.clear(); - m_objective.reset( new Row() ); - m_artificial.reset(); - m_id_tick = 1; - } - -private: - - SolverImpl( const SolverImpl& ); - - SolverImpl& operator=( const SolverImpl& ); - - struct RowDeleter - { - template - void operator()( T& pair ) { delete pair.second; } - }; - - void clearRows() - { - std::for_each( m_rows.begin(), m_rows.end(), RowDeleter() ); - m_rows.clear(); - } - - /* Get the symbol for the given variable. - - If a symbol does not exist for the variable, one will be created. - - */ - Symbol getVarSymbol( const Variable& variable ) - { - VarMap::iterator it = m_vars.find( variable ); - if( it != m_vars.end() ) - return it->second; - Symbol symbol( Symbol::External, m_id_tick++ ); - m_vars[ variable ] = symbol; - return symbol; - } - - /* Create a new Row object for the given constraint. - - The terms in the constraint will be converted to cells in the row. - Any term in the constraint with a coefficient of zero is ignored. - This method uses the `getVarSymbol` method to get the symbol for - the variables added to the row. If the symbol for a given cell - variable is basic, the cell variable will be substituted with the - basic row. - - The necessary slack and error variables will be added to the row. - If the constant for the row is negative, the sign for the row - will be inverted so the constant becomes positive. - - The tag will be updated with the marker and error symbols to use - for tracking the movement of the constraint in the tableau. - - */ - Row* createRow( const Constraint& constraint, Tag& tag ) - { - typedef std::vector::const_iterator iter_t; - const Expression& expr( constraint.expression() ); - Row* row = new Row( expr.constant() ); - - // Substitute the current basic variables into the row. - iter_t end = expr.terms().end(); - for( iter_t it = expr.terms().begin(); it != end; ++it ) - { - if( !nearZero( it->coefficient() ) ) - { - Symbol symbol( getVarSymbol( it->variable() ) ); - RowMap::const_iterator row_it = m_rows.find( symbol ); - if( row_it != m_rows.end() ) - row->insert( *row_it->second, it->coefficient() ); - else - row->insert( symbol, it->coefficient() ); - } - } - - // Add the necessary slack, error, and dummy variables. - switch( constraint.op() ) - { - case OP_LE: - case OP_GE: - { - double coeff = constraint.op() == OP_LE ? 1.0 : -1.0; - Symbol slack( Symbol::Slack, m_id_tick++ ); - tag.marker = slack; - row->insert( slack, coeff ); - if( constraint.strength() < strength::required ) - { - Symbol error( Symbol::Error, m_id_tick++ ); - tag.other = error; - row->insert( error, -coeff ); - m_objective->insert( error, constraint.strength() ); - } - break; - } - case OP_EQ: - { - if( constraint.strength() < strength::required ) - { - Symbol errplus( Symbol::Error, m_id_tick++ ); - Symbol errminus( Symbol::Error, m_id_tick++ ); - tag.marker = errplus; - tag.other = errminus; - row->insert( errplus, -1.0 ); // v = eplus - eminus - row->insert( errminus, 1.0 ); // v - eplus + eminus = 0 - m_objective->insert( errplus, constraint.strength() ); - m_objective->insert( errminus, constraint.strength() ); - } - else - { - Symbol dummy( Symbol::Dummy, m_id_tick++ ); - tag.marker = dummy; - row->insert( dummy ); - } - break; - } - } - - // Ensure the row as a positive constant. - if( row->constant() < 0.0 ) - row->reverseSign(); - - return row; - } - - /* Choose the subject for solving for the row. - - This method will choose the best subject for using as the solve - target for the row. An invalid symbol will be returned if there - is no valid target. - - The symbols are chosen according to the following precedence: - - 1) The first symbol representing an external variable. - 2) A negative slack or error tag variable. - - If a subject cannot be found, an invalid symbol will be returned. - - */ - Symbol chooseSubject( const Row& row, const Tag& tag ) - { - typedef Row::CellMap::const_iterator iter_t; - iter_t end = row.cells().end(); - for( iter_t it = row.cells().begin(); it != end; ++it ) - { - if( it->first.type() == Symbol::External ) - return it->first; - } - if( tag.marker.type() == Symbol::Slack || tag.marker.type() == Symbol::Error ) - { - if( row.coefficientFor( tag.marker ) < 0.0 ) - return tag.marker; - } - if( tag.other.type() == Symbol::Slack || tag.other.type() == Symbol::Error ) - { - if( row.coefficientFor( tag.other ) < 0.0 ) - return tag.other; - } - return Symbol(); - } - - /* Add the row to the tableau using an artificial variable. - - This will return false if the constraint cannot be satisfied. - - */ - bool addWithArtificialVariable( const Row& row ) - { - // Create and add the artificial variable to the tableau - Symbol art( Symbol::Slack, m_id_tick++ ); - m_rows[ art ] = new Row( row ); - m_artificial.reset( new Row( row ) ); - - // Optimize the artificial objective. This is successful - // only if the artificial objective is optimized to zero. - optimize( *m_artificial ); - bool success = nearZero( m_artificial->constant() ); - m_artificial.reset(); - - // If the artificial variable is not basic, pivot the row so that - // it becomes basic. If the row is constant, exit early. - RowMap::iterator it = m_rows.find( art ); - if( it != m_rows.end() ) - { - std::unique_ptr rowptr( it->second ); - m_rows.erase( it ); - if( rowptr->cells().empty() ) - return success; - Symbol entering( anyPivotableSymbol( *rowptr ) ); - if( entering.type() == Symbol::Invalid ) - return false; // unsatisfiable (will this ever happen?) - rowptr->solveFor( art, entering ); - substitute( entering, *rowptr ); - m_rows[ entering ] = rowptr.release(); - } - - // Remove the artificial variable from the tableau. - RowMap::iterator end = m_rows.end(); - for( it = m_rows.begin(); it != end; ++it ) - it->second->remove( art ); - m_objective->remove( art ); - return success; - } - - /* Substitute the parametric symbol with the given row. - - This method will substitute all instances of the parametric symbol - in the tableau and the objective function with the given row. - - */ - void substitute( const Symbol& symbol, const Row& row ) - { - typedef RowMap::iterator iter_t; - iter_t end = m_rows.end(); - for( iter_t it = m_rows.begin(); it != end; ++it ) - { - it->second->substitute( symbol, row ); - if( it->first.type() != Symbol::External && - it->second->constant() < 0.0 ) - m_infeasible_rows.push_back( it->first ); - } - m_objective->substitute( symbol, row ); - if( m_artificial.get() ) - m_artificial->substitute( symbol, row ); - } - - /* Optimize the system for the given objective function. - - This method performs iterations of Phase 2 of the simplex method - until the objective function reaches a minimum. - - Throws - ------ - InternalSolverError - The value of the objective function is unbounded. - - */ - void optimize( const Row& objective ) - { - while( true ) - { - Symbol entering( getEnteringSymbol( objective ) ); - if( entering.type() == Symbol::Invalid ) - return; - RowMap::iterator it = getLeavingRow( entering ); - if( it == m_rows.end() ) - throw InternalSolverError( "The objective is unbounded." ); - // pivot the entering symbol into the basis - Symbol leaving( it->first ); - Row* row = it->second; - m_rows.erase( it ); - row->solveFor( leaving, entering ); - substitute( entering, *row ); - m_rows[ entering ] = row; - } - } - - /* Optimize the system using the dual of the simplex method. - - The current state of the system should be such that the objective - function is optimal, but not feasible. This method will perform - an iteration of the dual simplex method to make the solution both - optimal and feasible. - - Throws - ------ - InternalSolverError - The system cannot be dual optimized. - - */ - void dualOptimize() - { - while( !m_infeasible_rows.empty() ) - { - - Symbol leaving( m_infeasible_rows.back() ); - m_infeasible_rows.pop_back(); - RowMap::iterator it = m_rows.find( leaving ); - if( it != m_rows.end() && !nearZero( it->second->constant() ) && - it->second->constant() < 0.0 ) - { - Symbol entering( getDualEnteringSymbol( *it->second ) ); - if( entering.type() == Symbol::Invalid ) - throw InternalSolverError( "Dual optimize failed." ); - // pivot the entering symbol into the basis - Row* row = it->second; - m_rows.erase( it ); - row->solveFor( leaving, entering ); - substitute( entering, *row ); - m_rows[ entering ] = row; - } - } - } - - /* Compute the entering variable for a pivot operation. - - This method will return first symbol in the objective function which - is non-dummy and has a coefficient less than zero. If no symbol meets - the criteria, it means the objective function is at a minimum, and an - invalid symbol is returned. - - */ - Symbol getEnteringSymbol( const Row& objective ) - { - typedef Row::CellMap::const_iterator iter_t; - iter_t end = objective.cells().end(); - for( iter_t it = objective.cells().begin(); it != end; ++it ) - { - if( it->first.type() != Symbol::Dummy && it->second < 0.0 ) - return it->first; - } - return Symbol(); - } - - /* Compute the entering symbol for the dual optimize operation. - - This method will return the symbol in the row which has a positive - coefficient and yields the minimum ratio for its respective symbol - in the objective function. The provided row *must* be infeasible. - If no symbol is found which meats the criteria, an invalid symbol - is returned. - - */ - Symbol getDualEnteringSymbol( const Row& row ) - { - typedef Row::CellMap::const_iterator iter_t; - Symbol entering; - double ratio = std::numeric_limits::max(); - iter_t end = row.cells().end(); - for( iter_t it = row.cells().begin(); it != end; ++it ) - { - if( it->second > 0.0 && it->first.type() != Symbol::Dummy ) - { - double coeff = m_objective->coefficientFor( it->first ); - double r = coeff / it->second; - if( r < ratio ) - { - ratio = r; - entering = it->first; - } - } - } - return entering; - } - - /* Get the first Slack or Error symbol in the row. - - If no such symbol is present, and Invalid symbol will be returned. - - */ - Symbol anyPivotableSymbol( const Row& row ) - { - typedef Row::CellMap::const_iterator iter_t; - iter_t end = row.cells().end(); - for( iter_t it = row.cells().begin(); it != end; ++it ) - { - const Symbol& sym( it->first ); - if( sym.type() == Symbol::Slack || sym.type() == Symbol::Error ) - return sym; - } - return Symbol(); - } - - /* Compute the row which holds the exit symbol for a pivot. - - This method will return an iterator to the row in the row map - which holds the exit symbol. If no appropriate exit symbol is - found, the end() iterator will be returned. This indicates that - the objective function is unbounded. - - */ - RowMap::iterator getLeavingRow( const Symbol& entering ) - { - typedef RowMap::iterator iter_t; - double ratio = std::numeric_limits::max(); - iter_t end = m_rows.end(); - iter_t found = m_rows.end(); - for( iter_t it = m_rows.begin(); it != end; ++it ) - { - if( it->first.type() != Symbol::External ) - { - double temp = it->second->coefficientFor( entering ); - if( temp < 0.0 ) - { - double temp_ratio = -it->second->constant() / temp; - if( temp_ratio < ratio ) - { - ratio = temp_ratio; - found = it; - } - } - } - } - return found; - } - - /* Compute the leaving row for a marker variable. - - This method will return an iterator to the row in the row map - which holds the given marker variable. The row will be chosen - according to the following precedence: - - 1) The row with a restricted basic varible and a negative coefficient - for the marker with the smallest ratio of -constant / coefficient. - - 2) The row with a restricted basic variable and the smallest ratio - of constant / coefficient. - - 3) The last unrestricted row which contains the marker. - - If the marker does not exist in any row, the row map end() iterator - will be returned. This indicates an internal solver error since - the marker *should* exist somewhere in the tableau. - - */ - RowMap::iterator getMarkerLeavingRow( const Symbol& marker ) - { - const double dmax = std::numeric_limits::max(); - typedef RowMap::iterator iter_t; - double r1 = dmax; - double r2 = dmax; - iter_t end = m_rows.end(); - iter_t first = end; - iter_t second = end; - iter_t third = end; - for( iter_t it = m_rows.begin(); it != end; ++it ) - { - double c = it->second->coefficientFor( marker ); - if( c == 0.0 ) - continue; - if( it->first.type() == Symbol::External ) - { - third = it; - } - else if( c < 0.0 ) - { - double r = -it->second->constant() / c; - if( r < r1 ) - { - r1 = r; - first = it; - } - } - else - { - double r = it->second->constant() / c; - if( r < r2 ) - { - r2 = r; - second = it; - } - } - } - if( first != end ) - return first; - if( second != end ) - return second; - return third; - } - - /* Remove the effects of a constraint on the objective function. - - */ - void removeConstraintEffects( const Constraint& cn, const Tag& tag ) - { - if( tag.marker.type() == Symbol::Error ) - removeMarkerEffects( tag.marker, cn.strength() ); - if( tag.other.type() == Symbol::Error ) - removeMarkerEffects( tag.other, cn.strength() ); - } - - /* Remove the effects of an error marker on the objective function. - - */ - void removeMarkerEffects( const Symbol& marker, double strength ) - { - RowMap::iterator row_it = m_rows.find( marker ); - if( row_it != m_rows.end() ) - m_objective->insert( *row_it->second, -strength ); - else - m_objective->insert( marker, -strength ); - } - - /* Test whether a row is composed of all dummy variables. - - */ - bool allDummies( const Row& row ) - { - typedef Row::CellMap::const_iterator iter_t; - iter_t end = row.cells().end(); - for( iter_t it = row.cells().begin(); it != end; ++it ) - { - if( it->first.type() != Symbol::Dummy ) - return false; - } - return true; - } - - CnMap m_cns; - RowMap m_rows; - VarMap m_vars; - EditMap m_edits; - std::vector m_infeasible_rows; - std::unique_ptr m_objective; - std::unique_ptr m_artificial; - Symbol::Id m_id_tick; -}; - -} // namespace impl - -} // namespace kiwi diff --git a/libs/canvas/kiwi/strength.h b/libs/canvas/kiwi/strength.h deleted file mode 100644 index 11732e98f1..0000000000 --- a/libs/canvas/kiwi/strength.h +++ /dev/null @@ -1,44 +0,0 @@ -/*----------------------------------------------------------------------------- -| Copyright (c) 2013-2017, Nucleic Development Team. -| -| Distributed under the terms of the Modified BSD License. -| -| The full license is in the file LICENSE, distributed with this software. -|----------------------------------------------------------------------------*/ -#pragma once -#include - - -namespace kiwi -{ - -namespace strength -{ - -inline double create( double a, double b, double c, double w = 1.0 ) -{ - double result = 0.0; - result += std::max( 0.0, std::min( 1000.0, a * w ) ) * 1000000.0; - result += std::max( 0.0, std::min( 1000.0, b * w ) ) * 1000.0; - result += std::max( 0.0, std::min( 1000.0, c * w ) ); - return result; -} - - -const double required = create( 1000.0, 1000.0, 1000.0 ); - -const double strong = create( 1.0, 0.0, 0.0 ); - -const double medium = create( 0.0, 1.0, 0.0 ); - -const double weak = create( 0.0, 0.0, 1.0 ); - - -inline double clip( double value ) -{ - return std::max( 0.0, std::min( required, value ) ); -} - -} // namespace strength - -} // namespace kiwi diff --git a/libs/canvas/kiwi/symbol.h b/libs/canvas/kiwi/symbol.h deleted file mode 100644 index ec422ad12d..0000000000 --- a/libs/canvas/kiwi/symbol.h +++ /dev/null @@ -1,68 +0,0 @@ -/*----------------------------------------------------------------------------- -| Copyright (c) 2013-2017, Nucleic Development Team. -| -| Distributed under the terms of the Modified BSD License. -| -| The full license is in the file LICENSE, distributed with this software. -|----------------------------------------------------------------------------*/ -#pragma once - - -namespace kiwi -{ - -namespace impl -{ - -class Symbol -{ - -public: - - typedef unsigned long long Id; - - enum Type - { - Invalid, - External, - Slack, - Error, - Dummy - }; - - Symbol() : m_id( 0 ), m_type( Invalid ) {} - - Symbol( Type type, Id id ) : m_id( id ), m_type( type ) {} - - ~Symbol() {} - - Id id() const - { - return m_id; - } - - Type type() const - { - return m_type; - } - -private: - - Id m_id; - Type m_type; - - friend bool operator<( const Symbol& lhs, const Symbol& rhs ) - { - return lhs.m_id < rhs.m_id; - } - - friend bool operator==( const Symbol& lhs, const Symbol& rhs ) - { - return lhs.m_id == rhs.m_id; - } - -}; - -} // namespace impl - -} // namespace kiwi diff --git a/libs/canvas/kiwi/symbolics.h b/libs/canvas/kiwi/symbolics.h deleted file mode 100644 index 23eed60f59..0000000000 --- a/libs/canvas/kiwi/symbolics.h +++ /dev/null @@ -1,685 +0,0 @@ -/*----------------------------------------------------------------------------- -| Copyright (c) 2013-2017, Nucleic Development Team. -| -| Distributed under the terms of the Modified BSD License. -| -| The full license is in the file LICENSE, distributed with this software. -|----------------------------------------------------------------------------*/ -#pragma once -#include -#include "constraint.h" -#include "expression.h" -#include "term.h" -#include "variable.h" - - -namespace kiwi -{ - -// Variable multiply, divide, and unary invert - -inline -Term operator*( const Variable& variable, double coefficient ) -{ - return Term( variable, coefficient ); -} - - -inline -Term operator/( const Variable& variable, double denominator ) -{ - return variable * ( 1.0 / denominator ); -} - - -inline -Term operator-( const Variable& variable ) -{ - return variable * -1.0; -} - - -// Term multiply, divide, and unary invert - -inline -Term operator*( const Term& term, double coefficient ) -{ - return Term( term.variable(), term.coefficient() * coefficient ); -} - - -inline -Term operator/( const Term& term, double denominator ) -{ - return term * ( 1.0 / denominator ); -} - - -inline -Term operator-( const Term& term ) -{ - return term * -1.0; -} - - -// Expression multiply, divide, and unary invert - -inline -Expression operator*( const Expression& expression, double coefficient ) -{ - std::vector terms; - terms.reserve( expression.terms().size() ); - typedef std::vector::const_iterator iter_t; - iter_t begin = expression.terms().begin(); - iter_t end = expression.terms().end(); - for( iter_t it = begin; it != end; ++it ) - terms.push_back( ( *it ) * coefficient ); - return Expression( terms, expression.constant() * coefficient ); -} - - -inline -Expression operator/( const Expression& expression, double denominator ) -{ - return expression * ( 1.0 / denominator ); -} - - -inline -Expression operator-( const Expression& expression ) -{ - return expression * -1.0; -} - - -// Double multiply - -inline -Expression operator*( double coefficient, const Expression& expression ) -{ - return expression * coefficient; -} - - -inline -Term operator*( double coefficient, const Term& term ) -{ - return term * coefficient; -} - - -inline -Term operator*( double coefficient, const Variable& variable ) -{ - return variable * coefficient; -} - - -// Expression add and subtract - -inline -Expression operator+( const Expression& first, const Expression& second ) -{ - std::vector terms; - terms.reserve( first.terms().size() + second.terms().size() ); - terms.insert( terms.begin(), first.terms().begin(), first.terms().end() ); - terms.insert( terms.end(), second.terms().begin(), second.terms().end() ); - return Expression( terms, first.constant() + second.constant() ); -} - - -inline -Expression operator+( const Expression& first, const Term& second ) -{ - std::vector terms; - terms.reserve( first.terms().size() + 1 ); - terms.insert( terms.begin(), first.terms().begin(), first.terms().end() ); - terms.push_back( second ); - return Expression( terms, first.constant() ); -} - - -inline -Expression operator+( const Expression& expression, const Variable& variable ) -{ - return expression + Term( variable ); -} - - -inline -Expression operator+( const Expression& expression, double constant ) -{ - return Expression( expression.terms(), expression.constant() + constant ); -} - - -inline -Expression operator-( const Expression& first, const Expression& second ) -{ - return first + -second; -} - - -inline -Expression operator-( const Expression& expression, const Term& term ) -{ - return expression + -term; -} - - -inline -Expression operator-( const Expression& expression, const Variable& variable ) -{ - return expression + -variable; -} - - -inline -Expression operator-( const Expression& expression, double constant ) -{ - return expression + -constant; -} - - -// Term add and subtract - -inline -Expression operator+( const Term& term, const Expression& expression ) -{ - return expression + term; -} - - -inline -Expression operator+( const Term& first, const Term& second ) -{ - std::vector terms; - terms.reserve( 2 ); - terms.push_back( first ); - terms.push_back( second ); - return Expression( terms ); -} - - -inline -Expression operator+( const Term& term, const Variable& variable ) -{ - return term + Term( variable ); -} - - -inline -Expression operator+( const Term& term, double constant ) -{ - return Expression( term, constant ); -} - - -inline -Expression operator-( const Term& term, const Expression& expression ) -{ - return -expression + term; -} - - -inline -Expression operator-( const Term& first, const Term& second ) -{ - return first + -second; -} - - -inline -Expression operator-( const Term& term, const Variable& variable ) -{ - return term + -variable; -} - - -inline -Expression operator-( const Term& term, double constant ) -{ - return term + -constant; -} - - -// Variable add and subtract - -inline -Expression operator+( const Variable& variable, const Expression& expression ) -{ - return expression + variable; -} - - -inline -Expression operator+( const Variable& variable, const Term& term ) -{ - return term + variable; -} - - -inline -Expression operator+( const Variable& first, const Variable& second ) -{ - return Term( first ) + second; -} - - -inline -Expression operator+( const Variable& variable, double constant ) -{ - return Term( variable ) + constant; -} - - -inline -Expression operator-( const Variable& variable, const Expression& expression ) -{ - return variable + -expression; -} - - -inline -Expression operator-( const Variable& variable, const Term& term ) -{ - return variable + -term; -} - - -inline -Expression operator-( const Variable& first, const Variable& second ) -{ - return first + -second; -} - - -inline -Expression operator-( const Variable& variable, double constant ) -{ - return variable + -constant; -} - - -// Double add and subtract - -inline -Expression operator+( double constant, const Expression& expression ) -{ - return expression + constant; -} - - -inline -Expression operator+( double constant, const Term& term ) -{ - return term + constant; -} - - -inline -Expression operator+( double constant, const Variable& variable ) -{ - return variable + constant; -} - - -inline -Expression operator-( double constant, const Expression& expression ) -{ - return -expression + constant; -} - - -inline -Expression operator-( double constant, const Term& term ) -{ - return -term + constant; -} - - -inline -Expression operator-( double constant, const Variable& variable ) -{ - return -variable + constant; -} - - -// Expression relations - -inline -Constraint operator==( const Expression& first, const Expression& second ) -{ - return Constraint( first - second, OP_EQ ); -} - - -inline -Constraint operator==( const Expression& expression, const Term& term ) -{ - return expression == Expression( term ); -} - - -inline -Constraint operator==( const Expression& expression, const Variable& variable ) -{ - return expression == Term( variable ); -} - - -inline -Constraint operator==( const Expression& expression, double constant ) -{ - return expression == Expression( constant ); -} - - -inline -Constraint operator<=( const Expression& first, const Expression& second ) -{ - return Constraint( first - second, OP_LE ); -} - - -inline -Constraint operator<=( const Expression& expression, const Term& term ) -{ - return expression <= Expression( term ); -} - - -inline -Constraint operator<=( const Expression& expression, const Variable& variable ) -{ - return expression <= Term( variable ); -} - - -inline -Constraint operator<=( const Expression& expression, double constant ) -{ - return expression <= Expression( constant ); -} - - -inline -Constraint operator>=( const Expression& first, const Expression& second ) -{ - return Constraint( first - second, OP_GE ); -} - - -inline -Constraint operator>=( const Expression& expression, const Term& term ) -{ - return expression >= Expression( term ); -} - - -inline -Constraint operator>=( const Expression& expression, const Variable& variable ) -{ - return expression >= Term( variable ); -} - - -inline -Constraint operator>=( const Expression& expression, double constant ) -{ - return expression >= Expression( constant ); -} - - -// Term relations - -inline -Constraint operator==( const Term& term, const Expression& expression ) -{ - return expression == term; -} - - -inline -Constraint operator==( const Term& first, const Term& second ) -{ - return Expression( first ) == second; -} - - -inline -Constraint operator==( const Term& term, const Variable& variable ) -{ - return Expression( term ) == variable; -} - - -inline -Constraint operator==( const Term& term, double constant ) -{ - return Expression( term ) == constant; -} - - -inline -Constraint operator<=( const Term& term, const Expression& expression ) -{ - return expression >= term; -} - - -inline -Constraint operator<=( const Term& first, const Term& second ) -{ - return Expression( first ) <= second; -} - - -inline -Constraint operator<=( const Term& term, const Variable& variable ) -{ - return Expression( term ) <= variable; -} - - -inline -Constraint operator<=( const Term& term, double constant ) -{ - return Expression( term ) <= constant; -} - - -inline -Constraint operator>=( const Term& term, const Expression& expression ) -{ - return expression <= term; -} - - -inline -Constraint operator>=( const Term& first, const Term& second ) -{ - return Expression( first ) >= second; -} - - -inline -Constraint operator>=( const Term& term, const Variable& variable ) -{ - return Expression( term ) >= variable; -} - - -inline -Constraint operator>=( const Term& term, double constant ) -{ - return Expression( term ) >= constant; -} - - -// Variable relations -inline -Constraint operator==( const Variable& variable, const Expression& expression ) -{ - return expression == variable; -} - - -inline -Constraint operator==( const Variable& variable, const Term& term ) -{ - return term == variable; -} - - -inline -Constraint operator==( const Variable& first, const Variable& second ) -{ - return Term( first ) == second; -} - - -inline -Constraint operator==( const Variable& variable, double constant ) -{ - return Term( variable ) == constant; -} - - -inline -Constraint operator<=( const Variable& variable, const Expression& expression ) -{ - return expression >= variable; -} - - -inline -Constraint operator<=( const Variable& variable, const Term& term ) -{ - return term >= variable; -} - - -inline -Constraint operator<=( const Variable& first, const Variable& second ) -{ - return Term( first ) <= second; -} - - -inline -Constraint operator<=( const Variable& variable, double constant ) -{ - return Term( variable ) <= constant; -} - - -inline -Constraint operator>=( const Variable& variable, const Expression& expression ) -{ - return expression <= variable; -} - - -inline -Constraint operator>=( const Variable& variable, const Term& term ) -{ - return term <= variable; -} - - -inline -Constraint operator>=( const Variable& first, const Variable& second ) -{ - return Term( first ) >= second; -} - - -inline -Constraint operator>=( const Variable& variable, double constant ) -{ - return Term( variable ) >= constant; -} - - -// Double relations - -inline -Constraint operator==( double constant, const Expression& expression ) -{ - return expression == constant; -} - - -inline -Constraint operator==( double constant, const Term& term ) -{ - return term == constant; -} - - -inline -Constraint operator==( double constant, const Variable& variable ) -{ - return variable == constant; -} - - -inline -Constraint operator<=( double constant, const Expression& expression ) -{ - return expression >= constant; -} - - -inline -Constraint operator<=( double constant, const Term& term ) -{ - return term >= constant; -} - - -inline -Constraint operator<=( double constant, const Variable& variable ) -{ - return variable >= constant; -} - - -inline -Constraint operator>=( double constant, const Expression& expression ) -{ - return expression <= constant; -} - - -inline -Constraint operator>=( double constant, const Term& term ) -{ - return term <= constant; -} - - -inline -Constraint operator>=( double constant, const Variable& variable ) -{ - return variable <= constant; -} - - -// Constraint strength modifier - -inline -Constraint operator|( const Constraint& constraint, double strength ) -{ - return Constraint( constraint, strength ); -} - - -inline -Constraint operator|( double strength, const Constraint& constraint ) -{ - return constraint | strength; -} - -} // namespace kiwi diff --git a/libs/canvas/kiwi/term.h b/libs/canvas/kiwi/term.h deleted file mode 100644 index ac08569eba..0000000000 --- a/libs/canvas/kiwi/term.h +++ /dev/null @@ -1,58 +0,0 @@ -/*----------------------------------------------------------------------------- -| Copyright (c) 2013-2017, Nucleic Development Team. -| -| Distributed under the terms of the Modified BSD License. -| -| The full license is in the file LICENSE, distributed with this software. -|----------------------------------------------------------------------------*/ -#pragma once -#include -#include -#include "variable.h" - - -namespace kiwi -{ - -class Term -{ - -public: - - Term( const Variable& variable, double coefficient = 1.0 ) : - m_variable( variable ), m_coefficient( coefficient ) {} - - // to facilitate efficient map -> vector copies - Term( const std::pair& pair ) : - m_variable( pair.first ), m_coefficient( pair.second ) {} - - ~Term() {} - - const Variable& variable() const - { - return m_variable; - } - - double coefficient() const - { - return m_coefficient; - } - - double value() const - { - return m_coefficient * m_variable.value(); - } - -private: - - Variable m_variable; - double m_coefficient; -}; - -static std::ostream& operator<< (std::ostream& o, kiwi::Term const & t) -{ - return o << t.variable().name() << " * " << t.coefficient(); -} - -} // namespace kiwi - diff --git a/libs/canvas/kiwi/util.h b/libs/canvas/kiwi/util.h deleted file mode 100644 index 560a43a746..0000000000 --- a/libs/canvas/kiwi/util.h +++ /dev/null @@ -1,24 +0,0 @@ -/*----------------------------------------------------------------------------- -| Copyright (c) 2013-2017, Nucleic Development Team. -| -| Distributed under the terms of the Modified BSD License. -| -| The full license is in the file LICENSE, distributed with this software. -|----------------------------------------------------------------------------*/ -#pragma once - -namespace kiwi -{ - -namespace impl -{ - -inline bool nearZero(double value) -{ - const double eps = 1.0e-8; - return value < 0.0 ? -value < eps : value < eps; -} - -} // namespace impl - -} // namespace kiwi diff --git a/libs/canvas/kiwi/variable.h b/libs/canvas/kiwi/variable.h deleted file mode 100644 index f91a0a0b57..0000000000 --- a/libs/canvas/kiwi/variable.h +++ /dev/null @@ -1,111 +0,0 @@ -/*----------------------------------------------------------------------------- -| Copyright (c) 2013-2017, Nucleic Development Team. -| -| Distributed under the terms of the Modified BSD License. -| -| The full license is in the file LICENSE, distributed with this software. -|----------------------------------------------------------------------------*/ -#pragma once -#include -#include -#include "shareddata.h" - -namespace kiwi -{ - -class Variable -{ - -public: - class Context - { - public: - Context() {} - virtual ~Context() {} // LCOV_EXCL_LINE - }; - - Variable(Context *context = 0) : m_data(new VariableData("", context)) {} - - Variable(const std::string &name, Context *context = 0) : m_data(new VariableData(name, context)) {} - - Variable(const char *name, Context *context = 0) : m_data(new VariableData(name, context)) {} - - ~Variable() {} - - const std::string &name() const - { - return m_data->m_name; - } - - void setName(const char *name) - { - m_data->m_name = name; - } - - void setName(const std::string &name) - { - m_data->m_name = name; - } - - Context *context() const - { - return m_data->m_context.get(); - } - - void setContext(Context *context) - { - m_data->m_context.reset(context); - } - - double value() const - { - return m_data->m_value; - } - - void setValue(double value) - { - m_data->m_value = value; - } - - // operator== is used for symbolics - bool equals(const Variable &other) const - { - return m_data == other.m_data; - } - -private: - class VariableData : public SharedData - { - - public: - VariableData(const std::string &name, Context *context) : SharedData(), - m_name(name), - m_context(context), - m_value(0.0) {} - - VariableData(const char *name, Context *context) : SharedData(), - m_name(name), - m_context(context), - m_value(0.0) {} - - ~VariableData() {} - - std::string m_name; - std::unique_ptr m_context; - double m_value; - - private: - VariableData(const VariableData &other); - - VariableData &operator=(const VariableData &other); - }; - - SharedDataPtr m_data; - - friend bool operator<(const Variable &lhs, const Variable &rhs) - { - return lhs.m_data < rhs.m_data; - } -}; - -} // namespace kiwi diff --git a/libs/canvas/kiwi/version.h b/libs/canvas/kiwi/version.h deleted file mode 100644 index f6154482ae..0000000000 --- a/libs/canvas/kiwi/version.h +++ /dev/null @@ -1,14 +0,0 @@ -/*----------------------------------------------------------------------------- -| Copyright (c) 2013-2020, Nucleic Development Team. -| -| Distributed under the terms of the Modified BSD License. -| -| The full license is in the file LICENSE, distributed with this software. -|----------------------------------------------------------------------------*/ -#pragma once - -#define KIWI_MAJOR_VERSION 1 -#define KIWI_MINOR_VERSION 2 -#define KIWI_MICRO_VERSION 0 -#define KIWI_VERSION_HEX 0x010200 -#define KIWI_VERSION "1.2.0" diff --git a/libs/canvas/test/interactive/constraint_test.cc b/libs/canvas/test/interactive/constraint_test.cc deleted file mode 100644 index b026da3934..0000000000 --- a/libs/canvas/test/interactive/constraint_test.cc +++ /dev/null @@ -1,131 +0,0 @@ -#include - -#include -#include -#include - -#include "gtkmm2ext/colors.h" - -#include "canvas/box.h" -#include "canvas/canvas.h" -#include "canvas/circle.h" -#include "canvas/constrained_item.h" -#include "canvas/constraint_packer.h" -#include "canvas/rectangle.h" -#include "canvas/text.h" - -using namespace ArdourCanvas; -using namespace Gtk; -using std::cerr; -using std::endl; - -int -main (int argc, char* argv[]) -{ - Gtk::Main app (&argc, &argv); - - Gtk::Window win; - Gtk::Adjustment hadj (0, 0, 1000, 1, 10); - Gtk::Adjustment vadj (0, 0, 1000, 1, 10); - GtkCanvasViewport cview (hadj, vadj); - Canvas* c = cview.canvas (); - - c->set_background_color (0xffffffff); - - // cview.set_size_request (100, 100); - - win.add (cview); - - Rectangle* r1 = new Rectangle (c); - Rectangle* r2 = new Rectangle (c); - Rectangle* r3 = new Rectangle (c); - - r1->set_fill_color (Gtkmm2ext::random_color()); - r2->set_fill_color (Gtkmm2ext::random_color()); - r3->set_fill_color (Gtkmm2ext::random_color()); - - r1->name = "r1"; - r2->name = "r2"; - r3->name = "r3"; - - //r1->set_size_request (20, 20); - //r2->set_size_request (30, 30); - //r3->set_size_request (40, 40); - - ConstraintPacker* vbox = new ConstraintPacker (c->root(), Vertical); - vbox->name = "vbox"; - vbox->set_fill (true); - vbox->set_fill_color (0xff0000ff); - vbox->set_margin (20); - - vbox->pack_start (r1, PackOptions(PackExpand|PackFill)); - vbox->pack_start (r2, PackOptions(PackExpand|PackFill)); - vbox->pack_start (r3, PackOptions(PackExpand|PackFill)); - - ConstraintPacker* hbox1 = new ConstraintPacker (c, Horizontal); - hbox1->name = "hbox1"; - hbox1->set_fill (true); - hbox1->set_fill_color (0x00ff00ff); - - hbox1->set_margin (10); - - Rectangle* r4 = new Rectangle (c); - Rectangle* r5 = new Rectangle (c); - Rectangle* r6 = new Rectangle (c); - - r4->set_fill_color (Gtkmm2ext::random_color()); - r5->set_fill_color (Gtkmm2ext::random_color()); - r6->set_fill_color (Gtkmm2ext::random_color()); - - r4->name = "r4"; - r5->name = "r5"; - r6->name = "r6"; - - ConstrainedItem* ci4 = hbox1->pack_start (r4, PackOptions(PackExpand|PackFill)); - hbox1->pack_start (r5, PackOptions(PackExpand|PackFill)); - hbox1->pack_start (r6, PackOptions(PackExpand|PackFill)); - - BoxConstrainedItem* hb1; - BoxConstrainedItem* ci; - - hb1 = vbox->pack_start (hbox1, PackOptions (PackExpand|PackFill)); - - ci4->add_constraint (ci4->width() == hb1->width() / 2.); - - Circle* circle = new Circle (c); - circle->name = "circle"; - //circle->set_radius (30); - circle->set_fill_color (Gtkmm2ext::random_color()); - circle->set_outline_color (Gtkmm2ext::random_color()); - - ci = vbox->pack_start (circle, PackOptions (PackExpand|PackFill)); - ci->add_constraint (ci->height() == 0.5 * hb1->height()); - ci->add_constraint (ci->center_x() == ci4->center_x()); - ci->add_constraint (ci->top_padding() == 10); - ci->add_constraint (ci->bottom_padding() == 10); - - ConstraintPacker* hbox2 = new ConstraintPacker (c, Horizontal); - hbox2->name = "hbox2"; - hbox2->set_fill (true); - hbox2->set_fill_color (Gtkmm2ext::random_color()); - hbox2->set_outline (true); - - Text* txt = new Text (c); - txt->name = "text"; - - Pango::FontDescription font ("Sans"); - - txt->set_font_description (font); - txt->set ("hello world"); - - ConstrainedItem* hb2 = vbox->pack_start (hbox2, PackOptions (PackExpand|PackFill)); - ConstrainedItem* ti = hbox2->pack_start (txt, PackOptions (PackExpand), PackOptions (0)); - - ti->add_constraint (ti->center_x() == hb2->center_x()); - ti->add_constraint (ti->center_y() == hb2->center_y()); - - win.show_all (); - app.run (); - - return 0; -} diff --git a/libs/canvas/test/interactive/constraint_test2.cc b/libs/canvas/test/interactive/constraint_test2.cc deleted file mode 100644 index 014b543bd9..0000000000 --- a/libs/canvas/test/interactive/constraint_test2.cc +++ /dev/null @@ -1,184 +0,0 @@ -#include - -#include -#include -#include - -#include "pbd/compose.h" - -#include "gtkmm2ext/colors.h" - -#include "canvas/box.h" -#include "canvas/canvas.h" -#include "canvas/circle.h" -#include "canvas/constrained_item.h" -#include "canvas/constraint_packer.h" -#include "canvas/rectangle.h" -#include "canvas/text.h" - -using namespace ArdourCanvas; -using namespace Gtk; -using std::cerr; -using std::endl; - -#define SQUARED 16 - - struct Column { - Column (Canvas* c, uint32_t num) : number (num) { - box = new ConstraintPacker (c, Vertical); - box->name = string_compose ("col%1", num); - box->set_spacing (12); - - Pango::FontDescription font ("Sans"); - - for (int i = 0; i < SQUARED; ++i) { - rects[i] = new Rectangle (c); - rects[i]->name = string_compose ("r%1-%2", number, i); - rects[i]->set_size_request (8, 12); - rects[i]->set_outline_color (0xff0000ff); - rects[i]->set_fill_color (Gtkmm2ext::random_color()); - - BoxConstrainedItem* b = box->pack_start (rects[i], PackOptions (PackExpand|PackFill)); - - labels[i] = new Text (c); - labels[i]->name = string_compose ("t%1-%2", number, i); - labels[i]->set_font_description (font); - labels[i]->set (labels[i]->name); - labels[i]->set_fill_color (0x000000ff); - - ConstrainedItem* l = box->add_constrained (labels[i]); - - /* Note: the use of labels[i].width() here is - * equivalent to using a constant. This is not the same - * as l->width(), which is a constraint-solved - * variable. labels[i].width() is the pixel width of - * the current text contents of labels[i]. - */ - - l->centered_on (*b); - l->add_constraint (l->width() == labels[i]->width()); - l->add_constraint (l->height() == labels[i]->height()); - -#if 0 - l->add_constraint (l->left() == b->center_x() - (labels[i]->width() / 2.)); - l->add_constraint (l->width() == labels[i]->width()); - l->add_constraint (l->right() == l->left() + labels[i]->width()); - - l->add_constraint (l->top() == b->center_y() - (labels[i]->height() / 2)); - l->add_constraint (l->height() == labels[i]->height()); - l->add_constraint (l->bottom() == l->top() + l->height()); -#endif - } - } - - ConstraintPacker* box; - Rectangle* rects[SQUARED]; - Text* labels[SQUARED]; - uint32_t number; -}; - -int -main (int argc, char* argv[]) -{ - Gtk::Main app (&argc, &argv); - - Gtk::Window win; - Gtk::Adjustment hadj (0, 0, 1000, 1, 10); - Gtk::Adjustment vadj (0, 0, 1000, 1, 10); - GtkCanvasViewport cview (hadj, vadj); - Canvas* c = cview.canvas (); - - c->set_background_color (0xffffffff); - - // cview.set_size_request (100, 100); - - win.add (cview); - - ConstraintPacker* main_hbox = new ConstraintPacker (c->root(), Horizontal); - main_hbox->name = "main"; - main_hbox->set_spacing (12); - main_hbox->set_margin (24); - - Column* cols[SQUARED]; - - for (size_t i = 0; i < SQUARED; ++i) { - cols[i] = new Column (c, i); - main_hbox->pack_start (cols[i]->box, PackOptions (PackExpand|PackFill)); - } - - -#if 0 - Circle* circle = new Circle (c); - circle->name = "circle"; - //circle->set_radius (30); - circle->set_fill_color (Gtkmm2ext::random_color()); - circle->set_outline_color (Gtkmm2ext::random_color()); - - ci = vbox->pack_start (circle, PackOptions (PackExpand|PackFill)); - ci->add_constraint (ci->height() == 0.5 * hb1->height()); - - ConstraintPacker* hbox2 = new ConstraintPacker (c, Horizontal); - hbox2->name = "hbox2"; - hbox2->set_fill (true); - hbox2->set_fill_color (Gtkmm2ext::random_color()); - - Text* txt = new Text (c); - txt->name = "text"; - - Pango::FontDescription font ("Sans"); - - txt->set_font_description (font); - txt->set ("hello, world"); - - ConstrainedItem* ti = hbox2->pack_start (txt, PackExpand); - ti->add_constraint (ti->left() == 25); - - vbox->pack_start (hbox2, PackOptions (PackExpand|PackFill)); -#endif - - - win.show_all (); - app.run (); - - return 0; -} - - - -#if 0 -/* code test arbitrary constraint layout */ - - ConstraintPacker* packer = new ConstraintPacker (c->root()); - - ConstrainedItem* left = packer->add_constrained (r1); - ConstrainedItem* right = packer->add_constrained (r2); - ConstrainedItem* center = packer->add_constrained (r3); - - /* x-axis */ - - packer->constrain (left->left() == 0); - packer->constrain (center->left() == left->right()); - packer->constrain (right->left() == center->right()); - - packer->constrain (left->width() == packer->width * 0.4); - packer->constrain (center->width() == packer->width * 0.1); - packer->constrain (left->width() + right->width() + center->width() == packer->width); - - packer->constrain (left->right() == left->left() + left->width()); - packer->constrain (right->right() == right->left() + right->width()); - packer->constrain (center->right() == center->left() + center->width()); - - /* y-axis */ - - packer->constrain (left->top() == 0); - packer->constrain (right->top() == left->top()); - packer->constrain (center->top() == left->top()); - - packer->constrain (left->height() == packer->height); - packer->constrain (right->height() == left->height()); - packer->constrain (center->height() == left->height()); - - packer->constrain (left->bottom() == left->top() + left->height()); - packer->constrain (center->bottom() == center->top() + center->height()); - packer->constrain (right->bottom() == right->top() + right->height()); -#endif diff --git a/libs/canvas/test/interactive/constraint_test3.cc b/libs/canvas/test/interactive/constraint_test3.cc deleted file mode 100644 index 9d17bc5447..0000000000 --- a/libs/canvas/test/interactive/constraint_test3.cc +++ /dev/null @@ -1,93 +0,0 @@ -#include - -#include -#include -#include - -#include "gtkmm2ext/colors.h" - -#include "canvas/box.h" -#include "canvas/canvas.h" -#include "canvas/circle.h" -#include "canvas/constrained_item.h" -#include "canvas/constraint_packer.h" -#include "canvas/rectangle.h" -#include "canvas/text.h" - -using namespace ArdourCanvas; -using namespace Gtk; -using std::cerr; -using std::endl; - -int -main (int argc, char* argv[]) -{ - Gtk::Main app (&argc, &argv); - - Gtk::Window win; - Gtk::Adjustment hadj (0, 0, 1000, 1, 10); - Gtk::Adjustment vadj (0, 0, 1000, 1, 10); - GtkCanvasViewport cview (hadj, vadj); - Canvas* c = cview.canvas (); - - c->set_background_color (0xffffffff); - - cview.set_size_request (100, 100); - - win.add (cview); - - Rectangle* r1 = new Rectangle (c); - Rectangle* r2 = new Rectangle (c); - Rectangle* r3 = new Rectangle (c); - - r1->set_fill_color (Gtkmm2ext::random_color()); - r2->set_fill_color (Gtkmm2ext::random_color()); - r3->set_fill_color (Gtkmm2ext::random_color()); - - r1->name = "r1"; - r2->name = "r2"; - r3->name = "r3"; - - r1->set_size_request (20, 20); - r2->set_size_request (30, 30); - r3->set_size_request (40, 40); - - ConstraintPacker* packer = new ConstraintPacker (c->root()); - - ConstrainedItem* left = packer->add_constrained (r1); - ConstrainedItem* right = packer->add_constrained (r2); - ConstrainedItem* center = packer->add_constrained (r3); - - /* x-axis */ - - packer->constrain (left->left() == 0); - packer->constrain (center->left() == left->right()); - packer->constrain (right->left() == center->right()); - - packer->constrain (left->width() == packer->width * 0.4); - packer->constrain (center->width() == packer->width * 0.1); - packer->constrain (left->width() + right->width() + center->width() == packer->width); - - packer->constrain (left->right() == left->left() + left->width()); - packer->constrain (right->right() == right->left() + right->width()); - packer->constrain (center->right() == center->left() + center->width()); - - /* y-axis */ - - packer->constrain (left->top() == 0); - packer->constrain (right->top() == left->top()); - packer->constrain (center->top() == left->top()); - - packer->constrain (left->height() == packer->height); - packer->constrain (right->height() == left->height()); - packer->constrain (center->height() == left->height()); - - packer->constrain (left->bottom() == left->top() + left->height()); - packer->constrain (center->bottom() == center->top() + center->height()); - packer->constrain (right->bottom() == right->top() + right->height()); - - win.show_all (); - app.run (); - - return 0; -} diff --git a/libs/canvas/test/interactive/constraint_test4.cc b/libs/canvas/test/interactive/constraint_test4.cc deleted file mode 100644 index ed326f45be..0000000000 --- a/libs/canvas/test/interactive/constraint_test4.cc +++ /dev/null @@ -1,127 +0,0 @@ -#include - -#include -#include -#include - -#include "gtkmm2ext/colors.h" - -#include "canvas/box.h" -#include "canvas/canvas.h" -#include "canvas/circle.h" -#include "canvas/constrained_item.h" -#include "canvas/constraint_packer.h" -#include "canvas/rectangle.h" -#include "canvas/text.h" - -using namespace ArdourCanvas; -using namespace Gtk; -using std::cerr; -using std::endl; - -int -main (int argc, char* argv[]) -{ - Gtk::Main app (&argc, &argv); - - Gtk::Window win; - Gtk::Adjustment hadj (0, 0, 1000, 1, 10); - Gtk::Adjustment vadj (0, 0, 1000, 1, 10); - GtkCanvasViewport cview (hadj, vadj); - Canvas* c = cview.canvas (); - - c->set_background_color (0xffffffff); - - win.add (cview); - - /* Make some items */ - - Rectangle* r1 = new Rectangle (c); - Rectangle* r2 = new Rectangle (c); - Rectangle* r3 = new Rectangle (c); - - r1->set_fill_color (Gtkmm2ext::random_color()); - r2->set_fill_color (Gtkmm2ext::random_color()); - r3->set_fill_color (Gtkmm2ext::random_color()); - - r1->name = "L"; - r2->name = "R"; - r3->name = "C"; - - r1->set_size_request (20, 20); - r2->set_size_request (30, 30); - r3->set_size_request (40, 40); - - Text* txt = new Text (c); - txt->name = "text"; - Pango::FontDescription font ("Sans"); - txt->set_font_description (font); - txt->set ("hello world"); - - Rectangle* bb = new Rectangle (c); - bb->set_fill_color (Gtkmm2ext::random_color()); - - Circle* circ = new Circle (c); - circ->name = "circle"; - circ->set_fill_color (Gtkmm2ext::random_color()); - circ->set_outline_color (Gtkmm2ext::random_color()); - - /* create a container */ - - ConstraintPacker* packer = new ConstraintPacker (c->root()); - - /* give it a minimum size */ - - packer->set_size_request (100, 100); - - /* add stuff */ - - ConstrainedItem* left = packer->add_constrained (r1); - ConstrainedItem* right = packer->add_constrained (r2); - ConstrainedItem* center = packer->add_constrained (r3); - ConstrainedItem* text = packer->add_constrained (txt); - ConstrainedItem* bens_box = packer->add_constrained (bb); - ConstrainedItem* circle = packer->add_constrained (circ); - - /* first, constraints that connect an item dimension to the container dimensions or a constant */ - packer->constrain (left->left() == 0); - packer->constrain (left->height() == packer->height); - packer->constrain (left->top() == 0); - packer->constrain (left->width() == 0.5 * packer->width); - packer->constrain (right->right() == packer->width); - packer->constrain (center->height() == 0.5 * packer->height); - - /* second, constraints that connect an item dimension to other items */ - center->right_of (*left, 50); - right->right_of (*center); - center->same_width_as (*right); - right->same_width_as (*center); - right->same_height_as (*left); - center->top_aligned_with (*left); - right->top_aligned_with (*center); - - /* XXX this needs to somehow move into ConstraintPacker but I currently - * see no way to build a constraint from a container of - * ConstrainedItems - */ - - packer->constrain (left->width() + right->width() + center->width() + - left->left_padding() + left->right_padding() + - center->left_padding() + center->right_padding() + - right->left_padding() + right->right_padding() - == packer->width); - - /* Text at a fixed position */ - text->at (Duple (150, 50)); - /* Rectangle of fixed position and size */ - bens_box->box (Rect (40, 40, 80, 80)); - - /* a circle sized and centered */ - circle->size (Duple (30, 30)); - circle->centered_on (*center); - - win.show_all (); - app.run (); - - return 0; -} diff --git a/libs/canvas/wscript b/libs/canvas/wscript index 06185e42ba..f76cc4c18e 100644 --- a/libs/canvas/wscript +++ b/libs/canvas/wscript @@ -34,8 +34,6 @@ canvas_sources = [ 'canvas.cc', 'circle.cc', 'container.cc', - 'constrained_item.cc', - 'constraint_packer.cc', 'curve.cc', 'debug.cc', 'item.cc', @@ -98,46 +96,6 @@ def build(bld): obj.install_path = bld.env['LIBDIR'] obj.defines += [ 'PACKAGE="' + I18N_PACKAGE + '"' ] - # interactive (non-automated, non-cppunit) canvas tests - # fails to link when cross-compiling (lacks libpbd dependencies - # uselib = 'GLIBMM SIGCPP XML UUID SNDFILE GIOMM ARCHIVE CURL' - if False : # bld.env['BUILD_TESTS']: - constraint_test_src = [ 'test/interactive/constraint_test.cc' ] - constraint_test = bld (features = 'cxx cxxprogram') - constraint_test.source = constraint_test_src - constraint_test.includes = obj.includes + ['../pbd', '../gtkmm2ext'] - constraint_test.use = [ 'GTKMM', 'libcanvas', 'libgtkmm2ext' ] - constraint_test.name = 'constraint_test' - constraint_test.target = 'constraint_test' - constraint_test.install_path = '' - - constraint_test2_src = [ 'test/interactive/constraint_test2.cc' ] - constraint_test2 = bld (features = 'cxx cxxprogram') - constraint_test2.source = constraint_test2_src - constraint_test2.includes = obj.includes + ['../pbd', '../gtkmm2ext'] - constraint_test2.use = [ 'GTKMM', 'libcanvas', 'libgtkmm2ext' ] - constraint_test2.name = 'constraint_test2' - constraint_test2.target = 'constraint_test2' - constraint_test2.install_path = '' - - constraint_test3_src = [ 'test/interactive/constraint_test3.cc' ] - constraint_test3 = bld (features = 'cxx cxxprogram') - constraint_test3.source = constraint_test3_src - constraint_test3.includes = obj.includes + ['../pbd', '../gtkmm2ext'] - constraint_test3.use = [ 'GTKMM', 'libcanvas', 'libgtkmm2ext' ] - constraint_test3.name = 'constraint_test3' - constraint_test3.target = 'constraint_test3' - constraint_test3.install_path = '' - - constraint_test4_src = [ 'test/interactive/constraint_test4.cc' ] - constraint_test4 = bld (features = 'cxx cxxprogram') - constraint_test4.source = constraint_test4_src - constraint_test4.includes = obj.includes + ['../pbd', '../gtkmm2ext'] - constraint_test4.use = [ 'GTKMM', 'libcanvas', 'libgtkmm2ext' ] - constraint_test4.name = 'constraint_test4' - constraint_test4.target = 'constraint_test4' - constraint_test4.install_path = '' - # canvas unit-tests are outdated if False and bld.env['BUILD_TESTS'] and bld.is_defined('HAVE_CPPUNIT'): unit_testobj = bld(features = 'cxx cxxprogram')