Skip to content

Commit

Permalink
shift drag keys
Browse files Browse the repository at this point in the history
  • Loading branch information
pandrr committed Feb 11, 2025
1 parent 47790d5 commit 422e686
Show file tree
Hide file tree
Showing 4 changed files with 149 additions and 51 deletions.
16 changes: 16 additions & 0 deletions src/ui/core_extend_patch.js
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,22 @@ export default function extendCorePatch()
return ops;
};

CABLES.Patch.prototype.getAllAnimPorts = function ()
{
const ports = [];
const ops = gui.corePatch().ops;
for (let i = 0; i < ops.length; i++)
{
for (let j = 0; j < ops[i].portsIn.length; j++)
{
if (ops[i].portsIn[j].isAnimated())ports.push(ops[i].portsIn[j]);

}
}

return ports;
};

CABLES.Patch.prototype.reloadOp = function (objName, cb, refOldOp)
{
let count = 0;
Expand Down
136 changes: 96 additions & 40 deletions src/ui/gltimeline/gltimeline.js
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ export default class GlTimeline extends Events

#layout = 0;

/** @type {Array<Core.Key>} */
#selectedKeys = [];

hoverKeyRect = null;
Expand Down Expand Up @@ -253,10 +254,13 @@ export default class GlTimeline extends Events
this.updateAllElements();
}

snapTime(t)
/**
* @param {number} time
*/
snapTime(time)
{
if (this.cfg.restrictToFrames) t = Math.floor(t * this.fps) / this.fps;
return t;
if (this.cfg.restrictToFrames) time = Math.floor(time * this.fps) / this.fps;
return time;
}

toggleGraphLayout()
Expand Down Expand Up @@ -316,8 +320,8 @@ export default class GlTimeline extends Events

this.#rectSelect.setPosition(this.#lastXnoButton, this.#lastYnoButton, -1);
this.#rectSelect.setSize(x - this.#lastXnoButton, y - this.#lastYnoButton);

}

if (y < this.getFirstLinePosy())
{
gui.corePatch().timer.setTime(this.snapTime(this.view.pixelToTime(e.offsetX - this.titleSpace) + this.view.offset));
Expand Down Expand Up @@ -411,6 +415,18 @@ export default class GlTimeline extends Events
this.updateAllElements();
}

getSelectedKeysBoundsTime()
{
let min = 999999;
let max = -999999;
for (let i = 0; i < this.#selectedKeys.length; i++)
{
min = Math.min(min, this.#selectedKeys[i].time);
max = Math.max(max, this.#selectedKeys[i].time);
}
return { "min": min, "max": max };
}

deleteSelectedKeys()
{
for (let i = 0; i < this.#selectedKeys.length; i++)
Expand Down Expand Up @@ -440,8 +456,9 @@ export default class GlTimeline extends Events
{
if (!e.pointerType) return;

if (this.hoverKeyRect == null)
this.unSelectAllKeys();
if (e.buttons == 1)
if (this.hoverKeyRect == null)
this.unSelectAllKeys();

try { this.#cgl.canvas.setPointerCapture(e.pointerId); }
catch (er) { this._log.log(er); }
Expand Down Expand Up @@ -714,16 +731,68 @@ export default class GlTimeline extends Events
/**
* @param {ClipboardEvent} event
*/
copy(event)
copy(event = null)
{
const obj = { "keys": this.serializeSelectedKeys() };
const objStr = JSON.stringify(obj);

console.log("copy", obj);
if (event)
{
const objStr = JSON.stringify(obj);
event.clipboardData.setData("text/plain", objStr);
event.preventDefault();
}
return obj;

event.clipboardData.setData("text/plain", objStr);
event.preventDefault();
}

/**
* @param {ClipboardEvent} event
*/
cut(event)
{
this.copy(event);
this.deleteSelectedKeys();
}

/**
* @param {Array<AnimKey>} keys
* @param {boolean} setCursorTime=true
*/
deserializeKeys(keys, setCursorTime = true)
{

let minTime = Number.MAX_VALUE;
for (let i in keys)
{
minTime = Math.min(minTime, keys[i].t);
}
let notfoundallAnims = false;

for (let i = 0; i < keys.length; i++)
{
console.log("add key...");
const k = keys[i];
if (setCursorTime)
{
k.t = k.t - minTime + this.cursorTime;
}

let found = false;
for (let j = 0; j < this.#tlAnims.length; j++)
{
let an = this.#tlAnims[j].getAnimByName(k.animName);
if (an)
{
an.addKey(new CABLES.ANIM.Key(keys[i]));
found = true;
}
}

if (!found)
notfoundallAnims = true;

}
return notfoundallAnims;
}

/**
Expand All @@ -744,35 +813,7 @@ export default class GlTimeline extends Events
{
if (json.keys)
{

let minTime = Number.MAX_VALUE;
for (let i in json.keys)
{
minTime = Math.min(minTime, json.keys[i].t);
}
let notfoundallAnims = false;

for (let i = 0; i < json.keys.length; i++)
{
const k = json.keys[i];
k.t = k.t - minTime + this.cursorTime;

let found = false;
for (let j = 0; j < this.#tlAnims.length; j++)
{
let an = this.#tlAnims[j].getAnimByName(k.animName);
if (an)
{
an.addKey(new CABLES.ANIM.Key(json.keys[i]));
found = true;
}
}

if (!found)
notfoundallAnims = true;

}

const notfoundallAnims = this.deserializeKeys(json.keys);
if (notfoundallAnims)
{
notifyWarn("could not find all anims for pasted keys");
Expand All @@ -782,6 +823,13 @@ export default class GlTimeline extends Events
notify(json.keys.length + " keys pasted");
}

const animPorts = gui.corePatch().getAllAnimPorts();
for (let i = 0; i < animPorts.length; i++)
{

if (animPorts[i].anim)
animPorts[i].anim.removeDuplicates();
}
// anim.sortKeys();

// for (let i in anim.keys)
Expand All @@ -804,4 +852,12 @@ export default class GlTimeline extends Events
return true;
}

duplicateSelectedKeys()
{
const o = this.copy();

this.deserializeKeys(o.keys, false);

}

}
5 changes: 3 additions & 2 deletions src/ui/gltimeline/gltlanimline.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ export default class glTlAnimLine extends Events

/**
* @param {GlTimeline} glTl
* @param {Array<Port>} ports
* @param {Array<Core.Port>} ports
* @param {Object} options
*/
constructor(glTl, ports, options = {})
Expand Down Expand Up @@ -101,7 +101,8 @@ export default class glTlAnimLine extends Events

const lid = anim.addEventListener("onChange", () =>
{
keys.init();
if (!keys.isDragging())
keys.init();
});

this.#animChangeListeners.push({ "id": lid, "anim": anim });
Expand Down
43 changes: 34 additions & 9 deletions src/ui/gltimeline/gltlkeys.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,8 @@ export default class glTlKeys extends Events
#points = [];
#options = {};

#dragStarted = false;

/**
* @param {GlTimeline} glTl
* @param {Anim} anim
Expand Down Expand Up @@ -75,7 +77,11 @@ export default class glTlKeys extends Events

this.points = [];
this.init();
}

isDragging()
{
return this.#dragStarted;
}

get anim()
Expand Down Expand Up @@ -256,27 +262,46 @@ export default class glTlKeys extends Events
kr.on(GlRect.EVENT_DRAGEND, () =>
{
this.#anim.sortKeys();
this.#dragStarted = false;
});

kr.on(GlRect.EVENT_DRAGSTART, (rect, x, y, button, e) =>
{
startDrag = this.#glTl.view.pixelToTime(e.offsetX);

if (button == 1 && !this.#dragStarted)
{
this.#dragStarted = true;
startDrag = this.#glTl.view.pixelToTime(e.offsetX);

console.log("dragstart", button, e.shiftKey);

if (e.shiftKey)
{
this.#glTl.duplicateSelectedKeys();
}

}
});

kr.on(GlRect.EVENT_DRAG, (rect, offx, offy, button, e) =>
{
if (this.#glTl.selectRect) return;

const offTime = this.#glTl.view.pixelToTime(e.offsetX) - startDrag;
startDrag = this.#glTl.view.pixelToTime(e.offsetX);

if (this.#glTl.getNumSelectedKeys() > 0)
if (button == 1)
{
this.#glTl.moveSelectedKeysDelta(offTime);
this.#anim.sortKeys();
}

this.update(0, 0);
const offTime = this.#glTl.view.pixelToTime(e.offsetX) - startDrag;
startDrag = this.#glTl.snapTime(this.#glTl.view.pixelToTime(e.offsetX));

if (this.#glTl.getNumSelectedKeys() > 0)
{
this.#glTl.moveSelectedKeysDelta(this.#glTl.snapTime(offTime));
this.#anim.sortKeys();
}

this.update(0, 0);

}
});

this.#keyRects.push(kr);
Expand Down

0 comments on commit 422e686

Please sign in to comment.