From: Joel Holdsworth Date: Mon, 27 Jul 2015 01:24:11 +0000 (-0600) Subject: TraceTreeItem: Separated from RowItem X-Git-Url: http://git.code-monkey.de/?p=pulseview.git;a=commitdiff_plain;h=af503b104d890a357c736c678bb00296d889c090 TraceTreeItem: Separated from RowItem --- diff --git a/CMakeLists.txt b/CMakeLists.txt index be2cd14..a979be6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -207,8 +207,6 @@ set(pulseview_SOURCES 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 @@ -216,6 +214,8 @@ set(pulseview_SOURCES 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 @@ -265,6 +265,7 @@ set(pulseview_HEADERS 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 diff --git a/pv/view/header.cpp b/pv/view/header.cpp index f31a91c..60d64b2 100644 --- a/pv/view/header.cpp +++ b/pv/view/header.cpp @@ -54,7 +54,7 @@ namespace view { const int Header::Padding = 12; const int Header::BaselineOffset = 5; -static bool item_selected(shared_ptr r) +static bool item_selected(shared_ptr r) { return r->selected(); } @@ -89,7 +89,7 @@ shared_ptr Header::get_mouse_over_item(const QPoint &pt) for (auto &i : view_) if (i->enabled() && i->label_rect(r).contains(pt)) return i; - return shared_ptr(); + return shared_ptr(); } void Header::paintEvent(QPaintEvent*) @@ -99,17 +99,17 @@ void Header::paintEvent(QPaintEvent*) // would be clipped away. const QRect rect(0, 0, width() - BaselineOffset, height()); - vector< shared_ptr > row_items( + vector< shared_ptr > items( view_.begin(), view_.end()); - stable_sort(row_items.begin(), row_items.end(), - [](const shared_ptr &a, const shared_ptr &b) { + stable_sort(items.begin(), items.end(), + [](const shared_ptr &a, const shared_ptr &b) { return a->visual_v_offset() < b->visual_v_offset(); }); QPainter painter(this); painter.setRenderHint(QPainter::Antialiasing); - for (const shared_ptr r : row_items) + for (const shared_ptr r : items) { assert(r); @@ -160,17 +160,17 @@ void Header::keyPressEvent(QKeyEvent *e) void Header::on_group() { - vector< shared_ptr > selected_items( + vector< shared_ptr > 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 &a, const shared_ptr &b) { + [](const shared_ptr &a, const shared_ptr &b) { return a->visual_v_offset() < b->visual_v_offset(); }); shared_ptr group(new TraceGroup()); - shared_ptr mouse_down_item( - std::dynamic_pointer_cast(mouse_down_item_)); - shared_ptr focus_item( + shared_ptr mouse_down_item( + std::dynamic_pointer_cast(mouse_down_item_)); + shared_ptr focus_item( mouse_down_item ? mouse_down_item : selected_items.front()); assert(focus_item); @@ -182,7 +182,7 @@ void Header::on_group() focus_item->v_extents().first); for (size_t i = 0; i < selected_items.size(); i++) { - const shared_ptr &r = selected_items[i]; + const shared_ptr &r = selected_items[i]; assert(r->owner()); r->owner()->remove_child_item(r); group->add_child_item(r); @@ -198,7 +198,7 @@ void Header::on_ungroup() bool restart; do { restart = false; - for (const shared_ptr r : view_) { + for (const shared_ptr r : view_) { const shared_ptr tg = dynamic_pointer_cast(r); if (tg && tg->selected()) { diff --git a/pv/view/header.hpp b/pv/view/header.hpp index 91612b9..ade6d33 100644 --- a/pv/view/header.hpp +++ b/pv/view/header.hpp @@ -30,7 +30,7 @@ namespace pv { namespace view { -class RowItem; +class TraceTreeItem; class View; class ViewItem; diff --git a/pv/view/rowitem.cpp b/pv/view/rowitem.cpp deleted file mode 100644 index 07540c1..0000000 --- a/pv/view/rowitem.cpp +++ /dev/null @@ -1,139 +0,0 @@ -/* - * This file is part of the PulseView project. - * - * Copyright (C) 2013 Joel Holdsworth - * - * 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 - -#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 diff --git a/pv/view/rowitem.hpp b/pv/view/rowitem.hpp index c8f1097..80bf8a5 100644 --- a/pv/view/rowitem.hpp +++ b/pv/view/rowitem.hpp @@ -21,107 +21,14 @@ #ifndef PULSEVIEW_PV_VIEW_ROWITEM_HPP #define PULSEVIEW_PV_VIEW_ROWITEM_HPP -#include - -#include - #include "viewitem.hpp" namespace pv { namespace view { -class RowItemOwner; - -class RowItem : public ViewItem, - public std::enable_shared_from_this +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 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 diff --git a/pv/view/rowitemowner.cpp b/pv/view/rowitemowner.cpp deleted file mode 100644 index 49e6e1a..0000000 --- a/pv/view/rowitemowner.cpp +++ /dev/null @@ -1,146 +0,0 @@ -/* - * This file is part of the PulseView project. - * - * Copyright (C) 2014 Joel Holdsworth - * - * 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 - -#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 >& RowItemOwner::child_items() -{ - return items_; -} - -const vector< shared_ptr >& 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 item) -{ - assert(!item->owner()); - item->set_owner(this); - items_.push_back(item); - - extents_changed(true, true); -} - -void RowItemOwner::remove_child_item(std::shared_ptr 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 -set< shared_ptr > RowItemOwner::list_by_type() -{ - set< shared_ptr > items; - for (const auto &r : *this) { - shared_ptr p = dynamic_pointer_cast(r); - if (p) - items.insert(p); - } - - return items; -} - -template set< shared_ptr > RowItemOwner::list_by_type(); - -pair RowItemOwner::v_extents() const -{ - pair extents(INT_MAX, INT_MIN); - - for (const shared_ptr r : child_items()) { - assert(r); - if (!r->enabled()) - continue; - - const int child_offset = r->layout_v_offset(); - const pair 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 diff --git a/pv/view/rowitemowner.hpp b/pv/view/rowitemowner.hpp deleted file mode 100644 index f64b259..0000000 --- a/pv/view/rowitemowner.hpp +++ /dev/null @@ -1,153 +0,0 @@ -/* - * This file is part of the PulseView project. - * - * Copyright (C) 2014 Joel Holdsworth - * - * 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 -#include - -#include "rowitemiterator.hpp" - -namespace pv { - -class Session; - -namespace view { - -class RowItem; -class View; - -class RowItemOwner -{ -public: - typedef std::vector< std::shared_ptr > item_list; - typedef RowItemIterator iterator; - typedef RowItemIterator 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 item); - - /** - * Removes a child item from this object. - */ - void remove_child_item(std::shared_ptr 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 - std::set< std::shared_ptr > 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 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 diff --git a/pv/view/trace.hpp b/pv/view/trace.hpp index 7d0b8a0..8c99191 100644 --- a/pv/view/trace.hpp +++ b/pv/view/trace.hpp @@ -29,7 +29,7 @@ #include -#include "rowitem.hpp" +#include "tracetreeitem.hpp" class QFormLayout; @@ -41,7 +41,7 @@ class Popup; namespace view { -class Trace : public RowItem +class Trace : public TraceTreeItem { Q_OBJECT diff --git a/pv/view/tracegroup.cpp b/pv/view/tracegroup.cpp index 74221d4..87f1ff3 100644 --- a/pv/view/tracegroup.cpp +++ b/pv/view/tracegroup.cpp @@ -49,7 +49,7 @@ TraceGroup::~TraceGroup() bool TraceGroup::enabled() const { return std::any_of(child_items().begin(), child_items().end(), - [](const shared_ptr &r) { return r->enabled(); }); + [](const shared_ptr &r) { return r->enabled(); }); } pv::Session& TraceGroup::session() @@ -78,7 +78,7 @@ const pv::view::View* TraceGroup::view() const pair TraceGroup::v_extents() const { - return RowItemOwner::v_extents(); + return TraceTreeItemOwner::v_extents(); } void TraceGroup::paint_label(QPainter &p, const QRect &rect, bool hover) @@ -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 r : child_items()) + for (const shared_ptr r : child_items()) if (r && r->enabled()) child_rect = child_rect.united(r->label_rect(rect)); @@ -157,12 +157,12 @@ int TraceGroup::owner_visual_v_offset() const void TraceGroup::restack_items() { - vector< shared_ptr > items( + vector< shared_ptr > items( child_items().begin(), child_items().end()); // Sort by the centre line of the extents stable_sort(items.begin(), items.end(), - [](const shared_ptr &a, const shared_ptr &b) { + [](const shared_ptr &a, const shared_ptr &b) { const auto aext = a->v_extents(); const auto bext = b->v_extents(); return a->layout_v_offset() + @@ -172,7 +172,7 @@ void TraceGroup::restack_items() }); int total_offset = 0; - for (shared_ptr r : items) { + for (shared_ptr r : items) { const pair extents = r->v_extents(); if (extents.first == 0 && extents.second == 0) continue; @@ -197,11 +197,11 @@ unsigned int TraceGroup::depth() const void TraceGroup::ungroup() { - const vector< shared_ptr > items( + const vector< shared_ptr > items( child_items().begin(), child_items().end()); clear_child_items(); - for (shared_ptr r : items) + for (shared_ptr r : items) owner_->add_child_item(r); owner_->remove_child_item(shared_from_this()); diff --git a/pv/view/tracegroup.hpp b/pv/view/tracegroup.hpp index 5310313..6407f1b 100644 --- a/pv/view/tracegroup.hpp +++ b/pv/view/tracegroup.hpp @@ -21,13 +21,13 @@ #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 diff --git a/pv/view/tracetreeitem.cpp b/pv/view/tracetreeitem.cpp new file mode 100644 index 0000000..1e09908 --- /dev/null +++ b/pv/view/tracetreeitem.cpp @@ -0,0 +1,139 @@ +/* + * This file is part of the PulseView project. + * + * Copyright (C) 2013 Joel Holdsworth + * + * 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 + +#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 diff --git a/pv/view/tracetreeitem.hpp b/pv/view/tracetreeitem.hpp new file mode 100644 index 0000000..3b21698 --- /dev/null +++ b/pv/view/tracetreeitem.hpp @@ -0,0 +1,130 @@ +/* + * This file is part of the PulseView project. + * + * Copyright (C) 2013 Joel Holdsworth + * + * 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 + +#include + +#include "rowitem.hpp" + +namespace pv { +namespace view { + +class TraceTreeItemOwner; + +class TraceTreeItem : public RowItem, + public std::enable_shared_from_this +{ + 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 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 diff --git a/pv/view/tracetreeitemowner.cpp b/pv/view/tracetreeitemowner.cpp new file mode 100644 index 0000000..247e3e6 --- /dev/null +++ b/pv/view/tracetreeitemowner.cpp @@ -0,0 +1,146 @@ +/* + * This file is part of the PulseView project. + * + * Copyright (C) 2014 Joel Holdsworth + * + * 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 + +#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 >& TraceTreeItemOwner::child_items() +{ + return items_; +} + +const vector< shared_ptr >& 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 item) +{ + assert(!item->owner()); + item->set_owner(this); + items_.push_back(item); + + extents_changed(true, true); +} + +void TraceTreeItemOwner::remove_child_item(std::shared_ptr 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 +set< shared_ptr > TraceTreeItemOwner::list_by_type() +{ + set< shared_ptr > items; + for (const auto &r : *this) { + shared_ptr p = dynamic_pointer_cast(r); + if (p) + items.insert(p); + } + + return items; +} + +template set< shared_ptr > TraceTreeItemOwner::list_by_type(); + +pair TraceTreeItemOwner::v_extents() const +{ + pair extents(INT_MAX, INT_MIN); + + for (const shared_ptr r : child_items()) { + assert(r); + if (!r->enabled()) + continue; + + const int child_offset = r->layout_v_offset(); + const pair 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 diff --git a/pv/view/tracetreeitemowner.hpp b/pv/view/tracetreeitemowner.hpp new file mode 100644 index 0000000..905746d --- /dev/null +++ b/pv/view/tracetreeitemowner.hpp @@ -0,0 +1,153 @@ +/* + * This file is part of the PulseView project. + * + * Copyright (C) 2014 Joel Holdsworth + * + * 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 +#include + +#include "rowitemiterator.hpp" + +namespace pv { + +class Session; + +namespace view { + +class TraceTreeItem; +class View; + +class TraceTreeItemOwner +{ +public: + typedef std::vector< std::shared_ptr > item_list; + typedef RowItemIterator iterator; + typedef RowItemIterator 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 item); + + /** + * Removes a child item from this object. + */ + void remove_child_item(std::shared_ptr 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 + std::set< std::shared_ptr > 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 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 diff --git a/pv/view/view.cpp b/pv/view/view.cpp index 9de93f3..540b90e 100644 --- a/pv/view/view.cpp +++ b/pv/view/view.cpp @@ -504,13 +504,13 @@ void View::update_viewport() 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 @@ -672,15 +672,15 @@ QRectF View::label_rect(const QRectF &rect) return QRectF(); } -RowItemOwner* View::find_prevalent_trace_group( +TraceTreeItemOwner* View::find_prevalent_trace_group( const shared_ptr &group, const unordered_map, shared_ptr > &signal_map) { assert(group); - unordered_set owners; - vector owner_list; + unordered_set owners; + vector owner_list; // Make a set and a list of all the owners for (const auto &channel : group->channels()) { @@ -688,18 +688,18 @@ RowItemOwner* View::find_prevalent_trace_group( 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; @@ -825,8 +825,8 @@ void View::time_item_appearance_changed(bool label, bool content) 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(); } @@ -864,7 +864,7 @@ void View::v_scroll_value_changed() void View::signals_changed() { - vector< shared_ptr > new_top_level_items; + vector< shared_ptr > new_top_level_items; const auto device = session_.device(); if (!device) @@ -913,7 +913,7 @@ void View::signals_changed() 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 @@ -963,7 +963,7 @@ void View::signals_changed() // Remove any removed traces for (shared_ptr trace : remove_traces) { - RowItemOwner *const owner = trace->owner(); + TraceTreeItemOwner *const owner = trace->owner(); assert(owner); owner->remove_child_item(trace); } @@ -1044,10 +1044,10 @@ void View::perform_delayed_view_update() 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(); } @@ -1057,7 +1057,7 @@ void View::process_sticky_events() void View::on_hover_point_changed() { - for (shared_ptr r : *this) + for (shared_ptr r : *this) r->hover_point_changed(); } diff --git a/pv/view/view.hpp b/pv/view/view.hpp index 5f81d44..95e518a 100644 --- a/pv/view/view.hpp +++ b/pv/view/view.hpp @@ -38,7 +38,7 @@ #include "cursorpair.hpp" #include "flag.hpp" -#include "rowitemowner.hpp" +#include "tracetreeitemowner.hpp" namespace sigrok { class ChannelGroup; @@ -56,13 +56,13 @@ class Ruler; 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: @@ -209,7 +209,7 @@ public: void update_viewport(); - void restack_all_row_items(); + void restack_all_trace_tree_items(); Q_SIGNALS: void hover_point_changed(); @@ -260,7 +260,7 @@ private: 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. @@ -274,7 +274,7 @@ private: */ QRectF label_rect(const QRectF &rect); - RowItemOwner* find_prevalent_trace_group( + TraceTreeItemOwner* find_prevalent_trace_group( const std::shared_ptr &group, const std::unordered_map, std::shared_ptr > &signal_map); diff --git a/pv/view/viewport.cpp b/pv/view/viewport.cpp index a4b6680..007a8c2 100644 --- a/pv/view/viewport.cpp +++ b/pv/view/viewport.cpp @@ -148,12 +148,12 @@ bool Viewport::touch_event(QTouchEvent *event) void Viewport::paintEvent(QPaintEvent*) { - vector< shared_ptr > row_items(view_.begin(), view_.end()); + vector< shared_ptr > row_items(view_.begin(), view_.end()); assert(none_of(row_items.begin(), row_items.end(), - [](const shared_ptr &r) { return !r; })); + [](const shared_ptr &r) { return !r; })); stable_sort(row_items.begin(), row_items.end(), - [](const shared_ptr &a, const shared_ptr &b) { + [](const shared_ptr &a, const shared_ptr &b) { return a->visual_v_offset() < b->visual_v_offset(); }); const vector< shared_ptr > time_items(view_.time_items()); @@ -167,17 +167,17 @@ void Viewport::paintEvent(QPaintEvent*) for (const shared_ptr t : time_items) t->paint_back(p, pp); - for (const shared_ptr r : row_items) + for (const shared_ptr r : row_items) r->paint_back(p, pp); for (const shared_ptr t : time_items) t->paint_mid(p, pp); - for (const shared_ptr r : row_items) + for (const shared_ptr r : row_items) r->paint_mid(p, pp); p.setRenderHint(QPainter::Antialiasing, false); - for (const shared_ptr r : row_items) + for (const shared_ptr r : row_items) r->paint_fore(p, pp); for (const shared_ptr t : time_items) t->paint_fore(p, pp); diff --git a/pv/view/viewwidget.cpp b/pv/view/viewwidget.cpp index 600dd62..9913b5c 100644 --- a/pv/view/viewwidget.cpp +++ b/pv/view/viewwidget.cpp @@ -22,7 +22,7 @@ #include #include -#include "rowitem.hpp" +#include "tracetreeitem.hpp" #include "view.hpp" #include "viewwidget.hpp" @@ -66,7 +66,7 @@ bool ViewWidget::accept_drag() const const vector< shared_ptr > items(view_.time_items()); const bool any_row_items_selected = any_of(view_.begin(), view_.end(), - [](const shared_ptr &r) { return r->selected(); }); + [](const shared_ptr &r) { return r->selected(); }); const bool any_time_items_selected = any_of(items.begin(), items.end(), [](const shared_ptr &i) { return i->selected(); }); @@ -74,8 +74,8 @@ bool ViewWidget::accept_drag() const 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 r : view_) + TraceTreeItemOwner *item_owner = nullptr; + for (shared_ptr r : view_) if (r->dragging()) { if (!item_owner) item_owner = r->owner(); @@ -105,8 +105,8 @@ void ViewWidget::drag_items(const QPoint &delta) bool item_dragged = false; // Drag the row items - RowItemOwner *item_owner = nullptr; - for (std::shared_ptr r : view_) + TraceTreeItemOwner *item_owner = nullptr; + for (std::shared_ptr r : view_) if (r->dragging()) { item_owner = r->owner(); r->drag_by(delta); @@ -201,7 +201,7 @@ void ViewWidget::mouse_left_release_event(QMouseEvent *event) i->drag_release(); if (item_dragging_) - view_.restack_all_row_items(); + view_.restack_all_trace_tree_items(); else { if (!ctrl_pressed) {