Improve snap behavior on group resizing

Related to #183
parent fe566c07
Pipeline #3592 passed with stage
in 13 minutes and 51 seconds
......@@ -131,3 +131,24 @@ int SnapModel::proposeSize(int in, int out, int size, bool right, int maxSnapDis
unIgnore();
return proposed_size;
}
int SnapModel::proposeSize(int in, int out, const std::vector<int> boundaries, int size, bool right, int maxSnapDist)
{
ignore(boundaries);
int proposed_size = -1;
if (right) {
int target_pos = in + size - 1;
int snapped_pos = getClosestPoint(target_pos);
if (snapped_pos != -1 && qAbs(target_pos - snapped_pos) <= maxSnapDist) {
proposed_size = snapped_pos - in;
}
} else {
int target_pos = out + 1 - size;
int snapped_pos = getClosestPoint(target_pos);
if (snapped_pos != -1 && qAbs(target_pos - snapped_pos) <= maxSnapDist) {
proposed_size = out - snapped_pos;
}
}
unIgnore();
return proposed_size;
}
......@@ -86,6 +86,7 @@ public:
@param maxSnapDist maximal number of frames we are allowed to snap to
*/
int proposeSize(int in, int out, int size, bool right, int maxSnapDist);
int proposeSize(int in, int out, const std::vector<int> boundaries, int size, bool right, int maxSnapDist);
// For testing only
std::map<int, int> _snaps() { return m_snaps; }
......
......@@ -1603,6 +1603,27 @@ void TimelineModel::processGroupResize(QVariantList startPos, QVariantList endPo
}
}
const std::vector<int> TimelineModel::getBoundaries(int itemId)
{
std::vector<int> boundaries;
std::unordered_set<int> items;
if (m_groups->isInGroup(itemId)) {
int groupId = m_groups->getRootId(itemId);
items = m_groups->getLeaves(groupId);
} else {
items.insert(itemId);
}
for (int id : items) {
if (isClip(id) || isComposition(id)) {
int in = getItemPosition(id);
int out = in + getItemPlaytime(id);
boundaries.push_back(in);
boundaries.push_back(out);
}
}
return boundaries;
}
int TimelineModel::requestItemResize(int itemId, int size, bool right, bool logUndo, int snapDistance, bool allowSingleResize)
{
if (logUndo) {
......@@ -1635,7 +1656,7 @@ int TimelineModel::requestItemResize(int itemId, int size, bool right, bool logU
}
int timelinePos = pCore->getTimelinePosition();
m_snaps->addPoint(timelinePos);
int proposed_size = m_snaps->proposeSize(in, out, size, right, snapDistance);
int proposed_size = m_snaps->proposeSize(in, out, getBoundaries(itemId), size, right, snapDistance);
m_snaps->removePoint(timelinePos);
if (proposed_size > 0) {
// only test move if proposed_size is valid
......@@ -3236,7 +3257,7 @@ void TimelineModel::setTrackLockedState(int trackId, bool lock)
} else {
getTrackById(trackId)->unlock();
}
};
}
std::unordered_set<int> TimelineModel::getAllTracksIds() const
{
......
......@@ -531,6 +531,9 @@ protected:
@returns best snap position or -1 if no snap point is near
*/
int getBestSnapPos(int pos, int length, const std::vector<int> &pts = std::vector<int>(), int cursorPosition = 0, int snapDistance = -1);
/* @brief Returns a list of in/out of all items in the group of itemId
*/
const std::vector<int> getBoundaries(int itemId);
public:
/* @brief Requests the next snapped point
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment