]> sigrok.org Git - pulseview.git/blobdiff - pv/view/view.cpp
View: Set scroll_needs_defaults_ to true by default
[pulseview.git] / pv / view / view.cpp
index d9b02353adaf708f04ea47b2ad4b4cc1112d7bb0..287bfb6c51b7429467d72779abd2cadb3b3a76a1 100644 (file)
@@ -129,6 +129,7 @@ View::View(Session &session, bool is_main_view, QWidget *parent) :
        scale_(1e-3),
        offset_(0),
        updating_scroll_(false),
+       settings_restored_(false),
        sticky_scrolling_(false), // Default setting is set in MainWindow::setup_ui()
        always_zoom_to_fit_(false),
        tick_period_(0),
@@ -140,7 +141,7 @@ View::View(Session &session, bool is_main_view, QWidget *parent) :
        next_flag_text_('A'),
        trigger_markers_(),
        hover_point_(-1, -1),
-       scroll_needs_defaults_(false),
+       scroll_needs_defaults_(true),
        saved_v_offset_(0)
 {
        QVBoxLayout *root_layout = new QVBoxLayout(this);
@@ -155,7 +156,7 @@ View::View(Session &session, bool is_main_view, QWidget *parent) :
        ruler_ = new Ruler(*this);
 
        header_ = new Header(*this);
-       header_->setMinimumWidth(15);  // So that the arrow tips show at least
+       header_->setMinimumWidth(10);  // So that the arrow tips show at least
 
        // We put the header into a simple layout so that we can add the top margin,
        // allowing us to make it line up with the bottom of the ruler
@@ -204,6 +205,9 @@ View::View(Session &session, bool is_main_view, QWidget *parent) :
        connect(ruler_, SIGNAL(selection_changed()),
                this, SIGNAL(selection_changed()));
 
+       connect(splitter_, SIGNAL(splitterMoved(int, int)),
+               this, SLOT(on_splitter_moved()));
+
        connect(this, SIGNAL(hover_point_changed()),
                this, SLOT(on_hover_point_changed()));
 
@@ -300,6 +304,8 @@ void View::save_settings(QSettings &settings) const
        settings.setValue("v_offset",
                scrollarea_->verticalScrollBar()->sliderPosition());
 
+       settings.setValue("splitter_state", splitter_->saveState());
+
        stringstream ss;
        boost::archive::text_oarchive oa(ss);
        oa << boost::serialization::make_nvp("offset", offset_);
@@ -331,6 +337,9 @@ void View::restore_settings(QSettings &settings)
                set_offset(offset);
        }
 
+       if (settings.contains("splitter_state"))
+               splitter_->restoreState(settings.value("splitter_state").toByteArray());
+
        for (shared_ptr<Signal> signal : signals_) {
                settings.beginGroup(signal->base()->internal_name());
                signal->restore_settings(settings);
@@ -343,6 +352,8 @@ void View::restore_settings(QSettings &settings)
                scroll_needs_defaults_ = false;
                // Note: see eventFilter() for additional information
        }
+
+       settings_restored_ = true;
 }
 
 vector< shared_ptr<TimeItem> > View::time_items() const
@@ -368,7 +379,7 @@ void View::set_scale(double scale)
 {
        if (scale_ != scale) {
                scale_ = scale;
-               Q_EMIT scale_changed();
+               scale_changed();
        }
 }
 
@@ -381,7 +392,7 @@ void View::set_offset(const pv::util::Timestamp& offset)
 {
        if (offset_ != offset) {
                offset_ = offset;
-               Q_EMIT offset_changed();
+               offset_changed();
        }
 }
 
@@ -411,7 +422,7 @@ void View::set_tick_prefix(pv::util::SIPrefix tick_prefix)
 {
        if (tick_prefix_ != tick_prefix) {
                tick_prefix_ = tick_prefix;
-               Q_EMIT tick_prefix_changed();
+               tick_prefix_changed();
        }
 }
 
@@ -424,7 +435,7 @@ void View::set_tick_precision(unsigned tick_precision)
 {
        if (tick_precision_ != tick_precision) {
                tick_precision_ = tick_precision;
-               Q_EMIT tick_precision_changed();
+               tick_precision_changed();
        }
 }
 
@@ -437,7 +448,7 @@ void View::set_tick_period(const pv::util::Timestamp& tick_period)
 {
        if (tick_period_ != tick_period) {
                tick_period_ = tick_period;
-               Q_EMIT tick_period_changed();
+               tick_period_changed();
        }
 }
 
@@ -450,7 +461,7 @@ void View::set_time_unit(pv::util::TimeUnit time_unit)
 {
        if (time_unit_ != time_unit) {
                time_unit_ = time_unit;
-               Q_EMIT time_unit_changed();
+               time_unit_changed();
        }
 }
 
@@ -864,29 +875,39 @@ void View::set_scroll_default()
                set_v_offset(extents.first);
 }
 
-bool View::header_fully_visible() const
+bool View::header_was_shrunk() const
 {
        const int header_pane_width = splitter_->sizes().front();
        const int header_width = header_->extended_size_hint().width();
 
-       return (header_pane_width >= header_width);
+       // Allow for a slight margin of error so that we also accept
+       // slight differences when e.g. a label name change increased
+       // the overall width
+       return (header_pane_width < (header_width - 10));
 }
 
-void View::update_layout()
+void View::expand_header_to_fit()
 {
-       // Only adjust pane sizes if the header hasn't been partially hidden by the user
-       if (header_fully_visible()) {
-               int splitter_area_width = 0;
-               for (int w : splitter_->sizes())
-                       splitter_area_width += w;
-
-               // Make sure the header has enough horizontal space to show all labels fully
-               QList<int> pane_sizes;
-               pane_sizes.push_back(header_->extended_size_hint().width());
-               pane_sizes.push_back(splitter_area_width - header_->extended_size_hint().width());
-               splitter_->setSizes(pane_sizes);
+       int splitter_area_width = 0;
+       for (int w : splitter_->sizes())
+               splitter_area_width += w;
+
+       // Workaround for when the header needs resizing but the view
+       // isn't visible yet and thus splitter_->sizes() returns (0, 0)
+       if (splitter_area_width == 0) {
+               QTimer::singleShot(50, this, SLOT(on_repeat_splitter_expansion()));
+               return;
        }
 
+       // Make sure the header has enough horizontal space to show all labels fully
+       QList<int> pane_sizes;
+       pane_sizes.push_back(header_->extended_size_hint().width());
+       pane_sizes.push_back(splitter_area_width - header_->extended_size_hint().width());
+       splitter_->setSizes(pane_sizes);
+}
+
+void View::update_layout()
+{
        update_scroll();
 }
 
@@ -1035,8 +1056,13 @@ void View::row_item_appearance_changed(bool label, bool content)
 
 void View::time_item_appearance_changed(bool label, bool content)
 {
-       if (label)
+       if (label) {
                ruler_->update();
+
+               // Make sure the header pane width is updated, too
+               update_layout();
+       }
+
        if (content)
                viewport_->update();
 }
@@ -1050,6 +1076,26 @@ void View::extents_changed(bool horz, bool vert)
        lazy_event_handler_.start();
 }
 
+void View::on_splitter_moved()
+{
+       // Setting the maximum width of the header widget doesn't work as
+       // expected because the splitter would allow the user to make the
+       // pane wider than that, creating empty space as a result.
+       // To make this work, we stricly enforce the maximum width by
+       // expanding the header unless the user shrunk it on purpose.
+       // As we're then setting the width of the header pane, we set the
+       // splitter to the maximum allowed position.
+       if (!header_was_shrunk())
+               expand_header_to_fit();
+}
+
+void View::on_repeat_splitter_expansion()
+{
+       // Don't mess with the header if settings were restored in the meanwhile
+       if (!settings_restored_)
+               expand_header_to_fit();
+}
+
 void View::h_scroll_value_changed(int value)
 {
        if (updating_scroll_)
@@ -1245,6 +1291,12 @@ void View::signals_changed()
                        offset += extents.second;
        }
 
+
+       if (!new_top_level_items.empty())
+               // Expand the header pane because the header should become fully
+               // visible when new signals are added
+               expand_header_to_fit();
+
        update_layout();
 
        header_->update();