summaryrefslogtreecommitdiffstats
path: root/src/display/control/canvas-item-group.cpp
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--src/display/control/canvas-item-group.cpp118
1 files changed, 118 insertions, 0 deletions
diff --git a/src/display/control/canvas-item-group.cpp b/src/display/control/canvas-item-group.cpp
new file mode 100644
index 0000000..93193c3
--- /dev/null
+++ b/src/display/control/canvas-item-group.cpp
@@ -0,0 +1,118 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/**
+ * A CanvasItem that contains other CanvasItem's.
+ */
+/*
+ * Author:
+ * Tavmjong Bah
+ *
+ * Copyright (C) 2020 Tavmjong Bah
+ *
+ * Rewrite of SPCanvasGroup
+ *
+ * Released under GNU GPL v2+, read the file 'COPYING' for more information.
+ */
+
+#include <boost/range/adaptor/reversed.hpp>
+#include "canvas-item-group.h"
+
+constexpr bool DEBUG_LOGGING = false;
+
+namespace Inkscape {
+
+CanvasItemGroup::CanvasItemGroup(CanvasItemGroup *group)
+ : CanvasItem(group)
+{
+ _name = "CanvasItemGroup";
+ _pickable = true; // For now all groups are pickable... look into turning this off for some groups (e.g. temp).
+}
+
+CanvasItemGroup::CanvasItemGroup(CanvasItemContext *context)
+ : CanvasItem(context)
+{
+ _name = "CanvasItemGroup:Root";
+ _pickable = true; // see above
+}
+
+CanvasItemGroup::~CanvasItemGroup()
+{
+ items.clear_and_dispose([] (auto c) { delete c; });
+}
+
+void CanvasItemGroup::_update(bool propagate)
+{
+ _bounds = {};
+
+ // Update all children and calculate new bounds.
+ for (auto &item : items) {
+ item.update(propagate);
+ _bounds |= item.get_bounds();
+ }
+}
+
+void CanvasItemGroup::_mark_net_invisible()
+{
+ if (!_net_visible) {
+ return;
+ }
+ _net_visible = false;
+ _need_update = false;
+ for (auto &item : items) {
+ item._mark_net_invisible();
+ }
+ _bounds = {};
+}
+
+void CanvasItemGroup::visit_page_rects(std::function<void(Geom::Rect const &)> const &f) const
+{
+ for (auto &item : items) {
+ if (!item.is_visible()) continue;
+ item.visit_page_rects(f);
+ }
+}
+
+void CanvasItemGroup::_render(Inkscape::CanvasItemBuffer &buf) const
+{
+ for (auto &item : items) {
+ item.render(buf);
+ }
+}
+
+// Return last visible and pickable item that contains point.
+// SPCanvasGroup returned distance but it was not used.
+CanvasItem *CanvasItemGroup::pick_item(Geom::Point const &p)
+{
+ if constexpr (DEBUG_LOGGING) {
+ std::cout << "CanvasItemGroup::pick_item:" << std::endl;
+ std::cout << " PICKING: In group: " << _name << " bounds: " << _bounds << std::endl;
+ }
+
+ for (auto &item : boost::adaptors::reverse(items)) {
+ if constexpr (DEBUG_LOGGING) std::cout << " PICKING: Checking: " << item.get_name() << " bounds: " << item.get_bounds() << std::endl;
+
+ if (item.is_visible() && item.is_pickable() && item.contains(p)) {
+ if (auto group = dynamic_cast<CanvasItemGroup*>(&item)) {
+ if (auto ret = group->pick_item(p)) {
+ return ret;
+ }
+ } else {
+ return &item;
+ }
+ }
+ }
+
+ return nullptr;
+}
+
+} // namespace Inkscape
+
+/*
+ Local Variables:
+ mode:c++
+ c-file-style:"stroustrup"
+ c-file-offsets:((innamespace . 0)(inline-open . 0)(case-label . +))
+ indent-tabs-mode:nil
+ fill-column:99
+ End:
+*/
+// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=8:softtabstop=4 :