use of com.helospark.tactview.core.timeline.TimelineChannel in project tactview by helospark.
the class CopyPasteRepository method copyClip.
public void copyClip(List<String> clipIds) {
if (clipIds.size() == 0) {
return;
}
List<TimelineClip> clips = timelineManager.resolveClipIdsToClips(clipIds);
TimelinePosition minimumPosition = timelineManager.findMinimumPosition(clips).get();
TimelinePosition relativeEndPosition = clips.stream().map(a -> a.getInterval().getEndPosition().subtract(minimumPosition)).sorted((a, b) -> b.compareTo(a)).findFirst().get();
List<ClipCopyPasteDomain.CopiedClipData> copiedData = new ArrayList<>();
for (var clipId : clipIds) {
TimelineChannel timelineChannel = timelineManager.findChannelForClipId(clipId).orElse(null);
TimelineClip timelineClip = timelineManager.findClipById(clipId).map(// clone here, so changes will not affect the pasted clip
clip -> clip.cloneClip(CloneRequestMetadata.ofDefault())).orElse(null);
if (timelineChannel != null && timelineClip != null) {
TimelinePosition relativePosition = timelineClip.getInterval().getStartPosition().subtract(minimumPosition);
copiedData.add(new ClipCopyPasteDomain.CopiedClipData(timelineClip, timelineChannel, relativePosition));
}
}
clipboardContent = new ClipCopyPasteDomain(copiedData, relativeEndPosition);
}
use of com.helospark.tactview.core.timeline.TimelineChannel in project tactview by helospark.
the class ClipInsertCommand method insertClipsAt.
private void insertClipsAt(TimelinePosition positionToInsertTo, TimelineInterval combinedInterval, List<ClipChannelIdPair> removedClips) {
for (var removedClip : removedClips) {
var clip = removedClip.clip;
TimelineInterval originalInterval = clip.getInterval();
TimelinePosition relativePositionWithinCombinedInterval = originalInterval.getStartPosition().subtract(combinedInterval.getStartPosition());
TimelinePosition newPosition = positionToInsertTo.add(relativePositionWithinCombinedInterval);
clip.setInterval(originalInterval.butMoveStartPostionTo(newPosition));
TimelineChannel channel = timelineManager.findChannelWithId(removedClip.channel).get();
timelineManager.addClip(channel, clip);
}
}
use of com.helospark.tactview.core.timeline.TimelineChannel in project tactview by helospark.
the class ClipInsertCommand method removeClipsToInsert.
private List<ClipChannelIdPair> removeClipsToInsert(List<TimelineClip> clipsToMove) {
// TODO: ripple if set
List<ClipChannelIdPair> clipsRemoved = new ArrayList<>();
for (var clip : clipsToMove) {
TimelineChannel channel = timelineManager.findChannelForClipId(clip.getId()).get();
clipsRemoved.add(new ClipChannelIdPair(clip, channel.getId()));
timelineManager.removeClip(clip.getId());
}
return clipsRemoved;
}
use of com.helospark.tactview.core.timeline.TimelineChannel in project tactview by helospark.
the class DuplicateChannelCommand method execute.
@Override
public void execute() {
TimelineChannel originalChannel = timelineManager.findChannelWithId(channelId).get();
TimelineChannel clonedChannel = originalChannel.cloneChannel(CloneRequestMetadata.ofDefault());
createdChannelId = clonedChannel.getId();
int originalChannelIndex = timelineManager.findChannelIndexByChannelId(channelId).get();
timelineManager.createChannel(originalChannelIndex + 1, clonedChannel);
}
use of com.helospark.tactview.core.timeline.TimelineChannel in project tactview by helospark.
the class TimelineCanvas method redrawInternal.
public void redrawInternal(boolean fullRedraw) {
LOGGER.trace("Canvas redraw requested, fullRedraw={}, time={}", fullRedraw, System.currentTimeMillis());
graphics.setLineWidth(1.0);
timelineState.setVisibleLength(TimelineLength.ofSeconds(mapCanvasPixelToTime(canvas.getWidth())));
double timelineWidth = timelineState.secondsToPixelsWithZoom(timelineAccessor.findEndPosition().add(TimelineLength.ofSeconds(10)));
timelineWidth -= canvas.getWidth();
if (timelineWidth < 1000) {
timelineWidth = 1000;
}
bottomBar.setMin(0);
bottomBar.setMax(timelineWidth);
clearCanvas();
double visibleAreaStartY = calculateScrolledY();
if (visibleAreaStartY < 0) {
visibleAreaStartY = 0;
}
TimelineInterval visibleInterval = TimelineInterval.fromDoubles(timelineState.getTranslateDouble(), timelineState.getTimelineLengthDouble() + timelineState.getTranslateDouble());
double channelStartY = TIMELINE_TIMESCALE_HEIGHT + CHANNEL_PADDING;
if (fullRedraw || previouslyCachedImage == null) {
List<TimelineUiCacheElement> newCachedElements = new ArrayList<>();
for (int i = 0; i < timelineAccessor.getChannels().size(); ++i) {
TimelineChannel currentChannel = timelineAccessor.getChannels().get(i);
NonIntersectingIntervalList<TimelineClip> clips = currentChannel.getAllClips().shallowCopy();
double clipHeight = calculateHeight(currentChannel);
if ((channelStartY + clipHeight) >= visibleAreaStartY && (channelStartY) <= visibleAreaStartY + canvas.getHeight()) {
for (var clip : clips) {
TimelineInterval interval = clip.getGlobalInterval();
double clipX = timelineState.secondsToPixelsWidthZoomAndTranslate(interval.getStartPosition());
double clipEndX = timelineState.secondsToPixelsWidthZoomAndTranslate(interval.getEndPosition());
double clipWidth = clipEndX - clipX;
double clipY = channelStartY - visibleAreaStartY;
boolean isPrimarySelectedClip = (selectedNodeRepository.getPrimarySelectedClip().map(a -> a.equals(clip.getId())).orElse(false));
boolean isSecondarySelectedClip = (selectedNodeRepository.getSelectedClipIds().stream().filter(a -> a.equals(clip.getId())).findAny().map(a -> true).orElse(false));
drawClip(visibleInterval, clip, visibleAreaStartY, clipY);
if (isPrimarySelectedClip) {
graphics.setFill(new Color(0.0, 1.0, 1.0, 0.3));
graphics.fillRoundRect(clipX, clipY, clipWidth, MIN_CHANNEL_HEIGHT, 4, 4);
} else if (isSecondarySelectedClip) {
graphics.setFill(new Color(0.0, 1.0, 1.0, 0.2));
graphics.fillRoundRect(clipX, clipY, clipWidth, MIN_CHANNEL_HEIGHT, 4, 4);
}
newCachedElements.add(new TimelineUiCacheElement(clip.getId(), TimelineUiCacheType.CLIP, new CollisionRectangle(clipX, clipY, clipWidth, MIN_CHANNEL_HEIGHT)));
List<NonIntersectingIntervalList<StatelessEffect>> effects = shallowCloneEffects(clip.getEffectChannels());
for (int j = 0; j < effects.size(); ++j) {
for (var effect : effects.get(j)) {
double effectX = timelineState.secondsToPixelsWidthZoomAndTranslate(effect.getGlobalInterval().getStartPosition());
double effectEndX = timelineState.secondsToPixelsWidthZoomAndTranslate(effect.getGlobalInterval().getEndPosition());
double effectY = clipY + MIN_CHANNEL_HEIGHT + EFFECT_HEIGHT * j;
if (effectEndX > clipEndX) {
effectEndX = clipEndX;
}
if (effectX < clipX) {
effectX = clipX;
}
double effectWidth = effectEndX - effectX;
double effectHeight = EFFECT_HEIGHT;
if (effectWidth < 0) {
continue;
}
boolean isPrimarySelectedEffect = (selectedNodeRepository.getPrimarySelectedEffect().map(a -> a.equals(effect.getId())).orElse(false));
boolean isSecondarySelectedEffect = (selectedNodeRepository.getSelectedEffectIds().stream().filter(a -> a.equals(effect.getId())).findAny().map(a -> true).orElse(false));
if (isPrimarySelectedEffect) {
graphics.setFill(new Color(0, 1, 1, 1));
} else if (isSecondarySelectedEffect) {
graphics.setFill(new Color(0, 0.8, 0.8, 1));
} else {
graphics.setFill(new Color(0, 0.5, 0.5, 1));
}
graphics.fillRoundRect(effectX, effectY, effectWidth, effectHeight - 1, 12, 12);
graphics.setFont(new Font(10.0));
graphics.setStroke(Color.WHITE);
graphics.setTextAlign(TextAlignment.LEFT);
graphics.save();
graphics.beginPath();
graphics.rect(effectX, effectY, effectWidth, effectHeight);
graphics.clip();
String name = Optional.ofNullable(nameToIdRepository.getNameForId(effect.getId())).orElse(effect.getId());
graphics.strokeText(name, effectX + 2, effectY + effectHeight / 2.0);
graphics.restore();
newCachedElements.add(new TimelineUiCacheElement(effect.getId(), TimelineUiCacheType.EFFECT, new CollisionRectangle(effectX, effectY, effectWidth, effectHeight)));
}
}
}
graphics.setStroke(Color.GRAY);
graphics.setLineWidth(0.8);
graphics.strokeLine(0, channelStartY + clipHeight + CHANNEL_PADDING - visibleAreaStartY, canvas.getWidth(), channelStartY + clipHeight + CHANNEL_PADDING - visibleAreaStartY);
}
double rowHeight = clipHeight + CHANNEL_PADDING * 2;
channelStartY += rowHeight;
VBox channelTitleVBox = (VBox) timelineState.getChannelTitlesAsNodes().get(i);
channelTitleVBox.setMinHeight(rowHeight);
channelTitleVBox.setMaxHeight(rowHeight);
channelTitleVBox.setPrefHeight(rowHeight);
}
rightBar.setMax(channelStartY);
drawTimelineTitles();
previouslyCachedImage = canvas.snapshot(new SnapshotParameters(), null);
cachedVisibleElements = newCachedElements;
} else {
graphics.drawImage(previouslyCachedImage, 0, 0);
}
drawSelectionBox();
drawLoopingLines();
drawChapterLines();
drawPlaybackLine();
drawSpecialPositionLine(visibleAreaStartY);
}
Aggregations