diff --git a/app/widget/resizablescrollbar/resizablescrollbar.cpp b/app/widget/resizablescrollbar/resizablescrollbar.cpp index fc6a79d44..f18a86037 100644 --- a/app/widget/resizablescrollbar/resizablescrollbar.cpp +++ b/app/widget/resizablescrollbar/resizablescrollbar.cpp @@ -39,11 +39,8 @@ void ResizableScrollBar::mouseMoveEvent(QMouseEvent *event) QRect sr = style()->subControlRect(QStyle::CC_ScrollBar, &opt, QStyle::SC_ScrollBarSlider, this); - QRect gr = style()->subControlRect(QStyle::CC_ScrollBar, &opt, - QStyle::SC_ScrollBarGroove, this); if (mouse_dragging_) { - int new_drag_pos = GetActiveMousePos(event); int mouse_movement = new_drag_pos - mouse_drag_start_; mouse_drag_start_ = new_drag_pos; @@ -52,21 +49,29 @@ void ResizableScrollBar::mouseMoveEvent(QMouseEvent *event) mouse_movement = -mouse_movement; } - double scale_multiplier = static_cast(sr.width()) / static_cast(sr.width() + mouse_movement); - emit RequestScale(scale_multiplier); + double width_adjustment = static_cast(sr.width() + mouse_movement); - if (mouse_handle_state_ == kInTopHandle) { - int slider_min = gr.x(); - int slider_max = gr.right() - (sr.width() + mouse_movement); - int val = QStyle::sliderValueFromPosition(minimum(), - maximum(), - event->pos().x() - slider_min, - slider_max - slider_min, - opt.upsideDown); + // Prevent dividing by zero or emitting a negative scale + if (width_adjustment > 0) { + double scale_multiplier = static_cast(sr.width()) / width_adjustment; + emit RequestScale(scale_multiplier); - setValue(val); - } else { - setValue(qRound(static_cast(value()) * scale_multiplier)); + if (mouse_handle_state_ == kInTopHandle) { + QRect gr = style()->subControlRect(QStyle::CC_ScrollBar, &opt, + QStyle::SC_ScrollBarGroove, this); + + int slider_min = gr.x(); + int slider_max = gr.right() - (sr.width() + mouse_movement); + int val = QStyle::sliderValueFromPosition(minimum(), + maximum(), + event->pos().x() - slider_min, + slider_max - slider_min, + opt.upsideDown); + + setValue(val); + } else { + setValue(qRound(static_cast(value()) * scale_multiplier)); + } } } else { diff --git a/app/widget/timebased/timebased.cpp b/app/widget/timebased/timebased.cpp index d5b8ce664..dfa31c908 100644 --- a/app/widget/timebased/timebased.cpp +++ b/app/widget/timebased/timebased.cpp @@ -81,7 +81,22 @@ void TimeBasedWidget::UpdateMaximumScroll() void TimeBasedWidget::ScrollBarResized(const double &multiplier) { - SetScale(GetScale() * multiplier); + QScrollBar* bar = static_cast(sender()); + + int current_max = bar->maximum(); + double proposed_max = static_cast(current_max) * multiplier; + + proposed_max = proposed_max - (bar->width() * 0.5 / multiplier) + (bar->width() * 0.5); + + double corrected_scale; + + if (current_max == 0) { + corrected_scale = multiplier; + } else { + corrected_scale = (proposed_max / static_cast(current_max)); + } + + SetScale(GetScale() * corrected_scale); } TimeRuler *TimeBasedWidget::ruler() const @@ -146,6 +161,7 @@ void TimeBasedWidget::SetTimebase(const rational &timebase) void TimeBasedWidget::SetScale(const double &scale) { + // Simple QObject slot wrapper around TimelineScaledObject::SetScale() TimelineScaledObject::SetScale(scale); } diff --git a/app/widget/timelinewidget/timelinescaledobject.cpp b/app/widget/timelinewidget/timelinescaledobject.cpp index f3a467782..d010c5129 100644 --- a/app/widget/timelinewidget/timelinescaledobject.cpp +++ b/app/widget/timelinewidget/timelinescaledobject.cpp @@ -71,7 +71,9 @@ const double& TimelineScaledObject::GetScale() const void TimelineScaledObject::SetScale(const double& scale) { - scale_ = scale; + Q_ASSERT(scale > 0); + + scale_ = qMin(scale, max_scale_); ScaleChangedEvent(scale_); }