diff --git a/src/app/ui/timeline/timeline.cpp b/src/app/ui/timeline/timeline.cpp index 0b644f0f2..938aa82ef 100644 --- a/src/app/ui/timeline/timeline.cpp +++ b/src/app/ui/timeline/timeline.cpp @@ -62,6 +62,7 @@ #include #include +#include #include namespace app { @@ -260,7 +261,9 @@ Timeline::Timeline(TooltipManager* tooltipManager) { enableFlags(CTRL_RIGHT_CLICK); - m_ctxConn = m_context->AfterCommandExecution.connect( + m_ctxConn1 = m_context->BeforeCommandExecution.connect( + &Timeline::onBeforeCommandExecution, this); + m_ctxConn2 = m_context->AfterCommandExecution.connect( &Timeline::onAfterCommandExecution, this); m_context->documents().add_observer(this); m_context->add_observer(this); @@ -1777,15 +1780,24 @@ paintNoDoc:; skinTheme()->styles.timelinePadding()); } +void Timeline::onBeforeCommandExecution(CommandExecutionEvent& ev) +{ + m_savedCounter = (m_document ? *m_document->undoHistory()->savedCounter(): + std::numeric_limits::min()); +} + void Timeline::onAfterCommandExecution(CommandExecutionEvent& ev) { if (!m_document) return; // TODO improve this: no need to regenerate everything after each command - regenerateRows(); - showCurrentCel(); - invalidate(); + const int currentCounter = *m_document->undoHistory()->savedCounter(); + if (m_savedCounter != currentCounter) { + regenerateRows(); + showCurrentCel(); + invalidate(); + } } void Timeline::onActiveSiteChange(const Site& site) diff --git a/src/app/ui/timeline/timeline.h b/src/app/ui/timeline/timeline.h index 4c14fa094..44420d34c 100644 --- a/src/app/ui/timeline/timeline.h +++ b/src/app/ui/timeline/timeline.h @@ -162,6 +162,7 @@ namespace app { void onRemoveTag(DocEvent& ev) override; // app::Context slots. + void onBeforeCommandExecution(CommandExecutionEvent& ev); void onAfterCommandExecution(CommandExecutionEvent& ev); // ContextObserver impl @@ -392,6 +393,11 @@ namespace app { Range m_dropRange; State m_state; + // Value of DocUndo::savedCounter() before executing a + // command. Used to compare after executing a command to avoid + // regenerating all rows if it's not necessary. + int m_savedCounter; + // Data used to display each row in the timeline std::vector m_rows; @@ -410,7 +416,7 @@ namespace app { gfx::Point m_oldPos; // Configure timeline std::unique_ptr m_confPopup; - obs::scoped_connection m_ctxConn; + obs::scoped_connection m_ctxConn1, m_ctxConn2; obs::connection m_firstFrameConn; // Marching ants stuff to show the range in the clipboard.