diff --git a/include/ClipView.h b/include/ClipView.h index 6e6ca4d6607..45cd602f6ce 100644 --- a/include/ClipView.h +++ b/include/ClipView.h @@ -172,7 +172,7 @@ public slots: bool unquantizedModHeld( QMouseEvent * me ); TimePos quantizeSplitPos(TimePos); - float pixelsPerBar(); + float pixelsPerBar() const; DataFile createClipDataFiles(const QVector & clips) const; @@ -234,6 +234,13 @@ protected slots: TimePos draggedClipPos( QMouseEvent * me ); int knifeMarkerPos( QMouseEvent * me ); void setColor(const std::optional& color); + + /** + * @returns the width of a note's resize area in pixels. + * @note When zoomed in, this is a constant pixel value, but when zoomed far out, + * it is a fraction of the clip width. + */ + int resizeGripWidth() const; //! Returns whether the user can left-resize this clip so that the start of the clip bounds is before the start of the clip content. virtual bool isResizableBeforeStart() { return true; }; diff --git a/src/gui/clips/ClipView.cpp b/src/gui/clips/ClipView.cpp index 44ff6fd36e9..f91c0bc45d1 100644 --- a/src/gui/clips/ClipView.cpp +++ b/src/gui/clips/ClipView.cpp @@ -56,9 +56,10 @@ namespace lmms::gui { -/*! The width of the resize grip in pixels - */ -const int RESIZE_GRIP_WIDTH = 8; +//! The default width of the resize grip in pixels +constexpr int RESIZE_GRIP_WIDTH = 8; +//! The maximum fraction of the clip width that the resize grip is allowed to take up +constexpr float RESIZE_GRIP_MAX_WIDTH_FRACTION = 0.1f; /*! A pointer for that text bubble used when moving segments, etc. @@ -397,6 +398,15 @@ void ClipView::setColor(const std::optional& color) Engine::getSong()->setModified(); } + +int ClipView::resizeGripWidth() const +{ + const int clipWidth = m_clip->length() * pixelsPerBar() / TimePos::ticksPerBar(); + return std::min(RESIZE_GRIP_WIDTH, static_cast(std::round(RESIZE_GRIP_MAX_WIDTH_FRACTION * clipWidth))); +} + + + /*! \brief Change the ClipView's display when something * being dragged enters it. * @@ -488,7 +498,7 @@ void ClipView::updateCursor(QMouseEvent * me) // If we are at the edges, use the resize cursor if (!me->buttons() && m_clip->manuallyResizable() && !isSelected() - && ((posX > width() - RESIZE_GRIP_WIDTH) || (posX < RESIZE_GRIP_WIDTH))) + && ((posX > width() - resizeGripWidth()) || (posX < resizeGripWidth()))) { setCursor(Qt::SizeHorCursor); } @@ -661,12 +671,12 @@ void ClipView::mousePressEvent( QMouseEvent * me ) m_action = Action::Move; setCursor( Qt::SizeAllCursor ); } - else if (pos.x() >= width() - RESIZE_GRIP_WIDTH) + else if (pos.x() >= width() - resizeGripWidth()) { m_action = Action::Resize; setCursor( Qt::SizeHorCursor ); } - else if (pos.x() < RESIZE_GRIP_WIDTH) + else if (pos.x() < resizeGripWidth()) { m_action = Action::ResizeLeft; setCursor( Qt::SizeHorCursor ); @@ -1255,7 +1265,7 @@ void ClipView::toggleSelectedAutoResize() * * \return the number of pixels per bar. */ -float ClipView::pixelsPerBar() +float ClipView::pixelsPerBar() const { return m_trackView->trackContainerView()->pixelsPerBar(); }