Search in sources :

Example 11 with TimelineChannel

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);
}
Also used : Component(com.helospark.lightdi.annotation.Component) AddExistingClipRequest(com.helospark.tactview.core.timeline.AddExistingClipRequest) UiCommandInterpreterService(com.helospark.tactview.ui.javafx.UiCommandInterpreterService) TimelinePosition(com.helospark.tactview.core.timeline.TimelinePosition) EffectCopyPasteDomainElement(com.helospark.tactview.ui.javafx.repository.copypaste.EffectCopyPasteDomain.EffectCopyPasteDomainElement) CompositeCommand(com.helospark.tactview.ui.javafx.commands.impl.CompositeCommand) AddExistingEffectCommand(com.helospark.tactview.ui.javafx.commands.impl.AddExistingEffectCommand) Collectors(java.util.stream.Collectors) TimelineClip(com.helospark.tactview.core.timeline.TimelineClip) EffectCopyPasteDomain(com.helospark.tactview.ui.javafx.repository.copypaste.EffectCopyPasteDomain) ArrayList(java.util.ArrayList) List(java.util.List) CloneRequestMetadata(com.helospark.tactview.core.clone.CloneRequestMetadata) AddExistingEffectRequest(com.helospark.tactview.core.timeline.AddExistingEffectRequest) TimelineChannel(com.helospark.tactview.core.timeline.TimelineChannel) TimelineManagerAccessor(com.helospark.tactview.core.timeline.TimelineManagerAccessor) AddExistingClipsCommand(com.helospark.tactview.ui.javafx.commands.impl.AddExistingClipsCommand) ClipCopyPasteDomain(com.helospark.tactview.ui.javafx.repository.copypaste.ClipCopyPasteDomain) StatelessEffect(com.helospark.tactview.core.timeline.StatelessEffect) Optional(java.util.Optional) TimelineChannel(com.helospark.tactview.core.timeline.TimelineChannel) ClipCopyPasteDomain(com.helospark.tactview.ui.javafx.repository.copypaste.ClipCopyPasteDomain) ArrayList(java.util.ArrayList) TimelinePosition(com.helospark.tactview.core.timeline.TimelinePosition) TimelineClip(com.helospark.tactview.core.timeline.TimelineClip)

Example 12 with TimelineChannel

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);
    }
}
Also used : TimelineChannel(com.helospark.tactview.core.timeline.TimelineChannel) TimelineInterval(com.helospark.tactview.core.timeline.TimelineInterval) TimelinePosition(com.helospark.tactview.core.timeline.TimelinePosition)

Example 13 with TimelineChannel

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;
}
Also used : ClipChannelIdPair(com.helospark.tactview.core.timeline.ClipChannelIdPair) TimelineChannel(com.helospark.tactview.core.timeline.TimelineChannel) ArrayList(java.util.ArrayList)

Example 14 with TimelineChannel

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);
}
Also used : TimelineChannel(com.helospark.tactview.core.timeline.TimelineChannel)

Example 15 with TimelineChannel

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);
}
Also used : TimelineInterval(com.helospark.tactview.core.timeline.TimelineInterval) Color(javafx.scene.paint.Color) ArrayList(java.util.ArrayList) TimelineUiCacheElement(com.helospark.tactview.ui.javafx.uicomponents.canvasdraw.domain.TimelineUiCacheElement) Font(javafx.scene.text.Font) TimelineChannel(com.helospark.tactview.core.timeline.TimelineChannel) SnapshotParameters(javafx.scene.SnapshotParameters) CollisionRectangle(com.helospark.tactview.ui.javafx.uicomponents.canvasdraw.domain.CollisionRectangle) VBox(javafx.scene.layout.VBox) NonIntersectingIntervalList(com.helospark.tactview.core.timeline.NonIntersectingIntervalList) TimelineClip(com.helospark.tactview.core.timeline.TimelineClip)

Aggregations

TimelineChannel (com.helospark.tactview.core.timeline.TimelineChannel)19 ArrayList (java.util.ArrayList)7 TimelineClip (com.helospark.tactview.core.timeline.TimelineClip)6 TimelineInterval (com.helospark.tactview.core.timeline.TimelineInterval)6 TimelinePosition (com.helospark.tactview.core.timeline.TimelinePosition)6 StatelessEffect (com.helospark.tactview.core.timeline.StatelessEffect)3 TimelineManagerAccessor (com.helospark.tactview.core.timeline.TimelineManagerAccessor)3 TimelineUiCacheElement (com.helospark.tactview.ui.javafx.uicomponents.canvasdraw.domain.TimelineUiCacheElement)3 List (java.util.List)3 Collectors (java.util.stream.Collectors)3 Component (com.helospark.lightdi.annotation.Component)2 CloneRequestMetadata (com.helospark.tactview.core.clone.CloneRequestMetadata)2 AddClipRequest (com.helospark.tactview.core.timeline.AddClipRequest)2 AddExistingClipRequest (com.helospark.tactview.core.timeline.AddExistingClipRequest)2 ClipChannelIdPair (com.helospark.tactview.core.timeline.ClipChannelIdPair)2 NotificationMessage (com.helospark.tactview.core.timeline.message.NotificationMessage)2 UiCommandInterpreterService (com.helospark.tactview.ui.javafx.UiCommandInterpreterService)2 AddClipsCommand (com.helospark.tactview.ui.javafx.commands.impl.AddClipsCommand)2 AddExistingClipsCommand (com.helospark.tactview.ui.javafx.commands.impl.AddExistingClipsCommand)2 ClipDragInformation (com.helospark.tactview.ui.javafx.repository.drag.ClipDragInformation)2