]> sigrok.org Git - pulseview.git/commitdiff
Added ViewItemOwner
authorJoel Holdsworth <redacted>
Mon, 17 Aug 2015 01:14:47 +0000 (19:14 -0600)
committerJoel Holdsworth <redacted>
Sun, 18 Oct 2015 21:32:29 +0000 (15:32 -0600)
CMakeLists.txt
pv/view/rowitemiterator.hpp [deleted file]
pv/view/tracegroup.cpp
pv/view/tracetreeitem.hpp
pv/view/tracetreeitemowner.cpp
pv/view/tracetreeitemowner.hpp
pv/view/viewitem.hpp
pv/view/viewitemiterator.hpp [new file with mode: 0644]
pv/view/viewitemowner.cpp [new file with mode: 0644]
pv/view/viewitemowner.hpp [new file with mode: 0644]

index c80a834dd0d4400cb69590c6e823d5f439c6e8e2..51170dee62255b9aa5fe6735423d945f73d83f9b 100644 (file)
@@ -219,6 +219,7 @@ set(pulseview_SOURCES
        pv/view/tracetreeitemowner.cpp
        pv/view/view.cpp
        pv/view/viewitem.cpp
+       pv/view/viewitemowner.cpp
        pv/view/viewitempaintparams.cpp
        pv/view/viewport.cpp
        pv/view/viewwidget.cpp
diff --git a/pv/view/rowitemiterator.hpp b/pv/view/rowitemiterator.hpp
deleted file mode 100644 (file)
index 9857e8a..0000000
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * This file is part of the PulseView project.
- *
- * Copyright (C) 2014 Joel Holdsworth <joel@airwebreathe.org.uk>
- *
- * 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 St, Fifth Floor, Boston, MA  02110-1301 USA
- */
-
-#ifndef PULSEVIEW_PV_VIEW_ROWITEMITERATOR_HPP
-#define PULSEVIEW_PV_VIEW_ROWITEMITERATOR_HPP
-
-#include <algorithm>
-#include <cassert>
-#include <iterator>
-#include <memory>
-#include <stack>
-#include <type_traits>
-#include <vector>
-
-#include <pv/session.hpp>
-
-namespace pv {
-namespace view {
-
-template<class Owner, class Item> class RowItemIterator
-{
-public:
-       typedef typename std::conditional<std::is_const<Owner>::value,
-               typename Owner::item_list::const_iterator,
-               typename Owner::item_list::iterator>::type child_iterator;
-
-       typedef std::shared_ptr<Item> value_type;
-       typedef ptrdiff_t difference_type;
-       typedef value_type pointer;
-       typedef value_type& reference;
-       typedef std::forward_iterator_tag iterator_category;
-
-public:
-       RowItemIterator(Owner *owner) :
-               owner_stack_({owner}) {}
-
-       RowItemIterator(Owner *owner, child_iterator iter) :
-               owner_stack_({owner}) {
-               assert(owner);
-               if (iter != owner->child_items().end())
-                       iter_stack_.push(iter);
-       }
-
-       RowItemIterator(const RowItemIterator<Owner, Item> &o) :
-               owner_stack_(o.owner_stack_),
-               iter_stack_(o.iter_stack_) {}
-
-       reference operator*() const {
-               return *iter_stack_.top();
-       }
-
-       reference operator->() const {
-               return *this;
-       }
-
-       RowItemIterator<Owner, Item>& operator++() {
-               using std::dynamic_pointer_cast;
-               using std::shared_ptr;
-
-               assert(!owner_stack_.empty());
-               assert(!iter_stack_.empty());
-
-               shared_ptr<Owner> owner(dynamic_pointer_cast<Owner>(
-                       *iter_stack_.top()));
-               if (owner && !owner->child_items().empty()) {
-                       owner_stack_.push(owner.get());
-                       iter_stack_.push(owner->child_items().begin());
-               } else {
-                       while (!iter_stack_.empty() && (++iter_stack_.top()) ==
-                               owner_stack_.top()->child_items().end()) {
-                               owner_stack_.pop();
-                               iter_stack_.pop();
-                       }
-               }
-
-               return *this;
-       }
-
-       RowItemIterator<Owner, Item> operator++(int) {
-               RowItemIterator<Owner, Item> pre = *this;
-               ++*this;
-               return pre;
-       }
-
-       bool operator==(const RowItemIterator &o) const {
-               return (iter_stack_.empty() && o.iter_stack_.empty()) || (
-                       iter_stack_.size() == o.iter_stack_.size() &&
-                       owner_stack_.top() == o.owner_stack_.top() &&
-                       iter_stack_.top() == o.iter_stack_.top());
-       }
-
-       bool operator!=(const RowItemIterator &o) const {
-               return !((const RowItemIterator&)*this == o);
-       }
-
-       void swap(RowItemIterator<Owner, Item>& other) {
-               swap(owner_stack_, other.owner_stack_);
-               swap(iter_stack_, other.iter_stack_);
-       }
-
-private:
-       std::stack<Owner*> owner_stack_;
-       std::stack<child_iterator> iter_stack_;
-};
-
-template<class Owner, class Item>
-void swap(RowItemIterator<Owner, Item>& a, RowItemIterator<Owner, Item>& b)
-{
-       a.swap(b);
-}
-
-} // namespace view
-} // namespace pv
-
-#endif // PULSEVIEW_PV_VIEW_ROWITEMITERATOR_HPP
index 87f1ff3dcab20fac2c065a5daadb0525534e56f8..140b85187efef4f2309837db938db75a6de82dce 100644 (file)
@@ -49,7 +49,7 @@ TraceGroup::~TraceGroup()
 bool TraceGroup::enabled() const
 {
        return std::any_of(child_items().begin(), child_items().end(),
-               [](const shared_ptr<TraceTreeItem> &r) { return r->enabled(); });
+               [](const shared_ptr<ViewItem> &r) { return r->enabled(); });
 }
 
 pv::Session& TraceGroup::session()
@@ -115,7 +115,7 @@ void TraceGroup::paint_label(QPainter &p, const QRect &rect, bool hover)
 QRectF TraceGroup::label_rect(const QRectF &rect) const
 {
        QRectF child_rect;
-       for (const shared_ptr<TraceTreeItem> r : child_items())
+       for (const shared_ptr<ViewItem> r : child_items())
                if (r && r->enabled())
                        child_rect = child_rect.united(r->label_rect(rect));
 
@@ -157,8 +157,7 @@ int TraceGroup::owner_visual_v_offset() const
 
 void TraceGroup::restack_items()
 {
-       vector< shared_ptr<TraceTreeItem> > items(
-               child_items().begin(), child_items().end());
+       vector<shared_ptr<TraceTreeItem>> items(trace_tree_child_items());
 
        // Sort by the centre line of the extents
        stable_sort(items.begin(), items.end(),
@@ -197,8 +196,7 @@ unsigned int TraceGroup::depth() const
 
 void TraceGroup::ungroup()
 {
-       const vector< shared_ptr<TraceTreeItem> > items(
-               child_items().begin(), child_items().end());
+       const vector<shared_ptr<TraceTreeItem>> items(trace_tree_child_items());
        clear_child_items();
 
        for (shared_ptr<TraceTreeItem> r : items)
index 5e60ffcb2e568f959bff3f4ab7f6d5470b1799f7..8a72f6ebd59217e0ec7522cc514205b09d69ea64 100644 (file)
@@ -46,6 +46,11 @@ public:
         */
        TraceTreeItem();
 
+       /**
+        * Gets the owner this item in the view item hierachy.
+        */
+       TraceTreeItemOwner* owner() const;
+
        /**
         * Gets the vertical layout offset of this signal.
         */
@@ -77,11 +82,6 @@ public:
         */
        void animate_to_layout_v_offset();
 
-       /**
-        * Gets the owner this trace in the view trace hierachy.
-        */
-       pv::view::TraceTreeItemOwner* owner() const;
-
        /**
         * Sets the owner this trace in the view trace hierachy.
         * @param The new owner of the trace.
@@ -112,7 +112,7 @@ public:
        virtual std::pair<int, int> v_extents() const = 0;
 
 protected:
-       pv::view::TraceTreeItemOwner *owner_;
+       TraceTreeItemOwner *owner_;
 
        int layout_v_offset_;
        int visual_v_offset_;
index 93b966b4aad99517cb5e13b4e3f206968263e719..af11ad2688b8d6f61c670d5398fd60ed470a4cf0 100644 (file)
@@ -31,26 +31,41 @@ using std::min;
 using std::pair;
 using std::set;
 using std::shared_ptr;
+using std::static_pointer_cast;
 using std::vector;
 
 namespace pv {
 namespace view {
 
-vector< shared_ptr<TraceTreeItem> >& TraceTreeItemOwner::child_items()
+vector< shared_ptr<ViewItem> >& TraceTreeItemOwner::child_items()
 {
        return items_;
 }
 
-const vector< shared_ptr<TraceTreeItem> >& TraceTreeItemOwner::child_items() const
+const vector< shared_ptr<ViewItem> >& TraceTreeItemOwner::child_items() const
 {
        return items_;
 }
 
-void TraceTreeItemOwner::clear_child_items()
+vector< std::shared_ptr<TraceTreeItem> >
+TraceTreeItemOwner::trace_tree_child_items() const
 {
+       vector< shared_ptr<TraceTreeItem> > items;
        for (auto &i : items_) {
-               assert(i->owner() == this);
-               i->set_owner(nullptr);
+               assert(dynamic_pointer_cast<TraceTreeItem>(i));
+               const shared_ptr<TraceTreeItem> t(
+                       static_pointer_cast<TraceTreeItem>(i));
+               items.push_back(t);
+       }
+
+       return items;
+}
+
+void TraceTreeItemOwner::clear_child_items()
+{
+       for (auto &t : trace_tree_child_items()) {
+               assert(t->owner() == this);
+               t->set_owner(nullptr);
        }
        items_.clear();
 }
@@ -75,37 +90,17 @@ void TraceTreeItemOwner::remove_child_item(std::shared_ptr<TraceTreeItem> item)
        extents_changed(true, true);
 }
 
-TraceTreeItemOwner::iterator TraceTreeItemOwner::begin()
-{
-       return iterator(this, items_.begin());
-}
-
-TraceTreeItemOwner::iterator TraceTreeItemOwner::end()
-{
-       return iterator(this);
-}
-
-TraceTreeItemOwner::const_iterator TraceTreeItemOwner::begin() const
-{
-       return const_iterator(this, items_.cbegin());
-}
-
-TraceTreeItemOwner::const_iterator TraceTreeItemOwner::end() const
-{
-       return const_iterator(this);
-}
-
 pair<int, int> TraceTreeItemOwner::v_extents() const
 {
        pair<int, int> extents(INT_MAX, INT_MIN);
 
-       for (const shared_ptr<TraceTreeItem> r : child_items()) {
-               assert(r);
-               if (!r->enabled())
+       for (const shared_ptr<TraceTreeItem> t : trace_tree_child_items()) {
+               assert(t);
+               if (!t->enabled())
                        continue;
 
-               const int child_offset = r->layout_v_offset();
-               const pair<int, int> child_extents = r->v_extents();
+               const int child_offset = t->layout_v_offset();
+               const pair<int, int> child_extents = t->v_extents();
                extents.first = min(child_extents.first + child_offset,
                        extents.first);
                extents.second = max(child_extents.second + child_offset,
index b26b1e7e46d3e81846f96fb5b2682e19c48f857a..025c34edad69f6f421d9fc9264f60e46f81f7e7a 100644 (file)
 #ifndef PULSEVIEW_PV_VIEW_TRACETREEITEMOWNER_HPP
 #define PULSEVIEW_PV_VIEW_TRACETREEITEMOWNER_HPP
 
-#include <memory>
-#include <vector>
-
-#include "rowitemiterator.hpp"
+#include "viewitemowner.hpp"
+#include "tracetreeitem.hpp"
 
 namespace pv {
 
@@ -35,24 +33,9 @@ namespace view {
 class TraceTreeItem;
 class View;
 
-class TraceTreeItemOwner
+class TraceTreeItemOwner : public ViewItemOwner
 {
 public:
-       typedef std::vector< std::shared_ptr<TraceTreeItem> > item_list;
-       typedef RowItemIterator<TraceTreeItemOwner, TraceTreeItem> iterator;
-       typedef RowItemIterator<const TraceTreeItemOwner, TraceTreeItem> const_iterator;
-
-public:
-       /**
-        * Returns the session of the onwer.
-        */
-       virtual pv::Session& session() = 0;
-
-       /**
-        * Returns the session of the owner.
-        */
-       virtual const pv::Session& session() const = 0;
-
        /**
         * Returns the view of the owner.
         */
@@ -65,6 +48,16 @@ public:
 
        virtual int owner_visual_v_offset() const = 0;
 
+       /**
+        * Returns the session of the onwer.
+        */
+       virtual pv::Session& session() = 0;
+
+       /**
+        * Returns the session of the owner.
+        */
+       virtual const pv::Session& session() const = 0;
+
        /**
         * Returns the number of nested parents that this row item owner has.
         */
@@ -80,6 +73,12 @@ public:
         */
        virtual const item_list& child_items() const;
 
+       /**
+        * Returns a list of row items owned by this object.
+        */
+       std::vector< std::shared_ptr<TraceTreeItem> >
+       trace_tree_child_items() const;
+
        /**
         * Clears the list of child items.
         */
@@ -95,43 +94,7 @@ public:
         */
        void remove_child_item(std::shared_ptr<TraceTreeItem> item);
 
-       /**
-        * Returns a depth-first iterator at the beginning of the child TraceTreeItem
-        * tree.
-        */
-       iterator begin();
-
-       /**
-        * Returns a depth-first iterator at the end of the child TraceTreeItem tree.
-        */
-       iterator end();
-
-       /**
-        * Returns a constant depth-first iterator at the beginning of the
-        * child TraceTreeItem tree.
-        */
-       const_iterator begin() const;
-
-       /**
-        * Returns a constant depth-first iterator at the end of the child
-        * TraceTreeItem tree.
-        */
-       const_iterator end() const;
-
-       /**
-        * Creates a list of decendant signals filtered by type.
-        */
-       template<class T>
-       std::vector< std::shared_ptr<T> > list_by_type() {
-               std::vector< std::shared_ptr<T> > items;
-               for (const auto &r : *this) {
-                       std::shared_ptr<T> p = std::dynamic_pointer_cast<T>(r);
-                       if (p)
-                               items.push_back(p);
-               }
-
-               return items;
-       }
+       virtual void restack_items();
 
        /**
         * Computes the vertical extents of the contents of this row item owner.
@@ -139,15 +102,10 @@ public:
         */
        std::pair<int, int> v_extents() const;
 
-       virtual void restack_items();
-
 public:
        virtual void row_item_appearance_changed(bool label, bool content) = 0;
 
        virtual void extents_changed(bool horz, bool vert) = 0;
-
-private:
-       item_list items_;
 };
 
 } // view
index 5b80c4e86efdb8fe3e9a95320bcd3aa232cd65a4..dd3d2aa0c2c61a4969a53c6a5fc899cb5c7e802b 100644 (file)
@@ -39,6 +39,8 @@ class Popup;
 
 namespace view {
 
+class ViewItemOwner;
+
 class ViewItem : public QObject
 {
        Q_OBJECT
diff --git a/pv/view/viewitemiterator.hpp b/pv/view/viewitemiterator.hpp
new file mode 100644 (file)
index 0000000..179de38
--- /dev/null
@@ -0,0 +1,132 @@
+/*
+ * This file is part of the PulseView project.
+ *
+ * Copyright (C) 2014 Joel Holdsworth <joel@airwebreathe.org.uk>
+ *
+ * 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 St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#ifndef PULSEVIEW_PV_VIEW_VIEWITEMITERATOR_HPP
+#define PULSEVIEW_PV_VIEW_VIEWITEMITERATOR_HPP
+
+#include <algorithm>
+#include <cassert>
+#include <iterator>
+#include <memory>
+#include <stack>
+#include <type_traits>
+#include <vector>
+
+#include <pv/session.hpp>
+
+namespace pv {
+namespace view {
+
+template<class Owner, class Item> class ViewItemIterator
+{
+public:
+       typedef typename std::conditional<std::is_const<Owner>::value,
+               typename Owner::item_list::const_iterator,
+               typename Owner::item_list::iterator>::type child_iterator;
+
+       typedef std::shared_ptr<Item> value_type;
+       typedef ptrdiff_t difference_type;
+       typedef value_type pointer;
+       typedef value_type& reference;
+       typedef std::forward_iterator_tag iterator_category;
+
+public:
+       ViewItemIterator(Owner *owner) :
+               owner_stack_({owner}) {}
+
+       ViewItemIterator(Owner *owner, child_iterator iter) :
+               owner_stack_({owner}) {
+               assert(owner);
+               if (iter != owner->child_items().end())
+                       iter_stack_.push(iter);
+       }
+
+       ViewItemIterator(const ViewItemIterator<Owner, Item> &o) :
+               owner_stack_(o.owner_stack_),
+               iter_stack_(o.iter_stack_) {}
+
+       reference operator*() const {
+               return *iter_stack_.top();
+       }
+
+       reference operator->() const {
+               return *this;
+       }
+
+       ViewItemIterator<Owner, Item>& operator++() {
+               using std::dynamic_pointer_cast;
+               using std::shared_ptr;
+
+               assert(!owner_stack_.empty());
+               assert(!iter_stack_.empty());
+
+               shared_ptr<Owner> owner(dynamic_pointer_cast<Owner>(
+                       *iter_stack_.top()));
+               if (owner && !owner->child_items().empty()) {
+                       owner_stack_.push(owner.get());
+                       iter_stack_.push(owner->child_items().begin());
+               } else {
+                       while (!iter_stack_.empty() && (++iter_stack_.top()) ==
+                               owner_stack_.top()->child_items().end()) {
+                               owner_stack_.pop();
+                               iter_stack_.pop();
+                       }
+               }
+
+               return *this;
+       }
+
+       ViewItemIterator<Owner, Item> operator++(int) {
+               ViewItemIterator<Owner, Item> pre = *this;
+               ++*this;
+               return pre;
+       }
+
+       bool operator==(const ViewItemIterator &o) const {
+               return (iter_stack_.empty() && o.iter_stack_.empty()) || (
+                       iter_stack_.size() == o.iter_stack_.size() &&
+                       owner_stack_.top() == o.owner_stack_.top() &&
+                       iter_stack_.top() == o.iter_stack_.top());
+       }
+
+       bool operator!=(const ViewItemIterator &o) const {
+               return !((const ViewItemIterator&)*this == o);
+       }
+
+       void swap(ViewItemIterator<Owner, Item>& other) {
+               swap(owner_stack_, other.owner_stack_);
+               swap(iter_stack_, other.iter_stack_);
+       }
+
+private:
+       std::stack<Owner*> owner_stack_;
+       std::stack<child_iterator> iter_stack_;
+};
+
+template<class Owner, class Item>
+void swap(ViewItemIterator<Owner, Item>& a, ViewItemIterator<Owner, Item>& b)
+{
+       a.swap(b);
+}
+
+} // namespace view
+} // namespace pv
+
+#endif // PULSEVIEW_PV_VIEW_VIEWITEMITERATOR_HPP
diff --git a/pv/view/viewitemowner.cpp b/pv/view/viewitemowner.cpp
new file mode 100644 (file)
index 0000000..8a70478
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * This file is part of the PulseView project.
+ *
+ * Copyright (C) 2014 Joel Holdsworth <joel@airwebreathe.org.uk>
+ *
+ * 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 St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#include <cassert>
+
+#include "tracetreeitem.hpp"
+#include "tracetreeitemowner.hpp"
+#include "trace.hpp"
+
+using std::dynamic_pointer_cast;
+using std::max;
+using std::make_pair;
+using std::min;
+using std::pair;
+using std::set;
+using std::shared_ptr;
+using std::vector;
+
+namespace pv {
+namespace view {
+
+ViewItemOwner::iterator ViewItemOwner::begin()
+{
+       return iterator(this, items_.begin());
+}
+
+ViewItemOwner::iterator ViewItemOwner::end()
+{
+       return iterator(this);
+}
+
+ViewItemOwner::const_iterator ViewItemOwner::begin() const
+{
+       return const_iterator(this, items_.cbegin());
+}
+
+ViewItemOwner::const_iterator ViewItemOwner::end() const
+{
+       return const_iterator(this);
+}
+
+} // view
+} // pv
diff --git a/pv/view/viewitemowner.hpp b/pv/view/viewitemowner.hpp
new file mode 100644 (file)
index 0000000..60c8507
--- /dev/null
@@ -0,0 +1,101 @@
+/*
+ * This file is part of the PulseView project.
+ *
+ * Copyright (C) 2014 Joel Holdsworth <joel@airwebreathe.org.uk>
+ *
+ * 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 St, Fifth Floor, Boston, MA  02110-1301 USA
+ */
+
+#ifndef PULSEVIEW_PV_VIEW_VIEWITEMOWNER_HPP
+#define PULSEVIEW_PV_VIEW_VIEWITEMOWNER_HPP
+
+#include <memory>
+#include <vector>
+
+#include "viewitemiterator.hpp"
+
+namespace pv {
+
+class Session;
+
+namespace view {
+
+class ViewItem;
+class View;
+
+class ViewItemOwner
+{
+public:
+       typedef std::vector< std::shared_ptr<ViewItem> > item_list;
+       typedef ViewItemIterator<ViewItemOwner, ViewItem> iterator;
+       typedef ViewItemIterator<const ViewItemOwner, ViewItem> const_iterator;
+
+public:
+       /**
+        * Returns a list of row items owned by this object.
+        */
+       virtual item_list& child_items() = 0;
+
+       /**
+        * Returns a list of row items owned by this object.
+        */
+       virtual const item_list& child_items() const = 0;
+
+       /**
+        * Returns a depth-first iterator at the beginning of the child ViewItem
+        * tree.
+        */
+       iterator begin();
+
+       /**
+        * Returns a depth-first iterator at the end of the child ViewItem tree.
+        */
+       iterator end();
+
+       /**
+        * Returns a constant depth-first iterator at the beginning of the
+        * child ViewItem tree.
+        */
+       const_iterator begin() const;
+
+       /**
+        * Returns a constant depth-first iterator at the end of the child
+        * ViewItem tree.
+        */
+       const_iterator end() const;
+
+       /**
+        * Creates a list of decendant signals filtered by type.
+        */
+       template<class T>
+       std::vector< std::shared_ptr<T> > list_by_type() {
+               std::vector< std::shared_ptr<T> > items;
+               for (const auto &r : *this) {
+                       std::shared_ptr<T> p = std::dynamic_pointer_cast<T>(r);
+                       if (p)
+                               items.push_back(p);
+               }
+
+               return items;
+       }
+
+protected:
+       item_list items_;
+};
+
+} // view
+} // pv
+
+#endif // PULSEVIEW_PV_VIEW_VIEWITEMOWNER_HPP