summaryrefslogtreecommitdiffstats
path: root/svx/source/sdr/animation
diff options
context:
space:
mode:
Diffstat (limited to 'svx/source/sdr/animation')
-rw-r--r--svx/source/sdr/animation/animationstate.cxx130
-rw-r--r--svx/source/sdr/animation/objectanimator.cxx35
-rw-r--r--svx/source/sdr/animation/scheduler.cxx173
3 files changed, 338 insertions, 0 deletions
diff --git a/svx/source/sdr/animation/animationstate.cxx b/svx/source/sdr/animation/animationstate.cxx
new file mode 100644
index 0000000000..074f2082e4
--- /dev/null
+++ b/svx/source/sdr/animation/animationstate.cxx
@@ -0,0 +1,130 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <svx/sdr/animation/animationstate.hxx>
+#include <svx/sdr/contact/viewobjectcontact.hxx>
+#include <svx/sdr/animation/objectanimator.hxx>
+#include <svx/sdr/contact/objectcontact.hxx>
+#include <drawinglayer/primitive2d/animatedprimitive2d.hxx>
+#include <drawinglayer/animation/animationtiming.hxx>
+#include <comphelper/lok.hxx>
+
+
+namespace sdr::animation
+{
+ double PrimitiveAnimation::getSmallestNextTime(double fCurrentTime)
+ {
+ double fRetval(0.0);
+
+ if(!maAnimatedPrimitives.empty())
+ {
+ const sal_Int32 nCount(maAnimatedPrimitives.size());
+
+ for(sal_Int32 a(0); a < nCount; a++)
+ {
+ const drawinglayer::primitive2d::Primitive2DReference xRef(maAnimatedPrimitives[a]);
+ const drawinglayer::primitive2d::AnimatedSwitchPrimitive2D* pCandidate = static_cast< const drawinglayer::primitive2d::AnimatedSwitchPrimitive2D* >(xRef.get());
+
+ const drawinglayer::animation::AnimationEntry& rAnimEntry = pCandidate->getAnimationEntry();
+ const double fNextTime(rAnimEntry.getNextEventTime(fCurrentTime));
+
+ if(!::basegfx::fTools::equalZero(fNextTime))
+ {
+ if(::basegfx::fTools::equalZero(fRetval))
+ {
+ fRetval = fNextTime;
+ }
+ else if(::basegfx::fTools::less(fNextTime, fRetval))
+ {
+ fRetval = fNextTime;
+ }
+ }
+ }
+ }
+
+ return fRetval;
+ }
+
+ void PrimitiveAnimation::prepareNextEvent()
+ {
+ const double fCurrentTime(mrVOContact.GetObjectContact().getPrimitiveAnimator().GetTime());
+ const double fNextTime(getSmallestNextTime(fCurrentTime));
+
+ // getSmallestNextTime will be zero when animation ended. If not zero, a next step
+ // exists
+ if(::basegfx::fTools::equalZero(fNextTime))
+ return;
+
+ // next time point exists, use it
+ sal_uInt32 nNextTime;
+
+ if(fNextTime >= double(0xffffff00))
+ {
+ // take care for very late points in time, e.g. when a text animation stops
+ // in a defined AnimationEntryFixed with endless (0xffffffff) duration
+ nNextTime = GetTime() + (1000 * 60 * 60); // one hour, works with vcl timers, 0xffffff00 was too much...
+ }
+ else
+ {
+ nNextTime = static_cast<sal_uInt32>(fNextTime);
+ }
+
+ // ensure step forward in integer timing, the floating step difference maybe smaller than 1.0. Use
+ // at least 25ms for next step
+ const sal_uInt32 nMinimumStepTime(static_cast<sal_uInt32>(fCurrentTime) + 25);
+
+ if(nNextTime <= nMinimumStepTime)
+ {
+ nNextTime = nMinimumStepTime;
+ }
+
+ // set time and reactivate by re-adding to the scheduler
+ SetTime(nNextTime);
+ mrVOContact.GetObjectContact().getPrimitiveAnimator().InsertEvent(*this);
+ }
+
+ PrimitiveAnimation::PrimitiveAnimation(sdr::contact::ViewObjectContact& rVOContact, drawinglayer::primitive2d::Primitive2DContainer&& rAnimatedPrimitives)
+ : mrVOContact(rVOContact),
+ maAnimatedPrimitives(std::move(rAnimatedPrimitives))
+ {
+ if (!comphelper::LibreOfficeKit::isActive())
+ // setup initially
+ prepareNextEvent();
+ }
+
+ PrimitiveAnimation::~PrimitiveAnimation()
+ {
+ // ensure that Event member is removed from PrimitiveAnimator
+ mrVOContact.GetObjectContact().getPrimitiveAnimator().RemoveEvent(this);
+ }
+
+ // execute event, from base class Event
+ void PrimitiveAnimation::Trigger(sal_uInt32 /*nTime*/)
+ {
+ // schedule a repaint of associated object
+ mrVOContact.ActionChanged();
+
+ if (!comphelper::LibreOfficeKit::isActive())
+ // re-setup
+ prepareNextEvent();
+ }
+
+} // end of namespace
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svx/source/sdr/animation/objectanimator.cxx b/svx/source/sdr/animation/objectanimator.cxx
new file mode 100644
index 0000000000..aad545fd75
--- /dev/null
+++ b/svx/source/sdr/animation/objectanimator.cxx
@@ -0,0 +1,35 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <svx/sdr/animation/objectanimator.hxx>
+
+
+namespace sdr::animation
+{
+ primitiveAnimator::primitiveAnimator()
+ {
+ }
+
+ primitiveAnimator::~primitiveAnimator()
+ {
+ }
+
+} // end of namespace
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svx/source/sdr/animation/scheduler.cxx b/svx/source/sdr/animation/scheduler.cxx
new file mode 100644
index 0000000000..02017d915d
--- /dev/null
+++ b/svx/source/sdr/animation/scheduler.cxx
@@ -0,0 +1,173 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include <svx/sdr/animation/scheduler.hxx>
+
+#include <algorithm>
+#include <vector>
+
+
+// event class
+
+namespace sdr::animation
+{
+ Event::Event() : mnTime(0)
+ {
+ }
+
+ Event::~Event()
+ {
+ }
+
+
+ void Event::SetTime(sal_uInt32 nNew)
+ {
+ if(mnTime != nNew)
+ {
+ mnTime = nNew;
+ }
+ }
+
+ Scheduler::Scheduler()
+ : Timer("sdr::animation::Scheduler"),
+ mnTime(0),
+ mnDeltaTime(0),
+ mbIsPaused(false)
+ {
+ SetPriority(TaskPriority::POST_PAINT);
+ }
+
+ Scheduler::~Scheduler()
+ {
+ Stop();
+ }
+
+ void Scheduler::Invoke()
+ {
+ // stop timer and add time
+ Stop();
+ mnTime += mnDeltaTime;
+
+ // execute events
+ triggerEvents();
+
+ // re-start or stop timer according to event list
+ checkTimeout();
+ }
+
+ void Scheduler::triggerEvents()
+ {
+ if (mvEvents.empty())
+ return;
+
+ // copy events which need to be executed to a vector. Remove them from
+ // the scheduler
+ ::std::vector< Event* > aToBeExecutedList;
+
+ while(!mvEvents.empty() && mvEvents.front()->GetTime() <= mnTime)
+ {
+ Event* pNextEvent = mvEvents.front();
+ mvEvents.erase(mvEvents.begin());
+ aToBeExecutedList.push_back(pNextEvent);
+ }
+
+ // execute events from the vector
+ for(auto& rpCandidate : aToBeExecutedList)
+ {
+ // trigger event. This may re-insert the event to the scheduler again
+ rpCandidate->Trigger(mnTime);
+ }
+ }
+
+ void Scheduler::checkTimeout()
+ {
+ // re-start or stop timer according to event list
+ if(!IsPaused() && !mvEvents.empty())
+ {
+ mnDeltaTime = mvEvents.front()->GetTime() - mnTime;
+
+ if(0 != mnDeltaTime)
+ {
+ SetTimeout(mnDeltaTime);
+ Start();
+ }
+ }
+ else
+ {
+ Stop();
+ }
+ }
+
+
+ // #i38135#
+ void Scheduler::SetTime(sal_uInt32 nTime)
+ {
+ // reset time
+ Stop();
+ mnTime = nTime;
+
+ if (mvEvents.empty())
+ return;
+
+ // reset event time points
+ for (auto & rEvent : mvEvents)
+ {
+ rEvent->SetTime(nTime);
+ }
+
+ if(!IsPaused())
+ {
+ // without delta time, init events by triggering them. This will invalidate
+ // painted objects and add them to the scheduler again
+ mnDeltaTime = 0;
+ triggerEvents();
+ checkTimeout();
+ }
+ }
+
+ void Scheduler::InsertEvent(Event& rNew)
+ {
+ // insert maintaining time ordering
+ auto it = std::find_if(mvEvents.begin(), mvEvents.end(),
+ [&rNew](const Event* pEvent) { return rNew.GetTime() < pEvent->GetTime(); });
+ mvEvents.insert(it, &rNew);
+ checkTimeout();
+ }
+
+ void Scheduler::RemoveEvent(Event* pOld)
+ {
+ if(!mvEvents.empty())
+ {
+ std::erase(mvEvents, pOld);
+ checkTimeout();
+ }
+ }
+
+ void Scheduler::SetPaused(bool bNew)
+ {
+ if(bNew != mbIsPaused)
+ {
+ mbIsPaused = bNew;
+ checkTimeout();
+ }
+ }
+
+} // end of namespace
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */