From: Joel Holdsworth Date: Sun, 2 Nov 2014 17:43:02 +0000 (+0000) Subject: TraceGroup: Implemented stacking X-Git-Tag: pulseview-0.3.0~448 X-Git-Url: https://sigrok.org/gitweb/?p=pulseview.git;a=commitdiff_plain;h=7ff0145fbf19de010232ea5edadea5df6c28ed8e TraceGroup: Implemented stacking --- diff --git a/pv/view/header.cpp b/pv/view/header.cpp index ffdf79a6..c94e2d61 100644 --- a/pv/view/header.cpp +++ b/pv/view/header.cpp @@ -181,7 +181,9 @@ void Header::mouseLeftReleaseEvent(QMouseEvent *event) for (auto &r : _view) r->drag_release(); - if (!_dragging) + if (_dragging) + _view.restack_all_row_items(); + else { if (!ctrl_pressed) { for (shared_ptr r : _view) @@ -243,6 +245,9 @@ void Header::mouseMoveEvent(QMouseEvent *event) r->select(); } + item_owner->restack_items(); + for (const auto &r : *item_owner) + r->animate_to_layout_v_offset(); signals_moved(); update(); diff --git a/pv/view/rowitem.cpp b/pv/view/rowitem.cpp index b64294c4..7bf52124 100644 --- a/pv/view/rowitem.cpp +++ b/pv/view/rowitem.cpp @@ -30,7 +30,8 @@ namespace view { RowItem::RowItem() : _owner(NULL), _layout_v_offset(0), - _visual_v_offset(0) + _visual_v_offset(0), + _v_offset_animation(this, "visual_v_offset") { } @@ -65,9 +66,24 @@ void RowItem::set_visual_v_offset(int v_offset) void RowItem::force_to_v_offset(int v_offset) { + _v_offset_animation.stop(); _layout_v_offset = _visual_v_offset = v_offset; } +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; @@ -76,18 +92,27 @@ RowItemOwner* RowItem::owner() const 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; + } - if (_owner) - _visual_v_offset += _owner->owner_v_offset(); _owner = owner; - if (_owner) - _visual_v_offset -= _owner->owner_v_offset(); + + 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_v_offset(); + return _visual_v_offset + _owner->owner_visual_v_offset(); } QPoint RowItem::point() const diff --git a/pv/view/rowitem.h b/pv/view/rowitem.h index d068848a..f2e6a66e 100644 --- a/pv/view/rowitem.h +++ b/pv/view/rowitem.h @@ -23,6 +23,8 @@ #include +#include + #include "selectableitem.h" namespace pv { @@ -34,6 +36,9 @@ class RowItem : public SelectableItem, public std::enable_shared_from_this { Q_OBJECT + Q_PROPERTY(int visual_v_offset + READ visual_v_offset + WRITE set_visual_v_offset) public: /** @@ -71,6 +76,12 @@ public: */ 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. */ @@ -147,6 +158,9 @@ protected: 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 index dd41af05..a8bdadfa 100644 --- a/pv/view/rowitemowner.cpp +++ b/pv/view/rowitemowner.cpp @@ -111,5 +111,9 @@ pair RowItemOwner::v_extents() const return extents; } +void RowItemOwner::restack_items() +{ +} + } // view } // pv diff --git a/pv/view/rowitemowner.h b/pv/view/rowitemowner.h index 0fda9aa2..2295e963 100644 --- a/pv/view/rowitemowner.h +++ b/pv/view/rowitemowner.h @@ -63,7 +63,7 @@ public: */ virtual const pv::view::View* view() const = 0; - virtual int owner_v_offset() const = 0; + virtual int owner_visual_v_offset() const = 0; /** * Returns the number of nested parents that this row item owner has. @@ -124,6 +124,8 @@ public: */ std::pair v_extents() const; + virtual void restack_items(); + public: virtual void appearance_changed(bool label, bool content) = 0; diff --git a/pv/view/tracegroup.cpp b/pv/view/tracegroup.cpp index 3058cec5..c2d3c060 100644 --- a/pv/view/tracegroup.cpp +++ b/pv/view/tracegroup.cpp @@ -116,7 +116,7 @@ QRectF TraceGroup::label_rect(int right) const { QRectF rect; for (const shared_ptr r : child_items()) - if (r) + if (r && r->enabled()) rect = rect.united(r->label_rect(right)); return QRectF(rect.x() - Width - Padding, rect.y(), @@ -150,9 +150,44 @@ pv::widgets::Popup* TraceGroup::create_popup(QWidget *parent) return NULL; } -int TraceGroup::owner_v_offset() const +int TraceGroup::owner_visual_v_offset() const { - return _owner ? layout_v_offset() + _owner->owner_v_offset() : 0; + return _owner ? visual_v_offset() + _owner->owner_visual_v_offset() : 0; +} + +void TraceGroup::restack_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 auto aext = a->v_extents(); + const auto bext = b->v_extents(); + return a->layout_v_offset() + + (aext.first + aext.second) / 2 < + b->layout_v_offset() + + (bext.first + bext.second) / 2; + }); + + int total_offset = 0; + for (shared_ptr r : items) { + const pair extents = r->v_extents(); + if (extents.first == 0 && extents.second == 0) + continue; + + // We position disabled traces, so that they are close to the + // animation target positon should they be re-enabled + if (r->enabled()) + total_offset += -extents.first; + + if (!r->dragging()) + r->set_layout_v_offset(total_offset); + + if (r->enabled()) + total_offset += extents.second; + } } unsigned int TraceGroup::depth() const diff --git a/pv/view/tracegroup.h b/pv/view/tracegroup.h index a950eac9..be4cbf1b 100644 --- a/pv/view/tracegroup.h +++ b/pv/view/tracegroup.h @@ -108,7 +108,9 @@ public: /** * Returns the total vertical offset of this trace and all it's owners */ - int owner_v_offset() const; + int owner_visual_v_offset() const; + + void restack_items(); /** * Returns the number of nested parents that this row item owner has. diff --git a/pv/view/view.cpp b/pv/view/view.cpp index ba095fb8..615235ef 100644 --- a/pv/view/view.cpp +++ b/pv/view/view.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #include @@ -56,6 +57,7 @@ using std::min; using std::pair; using std::set; using std::shared_ptr; +using std::unordered_set; using std::vector; using std::weak_ptr; @@ -181,7 +183,7 @@ double View::offset() const return _offset; } -int View::owner_v_offset() const +int View::owner_visual_v_offset() const { return -_v_offset; } @@ -331,6 +333,29 @@ void View::update_viewport() { assert(_viewport); _viewport->update(); + _header->update(); +} + +void View::restack_all_row_items() +{ + // Make a set of owners + unordered_set< RowItemOwner* > owners; + for (const auto &r : *this) + owners.insert(r->owner()); + + // Make a list that is sorted from deepest first + vector< RowItemOwner* > sorted_owners(owners.begin(), owners.end()); + sort(sorted_owners.begin(), sorted_owners.end(), + [](const RowItemOwner* a, const RowItemOwner *b) { + return a->depth() > b->depth(); }); + + // Restack the items recursively + for (auto &o : sorted_owners) + o->restack_items(); + + // Animate the items to their destination + for (const auto &r : *this) + r->animate_to_layout_v_offset(); } void View::get_scroll_layout(double &length, double &offset) const @@ -559,10 +584,8 @@ void View::process_sticky_events() { if (_sticky_events & SelectableItemHExtentsChanged) update_layout(); - if (_sticky_events & SelectableItemVExtentsChanged) { - _viewport->update(); - _header->update(); - } + if (_sticky_events & SelectableItemVExtentsChanged) + restack_all_row_items(); // Clear the sticky events _sticky_events = 0; diff --git a/pv/view/view.h b/pv/view/view.h index 2f746297..eb60ab1a 100644 --- a/pv/view/view.h +++ b/pv/view/view.h @@ -97,7 +97,7 @@ public: * seconds. */ double offset() const; - int owner_v_offset() const; + int owner_visual_v_offset() const; /** * Returns the number of nested parents that this row item owner has. @@ -152,6 +152,8 @@ public: void update_viewport(); + void restack_all_row_items(); + Q_SIGNALS: void hover_point_changed();