Members of the KDE Community are recommended to subscribe to the kde-community mailing list at https://mail.kde.org/mailman/listinfo/kde-community to allow them to participate in important discussions and receive other important announcements

Make spacer tool functionnal

parent 76d4f610
......@@ -22,7 +22,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
#include "timelinefunctions.hpp"
#include "core.h"
#include <klocalizedstring.h>"Rename
#include <klocalizedstring.h>
#include <QDebug>
bool TimelineFunction::requestClipCut(std::shared_ptr<TimelineItemModel> timeline, int clipId, int position)
......@@ -52,12 +52,38 @@ bool TimelineFunction::requestClipCut(std::shared_ptr<TimelineItemModel> timelin
return res;
}
int TimelineFunction::requestSpacerOperation(std::shared_ptr<TimelineItemModel> timeline, int trackId, int delta, int position)
int TimelineFunction::requestSpacerStartOperation(std::shared_ptr<TimelineItemModel> timeline, int trackId, int position)
{
std::unordered_set<int> clips = timeline->getItemsAfterPosition(-1, position);
qDebug()<<"/// FOUND CLIPS: "<<clips.size();
std::unordered_set<int> clips = timeline->getItemsAfterPosition(trackId, position);
if (clips.size() > 0) {
return timeline->requestClipsGroup(clips);
timeline->requestClipsGroup(clips, false);
return (*clips.cbegin());
}
return -1;
}
bool TimelineFunction::requestSpacerEndOperation(std::shared_ptr<TimelineItemModel> timeline, int clipId, int startPosition, int endPosition)
{
// Move group back to original position
int track = timeline->getItemTrackId(clipId);
timeline->requestClipMove(clipId, track, startPosition, false, false);
std::unordered_set<int> clips = timeline->getGroupElements(clipId);
// break group
timeline->requestClipUngroup(clipId, false);
// Start undoable command
std::function<bool(void)> undo = []() { return true; };
std::function<bool(void)> redo = []() { return true; };
int res = timeline->requestClipsGroup(clips, undo, redo);
bool final = false;
if (res > -1) {
final = timeline->requestGroupMove(clipId, res, 0, endPosition - startPosition, true, undo, redo);
}
if (final) {
final = timeline->requestClipUngroup(clipId, undo, redo);
}
if (final) {
pCore->pushUndo(undo, redo, i18n("Insert space"));
return true;
}
return false;
}
......@@ -34,7 +34,8 @@ along with this program. If not, see <http://www.gnu.org/licenses/>.
namespace TimelineFunction {
bool requestClipCut(std::shared_ptr<TimelineItemModel> timeline, int clipId, int position);
int requestSpacerOperation(std::shared_ptr<TimelineItemModel> timeline, int trackId, int delta, int position);
int requestSpacerStartOperation(std::shared_ptr<TimelineItemModel> timeline, int trackId, int position);
bool requestSpacerEndOperation(std::shared_ptr<TimelineItemModel> timeline, int clipId, int startPosition, int endPosition);
}
......
......@@ -484,7 +484,7 @@ bool TimelineModel::requestItemDeletion(int itemId, bool logUndo)
QWriteLocker locker(&m_lock);
Q_ASSERT(isClip(itemId) || isComposition(itemId));
if (m_groups->isInGroup(itemId)) {
return requestGroupDeletion(itemId);
return requestGroupDeletion(itemId, logUndo);
}
Fun undo = []() { return true; };
Fun redo = []() { return true; };
......@@ -574,14 +574,23 @@ std::unordered_set<int> TimelineModel::getItemsAfterPosition(int trackId, int po
}
bool TimelineModel::requestGroupMove(int clipId, int groupId, int delta_track, int delta_pos, bool updateView, bool logUndo)
{
std::function<bool(void)> undo = []() { return true; };
std::function<bool(void)> redo = []() { return true; };
bool res = requestGroupMove(clipId, groupId, delta_track, delta_pos, updateView, undo, redo);
if (res && logUndo) {
PUSH_UNDO(undo, redo, i18n("Move group"));
}
return res;
}
bool TimelineModel::requestGroupMove(int clipId, int groupId, int delta_track, int delta_pos, bool updateView, Fun &undo, Fun &redo)
{
#ifdef LOGGING
m_logFile << "timeline->requestGroupMove(" << clipId << "," << groupId << " ," << delta_track << ", " << delta_pos << ", "
<< (updateView ? "true" : "false") << ", " << (logUndo ? "true" : "false") << " ); " << std::endl;
<< (updateView ? "true" : "false") << " ); " << std::endl;
#endif
QWriteLocker locker(&m_lock);
std::function<bool(void)> undo = []() { return true; };
std::function<bool(void)> redo = []() { return true; };
Q_ASSERT(m_allGroups.count(groupId) > 0);
bool ok = true;
auto all_clips = m_groups->getLeaves(groupId);
......@@ -620,13 +629,10 @@ bool TimelineModel::requestGroupMove(int clipId, int groupId, int delta_track, i
return false;
}
}
if (logUndo) {
PUSH_UNDO(undo, redo, i18n("Move group"));
}
return true;
}
bool TimelineModel::requestGroupDeletion(int clipId)
bool TimelineModel::requestGroupDeletion(int clipId, bool logUndo)
{
#ifdef LOGGING
m_logFile << "timeline->requestGroupDeletion(" << clipId << " ); " << std::endl;
......@@ -669,7 +675,9 @@ bool TimelineModel::requestGroupDeletion(int clipId)
return false;
}
}
PUSH_UNDO(undo, redo, i18n("Remove group"));
if (logUndo) {
PUSH_UNDO(undo, redo, i18n("Remove group"));
}
return true;
}
......@@ -755,7 +763,19 @@ bool TimelineModel::requestClipTrim(int clipId, int delta, bool right, bool ripp
return requestItemResize(clipId, m_allClips[clipId]->getPlaytime() - delta, right, logUndo);
}
int TimelineModel::requestClipsGroup(const std::unordered_set<int> &ids)
int TimelineModel::requestClipsGroup(const std::unordered_set<int> &ids, bool logUndo)
{
QWriteLocker locker(&m_lock);
Fun undo = []() { return true; };
Fun redo = []() { return true; };
int result = requestClipsGroup(ids, undo, redo);
if (result > -1 && logUndo) {
PUSH_UNDO(undo, redo, i18n("Group clips"));
}
return result;
}
int TimelineModel::requestClipsGroup(const std::unordered_set<int> &ids, Fun &undo, Fun &redo)
{
#ifdef LOGGING
std::stringstream group;
......@@ -777,22 +797,17 @@ int TimelineModel::requestClipsGroup(const std::unordered_set<int> &ids)
for (int id : ids) {
if (isClip(id)) {
if (getClipTrackId(id) == -1) {
return false;
return -1;
}
} else if (!isGroup(id)) {
return false;
return -1;
}
}
Fun undo = []() { return true; };
Fun redo = []() { return true; };
int groupId = m_groups->groupItems(ids, undo, redo);
if (groupId != -1) {
PUSH_UNDO(undo, redo, i18n("Group clips"));
}
return groupId;
}
bool TimelineModel::requestClipUngroup(int id)
bool TimelineModel::requestClipUngroup(int id, bool logUndo)
{
#ifdef LOGGING
m_logFile << "timeline->requestClipUngroup(" << id << " ); " << std::endl;
......@@ -801,7 +816,7 @@ bool TimelineModel::requestClipUngroup(int id)
Fun undo = []() { return true; };
Fun redo = []() { return true; };
bool result = requestClipUngroup(id, undo, redo);
if (result) {
if (result && logUndo) {
PUSH_UNDO(undo, redo, i18n("Ungroup clips"));
}
return result;
......
......@@ -292,6 +292,7 @@ public:
@param logUndo if set to true, an undo object is created
*/
bool requestGroupMove(int clipId, int groupId, int delta_track, int delta_pos, bool updateView = true, bool logUndo = true);
bool requestGroupMove(int clipId, int groupId, int delta_track, int delta_pos, bool updateView, Fun &undo, Fun &redo);
/* @brief Deletes all clips inside the group that contains the given clip.
This action is undoable
......@@ -299,7 +300,7 @@ public:
Returns true on success. If it fails, nothing is modified.
@param clipId is the id of the clip that triggers the group deletion
*/
bool requestGroupDeletion(int clipId);
Q_INVOKABLE bool requestGroupDeletion(int clipId, bool logUndo = true);
/* @brief Change the duration of an item (clip or composition)
This action is undoable
......@@ -341,14 +342,15 @@ public:
Typically, ids would be ids of clips, but for convenience, some of them can be ids of groups as well.
@param ids Set of ids to group
*/
int requestClipsGroup(const std::unordered_set<int> &ids);
int requestClipsGroup(const std::unordered_set<int> &ids, bool logUndo = true);
int requestClipsGroup(const std::unordered_set<int> &ids, Fun &undo, Fun &redo);
/* @brief Destruct the topmost group containing clip
This action is undoable
Returns true on success. If it fails, nothing is modified.
@param id of the clip to degroup (all clips belonging to the same group will be ungrouped as well)
*/
bool requestClipUngroup(int id);
bool requestClipUngroup(int id, bool logUndo = true);
/* Same function, but accumulates undo and redo*/
bool requestClipUngroup(int id, Fun &undo, Fun &redo);
......
......@@ -87,7 +87,7 @@ Rectangle {
SystemPalette { id: activePalette }
color: Qt.darker(getColor())
border.color: selected? 'red' : borderColor
border.color: selected? 'red' : grouped ? 'yellow' : borderColor
border.width: 1.5
Drag.active: mouseArea.drag.active
Drag.proposedAction: Qt.MoveAction
......
......@@ -122,6 +122,12 @@ Column{
value: model.out
when: loader.status == Loader.Ready
}
Binding {
target: loader.item
property: "grouped"
value: model.grouped
when: loader.status == Loader.Ready
}
sourceComponent: {
if (model.isComposition) {
return compositionDelegate
......@@ -146,8 +152,6 @@ Column{
} else {
item.a_track = model.a_track
}
item.grouped= model.grouped
item.borderColor= (model.grouped ? 'yellow' : 'black')
item.trackIndex= trackRoot.DelegateModel.itemsIndex
item.trackId= trackRoot.trackId
//hash= model.hash
......
......@@ -88,6 +88,8 @@ Rectangle {
property int droppedTrack: -1
property int clipBeingMovedId: -1
property int spacerGroup: -1
property int spacerFrame: -1
property int spacerClickFrame: -1
property real timeScale: timeline.scaleFactor
property int trackHeight
......@@ -367,31 +369,39 @@ Rectangle {
timeline.seekPosition = timeline.position + (wheel.angleDelta.y > 0 ? 1 : -1)
timeline.position = timeline.seekPosition
}
onPressed: {
if (root.activeTool === 2 && mouse.y > ruler.height) {
// spacer tool
var y = mouse.y - ruler.height
var frame = (scrollView.flickableItem.contentX + mouse.x) / timeline.scaleFactor
var track = (mouse.modifiers & Qt.ControlModifier) ? tracksRepeater.itemAt(Logic.getTrackIndexFromPos(y)).trackId : -1
spacerGroup = timeline.requestSpacerStartOperation(track, frame)
if (spacerGroup > -1) {
drag.axis = Drag.XAxis
Drag.active = true
Drag.proposedAction = Qt.MoveAction
spacerClickFrame = frame
spacerFrame = controller.getClipPosition(spacerGroup)
}
}
}
onClicked: {
if (mouse.button & Qt.RightButton) {
menu.clickedX = mouse.x
menu.clickedY = mouse.y
menu.popup()
} else {
if (root.activeTool === 2 && mouse.y > ruler.height) {
// spacer tool
var y = mouse.y - ruler.height
spacerGroup = timeline.requestSpacerOperation(tracksRepeater.itemAt(Logic.getTrackIndexFromPos(y)).trackId, (scrollView.flickableItem.contentX + mouse.x) / timeline.scaleFactor)
if (spacerGroup > -1) {
//TODO: Start drag
}
} else if (root.activeTool === 1 && mouse.y > ruler.height) {
if (root.activeTool === 0 || mouse.y <= ruler.height) {
timeline.seekPosition = (scrollView.flickableItem.contentX + mouse.x) / timeline.scaleFactor
timeline.position = timeline.seekPosition
} else if (root.activeTool === 1) {
// razor tool
var y = mouse.y - ruler.height
timeline.cutClipUnderCursor((scrollView.flickableItem.contentX + mouse.x) / timeline.scaleFactor, tracksRepeater.itemAt(Logic.getTrackIndexFromPos(y)).trackId)
} else {
timeline.seekPosition = (scrollView.flickableItem.contentX + mouse.x) / timeline.scaleFactor
timeline.position = timeline.seekPosition
}
}
}
}
property bool scim: false
onReleased: scim = false
onExited: {
scim = false
}
......@@ -400,6 +410,13 @@ Rectangle {
if (root.activeTool === 0) {
timeline.seekPosition = (scrollView.flickableItem.contentX + mouse.x) / timeline.scaleFactor
timeline.position = timeline.seekPosition
} else if (root.activeTool === 2 && spacerGroup > -1) {
// Move group
var track = controller.getClipTrackId(spacerGroup)
var frame = Math.round((mouse.x + scrollView.flickableItem.contentX) / timeline.scaleFactor) + spacerFrame - spacerClickFrame
frame = controller.suggestClipMove(spacerGroup, track, frame);
controller.requestClipMove(spacerGroup, track, frame, true, false)
continuousScrolling(mouse.x + scrollView.flickableItem.contentX)
}
scim = true
}
......@@ -410,6 +427,17 @@ Rectangle {
}
}
}
onReleased: {
if (spacerGroup > -1) {
var frame = controller.getClipPosition(spacerGroup)
timeline.requestSpacerEndOperation(spacerGroup, spacerFrame, frame);
spacerClickFrame = -1
spacerFrame = -1
spacerGroup = -1
controller.request
}
scim = false
}
Timer {
id: scrubTimer
interval: 25
......
......@@ -468,9 +468,14 @@ void TimelineController::cutClipUnderCursor(int position, int track)
}
}
void TimelineController::requestSpacerOperation(int trackId, int position)
int TimelineController::requestSpacerStartOperation(int trackId, int position)
{
TimelineFunction::requestSpacerOperation(m_model, trackId, 0, position);
return TimelineFunction::requestSpacerStartOperation(m_model, trackId, position);
}
bool TimelineController::requestSpacerEndOperation(int clipId, int startPosition, int endPosition)
{
return TimelineFunction::requestSpacerEndOperation(m_model, clipId, startPosition, endPosition);
}
void TimelineController::seekCurrentClip(bool seekToEnd)
......
......@@ -193,7 +193,10 @@ public:
Q_INVOKABLE void cutClipUnderCursor(int position = -1, int track = -1);
/* @brief Request a spacer operation
*/
Q_INVOKABLE void requestSpacerOperation(int trackId, int position);
Q_INVOKABLE int requestSpacerStartOperation(int trackId, int position);
/* @brief Request a spacer operation
*/
Q_INVOKABLE bool requestSpacerEndOperation(int clipId, int startPosition, int endPosition);
/* @brief Seeks to selected clip start / end
*/
void seekCurrentClip(bool seekToEnd = false);
......
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