]> sigrok.org Git - pulseview.git/commitdiff
TraceGroup: Implemented stacking
authorJoel Holdsworth <redacted>
Sun, 2 Nov 2014 17:43:02 +0000 (17:43 +0000)
committerJoel Holdsworth <redacted>
Wed, 19 Nov 2014 10:23:31 +0000 (10:23 +0000)
pv/view/header.cpp
pv/view/rowitem.cpp
pv/view/rowitem.h
pv/view/rowitemowner.cpp
pv/view/rowitemowner.h
pv/view/tracegroup.cpp
pv/view/tracegroup.h
pv/view/view.cpp
pv/view/view.h

index ffdf79a6cce9f29e8bf6d105d65a399a6dd3e124..c94e2d613d2ef7c25f9b5319a93d133c9e30f866 100644 (file)
@@ -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<RowItem> 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();
index b64294c48907f564540c8edb91b33be01affdc95..7bf52124dac7159fed013600579d07d8d62dc284 100644 (file)
@@ -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
index d068848a54be6faf30488187516354f7d650fdc0..f2e6a66ec87bf6b6c460777d2a65ed832d260757 100644 (file)
@@ -23,6 +23,8 @@
 
 #include <memory>
 
+#include <QPropertyAnimation>
+
 #include "selectableitem.h"
 
 namespace pv {
@@ -34,6 +36,9 @@ class RowItem : public SelectableItem,
        public std::enable_shared_from_this<pv::view::RowItem>
 {
        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
index dd41af05b6e900ce9a6c2dc25d34181be3d81836..a8bdadfa21079a7da1bb44e3a6d01711bc62f558 100644 (file)
@@ -111,5 +111,9 @@ pair<int, int> RowItemOwner::v_extents() const
        return extents;
 }
 
+void RowItemOwner::restack_items()
+{
+}
+
 } // view
 } // pv
index 0fda9aa27b1778dbabfdf6c3d797fd3e4206065a..2295e9631542f42da6b65b6dc50ed0968f4d057a 100644 (file)
@@ -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<int, int> v_extents() const;
 
+       virtual void restack_items();
+
 public:
        virtual void appearance_changed(bool label, bool content) = 0;
 
index 3058cec5158ba90e1979a82ba3dd9d790b43ef56..c2d3c0609db498e0fd2c7b164f2118b84799c6c3 100644 (file)
@@ -116,7 +116,7 @@ QRectF TraceGroup::label_rect(int right) const
 {
        QRectF rect;
        for (const shared_ptr<RowItem> 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<RowItem> > 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 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<RowItem> r : items) {
+               const pair<int, int> 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
index a950eac91451ba188ab0bd898430b4d83ebdef2e..be4cbf1bef706b0dca132f50419acb136b17334e 100644 (file)
@@ -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.
index ba095fb808d083a98397740554de5bc3a4096c0e..615235efbd0af80e845d29106fd55d695791b690 100644 (file)
@@ -26,6 +26,7 @@
 #include <climits>
 #include <cmath>
 #include <mutex>
+#include <unordered_set>
 
 #include <QEvent>
 #include <QMouseEvent>
@@ -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;
index 2f7462978943a84362ff295f95a29011bef6599d..eb60ab1a7735d9f3e51e2f96f00928fa5445b4da 100644 (file)
@@ -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();