pv/view/header.cpp
pv/view/marginwidget.cpp
pv/view/logicsignal.cpp
- pv/view/rowitem.cpp
- pv/view/rowitemowner.cpp
pv/view/ruler.cpp
pv/view/signal.cpp
pv/view/timeitem.cpp
pv/view/trace.cpp
pv/view/tracegroup.cpp
pv/view/tracepalette.cpp
+ pv/view/tracetreeitem.cpp
+ pv/view/tracetreeitemowner.cpp
pv/view/view.cpp
pv/view/viewitem.cpp
pv/view/viewitempaintparams.cpp
pv/view/timemarker.hpp
pv/view/trace.hpp
pv/view/tracegroup.hpp
+ pv/view/tracetreeitem.hpp
pv/view/view.hpp
pv/view/viewitem.hpp
pv/view/viewport.hpp
const int Header::Padding = 12;
const int Header::BaselineOffset = 5;
-static bool item_selected(shared_ptr<RowItem> r)
+static bool item_selected(shared_ptr<TraceTreeItem> r)
{
return r->selected();
}
for (auto &i : view_)
if (i->enabled() && i->label_rect(r).contains(pt))
return i;
- return shared_ptr<RowItem>();
+ return shared_ptr<TraceTreeItem>();
}
void Header::paintEvent(QPaintEvent*)
// would be clipped away.
const QRect rect(0, 0, width() - BaselineOffset, height());
- vector< shared_ptr<RowItem> > row_items(
+ vector< shared_ptr<TraceTreeItem> > items(
view_.begin(), view_.end());
- stable_sort(row_items.begin(), row_items.end(),
- [](const shared_ptr<RowItem> &a, const shared_ptr<RowItem> &b) {
+ stable_sort(items.begin(), items.end(),
+ [](const shared_ptr<TraceTreeItem> &a, const shared_ptr<TraceTreeItem> &b) {
return a->visual_v_offset() < b->visual_v_offset(); });
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
- for (const shared_ptr<RowItem> r : row_items)
+ for (const shared_ptr<TraceTreeItem> r : items)
{
assert(r);
void Header::on_group()
{
- vector< shared_ptr<RowItem> > selected_items(
+ vector< shared_ptr<TraceTreeItem> > selected_items(
make_filter_iterator(item_selected, view_.begin(), view_.end()),
make_filter_iterator(item_selected, view_.end(), view_.end()));
stable_sort(selected_items.begin(), selected_items.end(),
- [](const shared_ptr<RowItem> &a, const shared_ptr<RowItem> &b) {
+ [](const shared_ptr<TraceTreeItem> &a, const shared_ptr<TraceTreeItem> &b) {
return a->visual_v_offset() < b->visual_v_offset(); });
shared_ptr<TraceGroup> group(new TraceGroup());
- shared_ptr<RowItem> mouse_down_item(
- std::dynamic_pointer_cast<RowItem>(mouse_down_item_));
- shared_ptr<RowItem> focus_item(
+ shared_ptr<TraceTreeItem> mouse_down_item(
+ std::dynamic_pointer_cast<TraceTreeItem>(mouse_down_item_));
+ shared_ptr<TraceTreeItem> focus_item(
mouse_down_item ? mouse_down_item : selected_items.front());
assert(focus_item);
focus_item->v_extents().first);
for (size_t i = 0; i < selected_items.size(); i++) {
- const shared_ptr<RowItem> &r = selected_items[i];
+ const shared_ptr<TraceTreeItem> &r = selected_items[i];
assert(r->owner());
r->owner()->remove_child_item(r);
group->add_child_item(r);
bool restart;
do {
restart = false;
- for (const shared_ptr<RowItem> r : view_) {
+ for (const shared_ptr<TraceTreeItem> r : view_) {
const shared_ptr<TraceGroup> tg =
dynamic_pointer_cast<TraceGroup>(r);
if (tg && tg->selected()) {
namespace pv {
namespace view {
-class RowItem;
+class TraceTreeItem;
class View;
class ViewItem;
+++ /dev/null
-/*
- * This file is part of the PulseView project.
- *
- * Copyright (C) 2013 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 <assert.h>
-
-#include "view.hpp"
-
-#include "rowitem.hpp"
-
-namespace pv {
-namespace view {
-
-RowItem::RowItem() :
- owner_(nullptr),
- layout_v_offset_(0),
- visual_v_offset_(0),
- v_offset_animation_(this, "visual_v_offset")
-{
-}
-
-int RowItem::layout_v_offset() const
-{
- return layout_v_offset_;
-}
-
-void RowItem::set_layout_v_offset(int v_offset)
-{
- if (layout_v_offset_ == v_offset)
- return;
-
- layout_v_offset_ = v_offset;
-
- if (owner_)
- owner_->extents_changed(false, true);
-}
-
-int RowItem::visual_v_offset() const
-{
- return visual_v_offset_;
-}
-
-void RowItem::set_visual_v_offset(int v_offset)
-{
- visual_v_offset_ = v_offset;
-
- if (owner_)
- owner_->row_item_appearance_changed(true, true);
-}
-
-void RowItem::force_to_v_offset(int v_offset)
-{
- v_offset_animation_.stop();
- layout_v_offset_ = visual_v_offset_ = v_offset;
-
- if (owner_) {
- owner_->row_item_appearance_changed(true, true);
- owner_->extents_changed(false, true);
- }
-}
-
-void RowItem::animate_to_layout_v_offset()
-{
- if (visual_v_offset_ == layout_v_offset_ ||
- (v_offset_animation_.endValue() == layout_v_offset_ &&
- v_offset_animation_.state() == QAbstractAnimation::Running))
- return;
-
- v_offset_animation_.setDuration(100);
- v_offset_animation_.setStartValue(visual_v_offset_);
- v_offset_animation_.setEndValue(layout_v_offset_);
- v_offset_animation_.setEasingCurve(QEasingCurve::OutQuad);
- v_offset_animation_.start();
-}
-
-RowItemOwner* RowItem::owner() const
-{
- return owner_;
-}
-
-void RowItem::set_owner(RowItemOwner *owner)
-{
- assert(owner_ || owner);
- v_offset_animation_.stop();
-
- if (owner_) {
- const int owner_offset = owner_->owner_visual_v_offset();
- layout_v_offset_ += owner_offset;
- visual_v_offset_ += owner_offset;
- }
-
- owner_ = owner;
-
- if (owner_) {
- const int owner_offset = owner_->owner_visual_v_offset();
- layout_v_offset_ -= owner_offset;
- visual_v_offset_ -= owner_offset;
- }
-}
-
-int RowItem::get_visual_y() const
-{
- assert(owner_);
- return visual_v_offset_ + owner_->owner_visual_v_offset();
-}
-
-void RowItem::drag_by(const QPoint &delta)
-{
- force_to_v_offset(drag_point_.y() + delta.y() -
- owner_->owner_visual_v_offset());
-}
-
-QPoint RowItem::point(const QRect &rect) const
-{
- return QPoint(rect.right(), get_visual_y());
-}
-
-void RowItem::hover_point_changed()
-{
-}
-
-} // namespace view
-} // namespace pv
#ifndef PULSEVIEW_PV_VIEW_ROWITEM_HPP
#define PULSEVIEW_PV_VIEW_ROWITEM_HPP
-#include <memory>
-
-#include <QPropertyAnimation>
-
#include "viewitem.hpp"
namespace pv {
namespace view {
-class RowItemOwner;
-
-class RowItem : public ViewItem,
- public std::enable_shared_from_this<pv::view::RowItem>
+class RowItem : public ViewItem
{
Q_OBJECT
- Q_PROPERTY(int visual_v_offset
- READ visual_v_offset
- WRITE set_visual_v_offset)
-
-public:
- /**
- * Constructor.
- */
- RowItem();
-
- /**
- * Gets the vertical layout offset of this signal.
- */
- int layout_v_offset() const;
-
- /**
- * Sets the vertical layout offset of this signal.
- */
- void set_layout_v_offset(int v_offset);
-
- /**
- * Gets the vertical visual offset of this signal.
- */
- int visual_v_offset() const;
-
- /**
- * Sets the vertical visual offset of this signal.
- */
- void set_visual_v_offset(int v_offset);
-
- /**
- * Sets the visual and layout offset of this signal.
- */
- void force_to_v_offset(int v_offset);
-
- /**
- * Begins an animation that will animate the visual offset toward
- * the layout offset.
- */
- void animate_to_layout_v_offset();
-
- /**
- * Gets the owner this trace in the view trace hierachy.
- */
- pv::view::RowItemOwner* owner() const;
-
- /**
- * Sets the owner this trace in the view trace hierachy.
- * @param The new owner of the trace.
- */
- void set_owner(pv::view::RowItemOwner *owner);
-
- /**
- * Gets the visual y-offset of the axis.
- */
- int get_visual_y() const;
-
- /**
- * Drags the item to a delta relative to the drag point.
- * @param delta the offset from the drag point.
- */
- void drag_by(const QPoint &delta);
-
- /**
- * Gets the arrow-tip point of the row item marker.
- * @param rect the rectangle of the header area.
- */
- QPoint point(const QRect &rect) const;
-
- /**
- * Computes the vertical extents of the contents of this row item.
- * @return A pair containing the minimum and maximum y-values.
- */
- virtual std::pair<int, int> v_extents() const = 0;
-
-public:
- virtual void hover_point_changed();
-
-protected:
- pv::view::RowItemOwner *owner_;
-
- int layout_v_offset_;
- int visual_v_offset_;
-
-private:
- QPropertyAnimation v_offset_animation_;
};
} // namespace view
+++ /dev/null
-/*
- * 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 "rowitem.hpp"
-#include "rowitemowner.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 {
-
-vector< shared_ptr<RowItem> >& RowItemOwner::child_items()
-{
- return items_;
-}
-
-const vector< shared_ptr<RowItem> >& RowItemOwner::child_items() const
-{
- return items_;
-}
-
-void RowItemOwner::clear_child_items()
-{
- for (auto &i : items_) {
- assert(i->owner() == this);
- i->set_owner(nullptr);
- }
- items_.clear();
-}
-
-void RowItemOwner::add_child_item(std::shared_ptr<RowItem> item)
-{
- assert(!item->owner());
- item->set_owner(this);
- items_.push_back(item);
-
- extents_changed(true, true);
-}
-
-void RowItemOwner::remove_child_item(std::shared_ptr<RowItem> item)
-{
- assert(item->owner() == this);
- item->set_owner(nullptr);
- auto iter = std::find(items_.begin(), items_.end(), item);
- assert(iter != items_.end());
- items_.erase(iter);
-
- extents_changed(true, true);
-}
-
-RowItemOwner::iterator RowItemOwner::begin()
-{
- return iterator(this, items_.begin());
-}
-
-RowItemOwner::iterator RowItemOwner::end()
-{
- return iterator(this);
-}
-
-RowItemOwner::const_iterator RowItemOwner::begin() const
-{
- return const_iterator(this, items_.cbegin());
-}
-
-RowItemOwner::const_iterator RowItemOwner::end() const
-{
- return const_iterator(this);
-}
-
-set< RowItemOwner* > RowItemOwner::list_row_item_owners()
-{
- set< RowItemOwner* > owners;
- for (const auto &r : *this)
- owners.insert(r->owner());
- return owners;
-}
-
-template<class T>
-set< shared_ptr<T> > RowItemOwner::list_by_type()
-{
- set< shared_ptr<T> > items;
- for (const auto &r : *this) {
- shared_ptr<T> p = dynamic_pointer_cast<T>(r);
- if (p)
- items.insert(p);
- }
-
- return items;
-}
-
-template set< shared_ptr<Trace> > RowItemOwner::list_by_type();
-
-pair<int, int> RowItemOwner::v_extents() const
-{
- pair<int, int> extents(INT_MAX, INT_MIN);
-
- for (const shared_ptr<RowItem> r : child_items()) {
- assert(r);
- if (!r->enabled())
- continue;
-
- const int child_offset = r->layout_v_offset();
- const pair<int, int> child_extents = r->v_extents();
- extents.first = min(child_extents.first + child_offset,
- extents.first);
- extents.second = max(child_extents.second + child_offset,
- extents.second);
- }
-
- return extents;
-}
-
-void RowItemOwner::restack_items()
-{
-}
-
-} // view
-} // pv
+++ /dev/null
-/*
- * 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_ROWITEMOWNER_HPP
-#define PULSEVIEW_PV_VIEW_ROWITEMOWNER_HPP
-
-#include <memory>
-#include <vector>
-
-#include "rowitemiterator.hpp"
-
-namespace pv {
-
-class Session;
-
-namespace view {
-
-class RowItem;
-class View;
-
-class RowItemOwner
-{
-public:
- typedef std::vector< std::shared_ptr<RowItem> > item_list;
- typedef RowItemIterator<RowItemOwner, RowItem> iterator;
- typedef RowItemIterator<const RowItemOwner, RowItem> 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.
- */
- virtual pv::view::View* view() = 0;
-
- /**
- * Returns the view of the owner.
- */
- virtual const pv::view::View* view() const = 0;
-
- virtual int owner_visual_v_offset() const = 0;
-
- /**
- * Returns the number of nested parents that this row item owner has.
- */
- virtual unsigned int depth() const = 0;
-
- /**
- * Returns a list of row items owned by this object.
- */
- virtual item_list& child_items();
-
- /**
- * Returns a list of row items owned by this object.
- */
- virtual const item_list& child_items() const;
-
- /**
- * Clears the list of child items.
- */
- void clear_child_items();
-
- /**
- * Adds a child item to this object.
- */
- void add_child_item(std::shared_ptr<RowItem> item);
-
- /**
- * Removes a child item from this object.
- */
- void remove_child_item(std::shared_ptr<RowItem> item);
-
- /**
- * Returns a depth-first iterator at the beginning of the child RowItem
- * tree.
- */
- iterator begin();
-
- /**
- * Returns a depth-first iterator at the end of the child RowItem tree.
- */
- iterator end();
-
- /**
- * Returns a constant depth-first iterator at the beginning of the
- * child RowItem tree.
- */
- const_iterator begin() const;
-
- /**
- * Returns a constant depth-first iterator at the end of the child
- * RowItem tree.
- */
- const_iterator end() const;
-
- /**
- * Makes a list of row item owners of all the row items that are
- * decendants of this item.
- */
- std::set< RowItemOwner* > list_row_item_owners();
-
- /**
- * Creates a list of decendant signals filtered by type.
- */
- template<class T>
- std::set< std::shared_ptr<T> > list_by_type();
-
- /**
- * Computes the vertical extents of the contents of this row item owner.
- * @return A pair containing the minimum and maximum y-values.
- */
- 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
-} // pv
-
-#endif // PULSEVIEW_PV_VIEW_ROWITEMOWNER_HPP
#include <stdint.h>
-#include "rowitem.hpp"
+#include "tracetreeitem.hpp"
class QFormLayout;
namespace view {
-class Trace : public RowItem
+class Trace : public TraceTreeItem
{
Q_OBJECT
bool TraceGroup::enabled() const
{
return std::any_of(child_items().begin(), child_items().end(),
- [](const shared_ptr<RowItem> &r) { return r->enabled(); });
+ [](const shared_ptr<TraceTreeItem> &r) { return r->enabled(); });
}
pv::Session& TraceGroup::session()
pair<int, int> TraceGroup::v_extents() const
{
- return RowItemOwner::v_extents();
+ return TraceTreeItemOwner::v_extents();
}
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<RowItem> r : child_items())
+ for (const shared_ptr<TraceTreeItem> r : child_items())
if (r && r->enabled())
child_rect = child_rect.united(r->label_rect(rect));
void TraceGroup::restack_items()
{
- vector< shared_ptr<RowItem> > items(
+ vector< shared_ptr<TraceTreeItem> > items(
child_items().begin(), child_items().end());
// Sort by the centre line of the extents
stable_sort(items.begin(), items.end(),
- [](const shared_ptr<RowItem> &a, const shared_ptr<RowItem> &b) {
+ [](const shared_ptr<TraceTreeItem> &a, const shared_ptr<TraceTreeItem> &b) {
const auto aext = a->v_extents();
const auto bext = b->v_extents();
return a->layout_v_offset() +
});
int total_offset = 0;
- for (shared_ptr<RowItem> r : items) {
+ for (shared_ptr<TraceTreeItem> r : items) {
const pair<int, int> extents = r->v_extents();
if (extents.first == 0 && extents.second == 0)
continue;
void TraceGroup::ungroup()
{
- const vector< shared_ptr<RowItem> > items(
+ const vector< shared_ptr<TraceTreeItem> > items(
child_items().begin(), child_items().end());
clear_child_items();
- for (shared_ptr<RowItem> r : items)
+ for (shared_ptr<TraceTreeItem> r : items)
owner_->add_child_item(r);
owner_->remove_child_item(shared_from_this());
#ifndef PULSEVIEW_PV_VIEW_TRACEGROUP_HPP
#define PULSEVIEW_PV_VIEW_TRACEGROUP_HPP
-#include "rowitem.hpp"
-#include "rowitemowner.hpp"
+#include "tracetreeitem.hpp"
+#include "tracetreeitemowner.hpp"
namespace pv {
namespace view {
-class TraceGroup : public RowItem, public RowItemOwner
+class TraceGroup : public TraceTreeItem, public TraceTreeItemOwner
{
Q_OBJECT
--- /dev/null
+/*
+ * This file is part of the PulseView project.
+ *
+ * Copyright (C) 2013 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 <assert.h>
+
+#include "view.hpp"
+
+#include "tracetreeitem.hpp"
+
+namespace pv {
+namespace view {
+
+TraceTreeItem::TraceTreeItem() :
+ owner_(nullptr),
+ layout_v_offset_(0),
+ visual_v_offset_(0),
+ v_offset_animation_(this, "visual_v_offset")
+{
+}
+
+int TraceTreeItem::layout_v_offset() const
+{
+ return layout_v_offset_;
+}
+
+void TraceTreeItem::set_layout_v_offset(int v_offset)
+{
+ if (layout_v_offset_ == v_offset)
+ return;
+
+ layout_v_offset_ = v_offset;
+
+ if (owner_)
+ owner_->extents_changed(false, true);
+}
+
+int TraceTreeItem::visual_v_offset() const
+{
+ return visual_v_offset_;
+}
+
+void TraceTreeItem::set_visual_v_offset(int v_offset)
+{
+ visual_v_offset_ = v_offset;
+
+ if (owner_)
+ owner_->row_item_appearance_changed(true, true);
+}
+
+void TraceTreeItem::force_to_v_offset(int v_offset)
+{
+ v_offset_animation_.stop();
+ layout_v_offset_ = visual_v_offset_ = v_offset;
+
+ if (owner_) {
+ owner_->row_item_appearance_changed(true, true);
+ owner_->extents_changed(false, true);
+ }
+}
+
+void TraceTreeItem::animate_to_layout_v_offset()
+{
+ if (visual_v_offset_ == layout_v_offset_ ||
+ (v_offset_animation_.endValue() == layout_v_offset_ &&
+ v_offset_animation_.state() == QAbstractAnimation::Running))
+ return;
+
+ v_offset_animation_.setDuration(100);
+ v_offset_animation_.setStartValue(visual_v_offset_);
+ v_offset_animation_.setEndValue(layout_v_offset_);
+ v_offset_animation_.setEasingCurve(QEasingCurve::OutQuad);
+ v_offset_animation_.start();
+}
+
+TraceTreeItemOwner* TraceTreeItem::owner() const
+{
+ return owner_;
+}
+
+void TraceTreeItem::set_owner(TraceTreeItemOwner *owner)
+{
+ assert(owner_ || owner);
+ v_offset_animation_.stop();
+
+ if (owner_) {
+ const int owner_offset = owner_->owner_visual_v_offset();
+ layout_v_offset_ += owner_offset;
+ visual_v_offset_ += owner_offset;
+ }
+
+ owner_ = owner;
+
+ if (owner_) {
+ const int owner_offset = owner_->owner_visual_v_offset();
+ layout_v_offset_ -= owner_offset;
+ visual_v_offset_ -= owner_offset;
+ }
+}
+
+int TraceTreeItem::get_visual_y() const
+{
+ assert(owner_);
+ return visual_v_offset_ + owner_->owner_visual_v_offset();
+}
+
+void TraceTreeItem::drag_by(const QPoint &delta)
+{
+ force_to_v_offset(drag_point_.y() + delta.y() -
+ owner_->owner_visual_v_offset());
+}
+
+QPoint TraceTreeItem::point(const QRect &rect) const
+{
+ return QPoint(rect.right(), get_visual_y());
+}
+
+void TraceTreeItem::hover_point_changed()
+{
+}
+
+} // namespace view
+} // namespace pv
--- /dev/null
+/*
+ * This file is part of the PulseView project.
+ *
+ * Copyright (C) 2013 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_TRACETREEITEM_HPP
+#define PULSEVIEW_PV_VIEW_TRACETREEITEM_HPP
+
+#include <memory>
+
+#include <QPropertyAnimation>
+
+#include "rowitem.hpp"
+
+namespace pv {
+namespace view {
+
+class TraceTreeItemOwner;
+
+class TraceTreeItem : public RowItem,
+ public std::enable_shared_from_this<pv::view::TraceTreeItem>
+{
+ Q_OBJECT
+ Q_PROPERTY(int visual_v_offset
+ READ visual_v_offset
+ WRITE set_visual_v_offset)
+
+public:
+ /**
+ * Constructor.
+ */
+ TraceTreeItem();
+
+ /**
+ * Gets the vertical layout offset of this signal.
+ */
+ int layout_v_offset() const;
+
+ /**
+ * Sets the vertical layout offset of this signal.
+ */
+ void set_layout_v_offset(int v_offset);
+
+ /**
+ * Gets the vertical visual offset of this signal.
+ */
+ int visual_v_offset() const;
+
+ /**
+ * Sets the vertical visual offset of this signal.
+ */
+ void set_visual_v_offset(int v_offset);
+
+ /**
+ * Sets the visual and layout offset of this signal.
+ */
+ void force_to_v_offset(int v_offset);
+
+ /**
+ * Begins an animation that will animate the visual offset toward
+ * the layout offset.
+ */
+ 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.
+ */
+ void set_owner(pv::view::TraceTreeItemOwner *owner);
+
+ /**
+ * Gets the visual y-offset of the axis.
+ */
+ int get_visual_y() const;
+
+ /**
+ * Drags the item to a delta relative to the drag point.
+ * @param delta the offset from the drag point.
+ */
+ void drag_by(const QPoint &delta);
+
+ /**
+ * Gets the arrow-tip point of the row item marker.
+ * @param rect the rectangle of the header area.
+ */
+ QPoint point(const QRect &rect) const;
+
+ /**
+ * Computes the vertical extents of the contents of this row item.
+ * @return A pair containing the minimum and maximum y-values.
+ */
+ virtual std::pair<int, int> v_extents() const = 0;
+
+public:
+ virtual void hover_point_changed();
+
+protected:
+ pv::view::TraceTreeItemOwner *owner_;
+
+ int layout_v_offset_;
+ int visual_v_offset_;
+
+private:
+ QPropertyAnimation v_offset_animation_;
+};
+
+} // namespace view
+} // namespace pv
+
+#endif // PULSEVIEW_PV_VIEW_TRACETREEITEM_HPP
--- /dev/null
+/*
+ * 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 {
+
+vector< shared_ptr<TraceTreeItem> >& TraceTreeItemOwner::child_items()
+{
+ return items_;
+}
+
+const vector< shared_ptr<TraceTreeItem> >& TraceTreeItemOwner::child_items() const
+{
+ return items_;
+}
+
+void TraceTreeItemOwner::clear_child_items()
+{
+ for (auto &i : items_) {
+ assert(i->owner() == this);
+ i->set_owner(nullptr);
+ }
+ items_.clear();
+}
+
+void TraceTreeItemOwner::add_child_item(std::shared_ptr<TraceTreeItem> item)
+{
+ assert(!item->owner());
+ item->set_owner(this);
+ items_.push_back(item);
+
+ extents_changed(true, true);
+}
+
+void TraceTreeItemOwner::remove_child_item(std::shared_ptr<TraceTreeItem> item)
+{
+ assert(item->owner() == this);
+ item->set_owner(nullptr);
+ auto iter = std::find(items_.begin(), items_.end(), item);
+ assert(iter != items_.end());
+ items_.erase(iter);
+
+ 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);
+}
+
+set< TraceTreeItemOwner* > TraceTreeItemOwner::list_row_item_owners()
+{
+ set< TraceTreeItemOwner* > owners;
+ for (const auto &r : *this)
+ owners.insert(r->owner());
+ return owners;
+}
+
+template<class T>
+set< shared_ptr<T> > TraceTreeItemOwner::list_by_type()
+{
+ set< shared_ptr<T> > items;
+ for (const auto &r : *this) {
+ shared_ptr<T> p = dynamic_pointer_cast<T>(r);
+ if (p)
+ items.insert(p);
+ }
+
+ return items;
+}
+
+template set< shared_ptr<Trace> > TraceTreeItemOwner::list_by_type();
+
+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())
+ continue;
+
+ const int child_offset = r->layout_v_offset();
+ const pair<int, int> child_extents = r->v_extents();
+ extents.first = min(child_extents.first + child_offset,
+ extents.first);
+ extents.second = max(child_extents.second + child_offset,
+ extents.second);
+ }
+
+ return extents;
+}
+
+void TraceTreeItemOwner::restack_items()
+{
+}
+
+} // view
+} // pv
--- /dev/null
+/*
+ * 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_TRACETREEITEMOWNER_HPP
+#define PULSEVIEW_PV_VIEW_TRACETREEITEMOWNER_HPP
+
+#include <memory>
+#include <vector>
+
+#include "rowitemiterator.hpp"
+
+namespace pv {
+
+class Session;
+
+namespace view {
+
+class TraceTreeItem;
+class View;
+
+class TraceTreeItemOwner
+{
+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.
+ */
+ virtual pv::view::View* view() = 0;
+
+ /**
+ * Returns the view of the owner.
+ */
+ virtual const pv::view::View* view() const = 0;
+
+ virtual int owner_visual_v_offset() const = 0;
+
+ /**
+ * Returns the number of nested parents that this row item owner has.
+ */
+ virtual unsigned int depth() const = 0;
+
+ /**
+ * Returns a list of row items owned by this object.
+ */
+ virtual item_list& child_items();
+
+ /**
+ * Returns a list of row items owned by this object.
+ */
+ virtual const item_list& child_items() const;
+
+ /**
+ * Clears the list of child items.
+ */
+ void clear_child_items();
+
+ /**
+ * Adds a child item to this object.
+ */
+ void add_child_item(std::shared_ptr<TraceTreeItem> item);
+
+ /**
+ * Removes a child item from this object.
+ */
+ 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;
+
+ /**
+ * Makes a list of row item owners of all the row items that are
+ * decendants of this item.
+ */
+ std::set< TraceTreeItemOwner* > list_row_item_owners();
+
+ /**
+ * Creates a list of decendant signals filtered by type.
+ */
+ template<class T>
+ std::set< std::shared_ptr<T> > list_by_type();
+
+ /**
+ * Computes the vertical extents of the contents of this row item owner.
+ * @return A pair containing the minimum and maximum y-values.
+ */
+ 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
+} // pv
+
+#endif // PULSEVIEW_PV_VIEW_TRACETREEITEMOWNER_HPP
header_->update();
}
-void View::restack_all_row_items()
+void View::restack_all_trace_tree_items()
{
// Make a list of owners that is sorted from deepest first
const auto owners = list_row_item_owners();
- vector< RowItemOwner* > sorted_owners(owners.begin(), owners.end());
+ vector< TraceTreeItemOwner* > sorted_owners(owners.begin(), owners.end());
sort(sorted_owners.begin(), sorted_owners.end(),
- [](const RowItemOwner* a, const RowItemOwner *b) {
+ [](const TraceTreeItemOwner* a, const TraceTreeItemOwner *b) {
return a->depth() > b->depth(); });
// Restack the items recursively
return QRectF();
}
-RowItemOwner* View::find_prevalent_trace_group(
+TraceTreeItemOwner* View::find_prevalent_trace_group(
const shared_ptr<sigrok::ChannelGroup> &group,
const unordered_map<shared_ptr<sigrok::Channel>, shared_ptr<Signal> >
&signal_map)
{
assert(group);
- unordered_set<RowItemOwner*> owners;
- vector<RowItemOwner*> owner_list;
+ unordered_set<TraceTreeItemOwner*> owners;
+ vector<TraceTreeItemOwner*> owner_list;
// Make a set and a list of all the owners
for (const auto &channel : group->channels()) {
if (iter == signal_map.end())
continue;
- RowItemOwner *const o = (*iter).second->owner();
+ TraceTreeItemOwner *const o = (*iter).second->owner();
owner_list.push_back(o);
owners.insert(o);
}
// Iterate through the list of owners, and find the most prevalent
size_t max_prevalence = 0;
- RowItemOwner *prevalent_owner = nullptr;
- for (RowItemOwner *owner : owners) {
+ TraceTreeItemOwner *prevalent_owner = nullptr;
+ for (TraceTreeItemOwner *owner : owners) {
const size_t prevalence = std::count_if(
owner_list.begin(), owner_list.end(),
- [&](RowItemOwner *o) { return o == owner; });
+ [&](TraceTreeItemOwner *o) { return o == owner; });
if (prevalence > max_prevalence) {
max_prevalence = prevalence;
prevalent_owner = owner;
void View::extents_changed(bool horz, bool vert)
{
sticky_events_ |=
- (horz ? RowItemHExtentsChanged : 0) |
- (vert ? RowItemVExtentsChanged : 0);
+ (horz ? TraceTreeItemHExtentsChanged : 0) |
+ (vert ? TraceTreeItemVExtentsChanged : 0);
lazy_event_handler_.start();
}
void View::signals_changed()
{
- vector< shared_ptr<RowItem> > new_top_level_items;
+ vector< shared_ptr<TraceTreeItem> > new_top_level_items;
const auto device = session_.device();
if (!device)
continue;
// Find best trace group to add to
- RowItemOwner *owner = find_prevalent_trace_group(
+ TraceTreeItemOwner *owner = find_prevalent_trace_group(
group, signal_map);
// If there is no trace group, create one
// Remove any removed traces
for (shared_ptr<Trace> trace : remove_traces) {
- RowItemOwner *const owner = trace->owner();
+ TraceTreeItemOwner *const owner = trace->owner();
assert(owner);
owner->remove_child_item(trace);
}
void View::process_sticky_events()
{
- if (sticky_events_ & RowItemHExtentsChanged)
+ if (sticky_events_ & TraceTreeItemHExtentsChanged)
update_layout();
- if (sticky_events_ & RowItemVExtentsChanged) {
- restack_all_row_items();
+ if (sticky_events_ & TraceTreeItemVExtentsChanged) {
+ restack_all_trace_tree_items();
update_scroll();
}
void View::on_hover_point_changed()
{
- for (shared_ptr<RowItem> r : *this)
+ for (shared_ptr<TraceTreeItem> r : *this)
r->hover_point_changed();
}
#include "cursorpair.hpp"
#include "flag.hpp"
-#include "rowitemowner.hpp"
+#include "tracetreeitemowner.hpp"
namespace sigrok {
class ChannelGroup;
class Trace;
class Viewport;
-class View : public QAbstractScrollArea, public RowItemOwner {
+class View : public QAbstractScrollArea, public TraceTreeItemOwner {
Q_OBJECT
private:
enum StickyEvents {
- RowItemHExtentsChanged = 1,
- RowItemVExtentsChanged = 2
+ TraceTreeItemHExtentsChanged = 1,
+ TraceTreeItemVExtentsChanged = 2
};
private:
void update_viewport();
- void restack_all_row_items();
+ void restack_all_trace_tree_items();
Q_SIGNALS:
void hover_point_changed();
void update_layout();
/**
- * Satisifies RowItem functionality.
+ * Satisifies TraceTreeItem functionality.
* @param p the QPainter to paint into.
* @param rect the rectangle of the header area.
* @param hover true if the label is being hovered over by the mouse.
*/
QRectF label_rect(const QRectF &rect);
- RowItemOwner* find_prevalent_trace_group(
+ TraceTreeItemOwner* find_prevalent_trace_group(
const std::shared_ptr<sigrok::ChannelGroup> &group,
const std::unordered_map<std::shared_ptr<sigrok::Channel>,
std::shared_ptr<Signal> > &signal_map);
void Viewport::paintEvent(QPaintEvent*)
{
- vector< shared_ptr<RowItem> > row_items(view_.begin(), view_.end());
+ vector< shared_ptr<TraceTreeItem> > row_items(view_.begin(), view_.end());
assert(none_of(row_items.begin(), row_items.end(),
- [](const shared_ptr<RowItem> &r) { return !r; }));
+ [](const shared_ptr<TraceTreeItem> &r) { return !r; }));
stable_sort(row_items.begin(), row_items.end(),
- [](const shared_ptr<RowItem> &a, const shared_ptr<RowItem> &b) {
+ [](const shared_ptr<TraceTreeItem> &a, const shared_ptr<TraceTreeItem> &b) {
return a->visual_v_offset() < b->visual_v_offset(); });
const vector< shared_ptr<TimeItem> > time_items(view_.time_items());
for (const shared_ptr<TimeItem> t : time_items)
t->paint_back(p, pp);
- for (const shared_ptr<RowItem> r : row_items)
+ for (const shared_ptr<TraceTreeItem> r : row_items)
r->paint_back(p, pp);
for (const shared_ptr<TimeItem> t : time_items)
t->paint_mid(p, pp);
- for (const shared_ptr<RowItem> r : row_items)
+ for (const shared_ptr<TraceTreeItem> r : row_items)
r->paint_mid(p, pp);
p.setRenderHint(QPainter::Antialiasing, false);
- for (const shared_ptr<RowItem> r : row_items)
+ for (const shared_ptr<TraceTreeItem> r : row_items)
r->paint_fore(p, pp);
for (const shared_ptr<TimeItem> t : time_items)
t->paint_fore(p, pp);
#include <QMouseEvent>
#include <QTouchEvent>
-#include "rowitem.hpp"
+#include "tracetreeitem.hpp"
#include "view.hpp"
#include "viewwidget.hpp"
const vector< shared_ptr<TimeItem> > items(view_.time_items());
const bool any_row_items_selected = any_of(view_.begin(), view_.end(),
- [](const shared_ptr<RowItem> &r) { return r->selected(); });
+ [](const shared_ptr<TraceTreeItem> &r) { return r->selected(); });
const bool any_time_items_selected = any_of(items.begin(), items.end(),
[](const shared_ptr<TimeItem> &i) { return i->selected(); });
if (any_row_items_selected && !any_time_items_selected)
{
// Check all the drag items share a common owner
- RowItemOwner *item_owner = nullptr;
- for (shared_ptr<RowItem> r : view_)
+ TraceTreeItemOwner *item_owner = nullptr;
+ for (shared_ptr<TraceTreeItem> r : view_)
if (r->dragging()) {
if (!item_owner)
item_owner = r->owner();
bool item_dragged = false;
// Drag the row items
- RowItemOwner *item_owner = nullptr;
- for (std::shared_ptr<RowItem> r : view_)
+ TraceTreeItemOwner *item_owner = nullptr;
+ for (std::shared_ptr<TraceTreeItem> r : view_)
if (r->dragging()) {
item_owner = r->owner();
r->drag_by(delta);
i->drag_release();
if (item_dragging_)
- view_.restack_all_row_items();
+ view_.restack_all_trace_tree_items();
else
{
if (!ctrl_pressed) {