blob: 35426edbd47f1365178db259db27a92e6c680e72 [file] [log] [blame]
/**************************************************************
*
* 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
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sdext.hxx"
#include "PresenterPaneAnimator.hxx"
#include "PresenterAnimation.hxx"
#include "PresenterAnimator.hxx"
#include "PresenterCanvasHelper.hxx"
#include "PresenterController.hxx"
#include "PresenterGeometryHelper.hxx"
#include "PresenterPaintManager.hxx"
#include "PresenterPaneContainer.hxx"
#include "PresenterPaneFactory.hxx"
#include "PresenterSprite.hxx"
#include "PresenterSpritePane.hxx"
#include "PresenterWindowManager.hxx"
#include <com/sun/star/awt/PosSize.hpp>
#include <com/sun/star/awt/XWindowPeer.hpp>
#include <com/sun/star/rendering/CompositeOperation.hpp>
#include <boost/bind.hpp>
#include <boost/bind/protect.hpp>
#include <boost/enable_shared_from_this.hpp>
using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::drawing::framework;
using ::rtl::OUString;
using ::std::vector;
namespace sdext { namespace presenter {
namespace {
class PaneGroup;
class PresenterPaneAnimatorBase
: public ::boost::enable_shared_from_this<PresenterPaneAnimatorBase>,
public PresenterPaneAnimator
{
public:
PresenterPaneAnimatorBase (
const css::uno::Reference<css::drawing::framework::XResourceId>& rxPaneId,
const ::rtl::Reference<PresenterController>& rpPresenterController,
const bool bAnimate,
const EndActions& rShowEndActions,
const EndActions& rEndEndActions);
virtual ~PresenterPaneAnimatorBase (void);
typedef ::std::vector< ::boost::function<void()> > EndOperators;
void ActivatePanes (void);
void ActivatePane (
const css::uno::Reference<css::drawing::framework::XResourceId>& rxPaneId);
void RestoreFrozenWindows (void);
void FreezePanes (const Reference<rendering::XSpriteCanvas>& rxCanvas);
protected:
::rtl::Reference<PresenterController> mpPresenterController;
::rtl::Reference<PresenterPaneContainer> mpPaneContainer;
::rtl::Reference<PresenterWindowManager> mpWindowManager;
::std::vector< ::boost::shared_ptr<PaneGroup> > maPaneGroups;
css::uno::Reference<css::drawing::framework::XResourceId> mxCenterPaneId;
bool mbDoAnimation;
EndActions maShowEndActions;
EndActions maHideEndActions;
void DeactivatePanes (void);
void ResizePane (
const css::uno::Reference<css::drawing::framework::XResourceId>& rxPaneId,
const geometry::RealRectangle2D& rBox);
void DeactivatePane (
const css::uno::Reference<css::drawing::framework::XResourceId>& rxPaneId);
};
class UnfoldInCenterAnimator : public PresenterPaneAnimatorBase
{
public:
UnfoldInCenterAnimator (
const css::uno::Reference<css::drawing::framework::XResourceId>& rxPaneId,
const ::rtl::Reference<PresenterController>& rpPresenterController,
const bool bAnimate,
const EndActions& rShowEndActions,
const EndActions& rEndEndActions);
virtual ~UnfoldInCenterAnimator (void);
virtual void ShowPane (void);
virtual void HidePane (void);
private:
geometry::RealRectangle2D maCenterPaneBox;
void SetupPaneGroups (void);
geometry::RealRectangle2D MovePanesAway (
const css::geometry::RealRectangle2D& rFreeCenterArea);
};
class MoveInFromBottomAnimator : public PresenterPaneAnimatorBase
{
public:
MoveInFromBottomAnimator(
const css::uno::Reference<css::drawing::framework::XResourceId>& rxPaneId,
const ::rtl::Reference<PresenterController>& rpPresenterController,
const bool bAnimate,
const EndActions& rShowEndActions,
const EndActions& rEndEndActions);
virtual ~MoveInFromBottomAnimator (void);
virtual void ShowPane (void);
virtual void HidePane (void);
private:
::boost::shared_ptr<PresenterSprite> maNewPaneSprite;
geometry::RealRectangle2D maCenterPaneBox;
void CreateShowAnimation (
const css::uno::Reference<css::drawing::framework::XResourceId>& rxPaneId,
const EndOperators& rpEndOperators,
const css::uno::Reference<css::rendering::XSpriteCanvas>& rxSpriteCanvas,
const bool bAnimate,
const css::geometry::RealPoint2D& rStartLocation,
const css::geometry::RealPoint2D& rEndLocation);
};
class TransparentOverlayAnimator : public PresenterPaneAnimatorBase
{
public:
TransparentOverlayAnimator(
const css::uno::Reference<css::drawing::framework::XResourceId>& rxPaneId,
const ::rtl::Reference<PresenterController>& rpPresenterController,
const bool bAnimate,
const EndActions& rShowEndActions,
const EndActions& rEndEndActions);
virtual ~TransparentOverlayAnimator (void);
virtual void ShowPane (void);
virtual void HidePane (void);
private:
PresenterSprite maBackgroundSprite;
void CreateBackgroundSprite (void);
};
class PaneDescriptor
{
public:
PresenterPaneContainer::SharedPaneDescriptor mpPaneDescriptor;
PaneDescriptor (const PresenterPaneContainer::SharedPaneDescriptor& rpDescriptor);
void Restore (void) const;
private:
double mnLeft;
double mnTop;
double mnRight;
double mnBottom;
};
class MultiAnimation : public PresenterAnimation
{
public:
typedef ::boost::function<void(double)> Animation;
MultiAnimation (const sal_uInt32 nDuration);
void AddAnimation (const Animation& rAnimation);
virtual void Run (const double nProgress, const sal_uInt64 nCurrentTime);
private:
vector<Animation> maAnimations;
};
class PaneGroup
{
public:
PaneGroup (void);
~PaneGroup (void);
void AddPane (const PresenterPaneContainer::SharedPaneDescriptor& rpPane);
void CreateSubstitution (const Reference<rendering::XSpriteCanvas>& rxCanvas);
void ThawPanes (void);
void Restore (void);
::boost::shared_ptr<PresenterSprite> GetSubstitution (void);
css::geometry::RealRectangle2D GetOriginalBoundingBox (void) const;
css::geometry::RealRectangle2D GetCurrentBoundingBox (void) const;
void MovePanes (
const double nXOffset,
const double nYOffset,
const ::rtl::Reference<PresenterWindowManager>& rpWindowManager);
void ActivatePanes (void);
void DeactivatePanes (void);
void HidePanes (void);
void ShowPanes (void);
private:
vector<PaneDescriptor> maPanes;
awt::Rectangle maOriginalBoundingBox;
css::geometry::RealRectangle2D maCurrentBoundingBox;
::boost::shared_ptr<PresenterSprite> mpSubstitution;
};
typedef ::boost::shared_ptr<PaneGroup> SharedPaneGroup;
void InterpolatePosition (
const ::boost::function<void(geometry::RealPoint2D)>& rSetter,
double nP,
const geometry::RealPoint2D rInitialBox,
const geometry::RealPoint2D rFinalBox);
template<typename T>
void InterpolateValue (
const ::boost::function<void(T)>& rSetter,
double nP,
const T aInitialValue,
const T aFinalValue);
void SpriteTransform(
const rtl::Reference<PresenterPaneContainer>& rpPaneContainer,
const Reference<XResourceId>& rxPaneId,
const Reference<awt::XWindow>& rxSpriteOwnerWindow,
const ::boost::shared_ptr<PresenterPaintManager>& rpPaintManager,
const bool bAppear,
const double nX,
const double nInitialTop,
const double nFinalTop,
const double nP);
void SpritePaneMove (
const rtl::Reference<PresenterPaneContainer>& rpPaneContainer,
const Reference<XResourceId>& rxPaneId,
const geometry::RealPoint2D& rLocation);
geometry::RealPoint2D GetLocation (const geometry::RealRectangle2D& rBox);
geometry::RealSize2D GetSize (const geometry::RealRectangle2D& rBox);
} // end of anonymous namespace
//=============================================================================
::boost::shared_ptr<PresenterPaneAnimator> CreateUnfoldInCenterAnimator (
const css::uno::Reference<css::drawing::framework::XResourceId>& rxPaneId,
const ::rtl::Reference<PresenterController>& rpPresenterController,
const bool bAnimate,
const EndActions& rShowEndActions,
const EndActions& rEndEndActions)
{
return ::boost::shared_ptr<PresenterPaneAnimator>(
new UnfoldInCenterAnimator(rxPaneId, rpPresenterController, bAnimate,
rShowEndActions, rEndEndActions));
}
::boost::shared_ptr<PresenterPaneAnimator> CreateMoveInFromBottomAnimator (
const css::uno::Reference<css::drawing::framework::XResourceId>& rxPaneId,
const ::rtl::Reference<PresenterController>& rpPresenterController,
const bool bAnimate,
const EndActions& rShowEndActions,
const EndActions& rEndEndActions)
{
return ::boost::shared_ptr<PresenterPaneAnimator>(
new MoveInFromBottomAnimator(rxPaneId, rpPresenterController, bAnimate,
rShowEndActions, rEndEndActions));
}
::boost::shared_ptr<PresenterPaneAnimator> CreateTransparentOverlay (
const css::uno::Reference<css::drawing::framework::XResourceId>& rxPaneId,
const ::rtl::Reference<PresenterController>& rpPresenterController,
const bool bAnimate,
const EndActions& rShowEndActions,
const EndActions& rEndEndActions)
{
return ::boost::shared_ptr<PresenterPaneAnimator>(
new TransparentOverlayAnimator(rxPaneId, rpPresenterController, bAnimate,
rShowEndActions, rEndEndActions));
}
//===== PresenterPaneAnimator =================================================
namespace {
PresenterPaneAnimatorBase::PresenterPaneAnimatorBase (
const css::uno::Reference<css::drawing::framework::XResourceId>& rxPaneId,
const ::rtl::Reference<PresenterController>& rpPresenterController,
const bool bAnimate,
const EndActions& rShowEndActions,
const EndActions& rHideEndActions)
: mpPresenterController(rpPresenterController),
mpPaneContainer(rpPresenterController->GetPaneContainer()),
mpWindowManager(rpPresenterController->GetWindowManager()),
maPaneGroups(),
mxCenterPaneId(rxPaneId),
mbDoAnimation(bAnimate),
maShowEndActions(rShowEndActions),
maHideEndActions(rHideEndActions)
{
}
PresenterPaneAnimatorBase::~PresenterPaneAnimatorBase (void)
{
}
void PresenterPaneAnimatorBase::FreezePanes (const Reference<rendering::XSpriteCanvas>& rxCanvas)
{
::std::vector<SharedPaneGroup>::const_iterator iGroup;
for (iGroup=maPaneGroups.begin(); iGroup!=maPaneGroups.end(); ++iGroup)
{
(*iGroup)->CreateSubstitution(rxCanvas);
(*iGroup)->GetSubstitution()->MoveTo(GetLocation((*iGroup)->GetOriginalBoundingBox()));
}
}
void PresenterPaneAnimatorBase::ActivatePanes (void)
{
ActivatePane(mxCenterPaneId);
::std::vector<SharedPaneGroup>::const_iterator iGroup;
for (iGroup=maPaneGroups.begin(); iGroup!=maPaneGroups.end(); ++iGroup)
{
(*iGroup)->ShowPanes();
(*iGroup)->ActivatePanes();
(*iGroup)->GetSubstitution()->Hide();
}
mpWindowManager->Update();
}
void PresenterPaneAnimatorBase::DeactivatePanes (void)
{
::std::vector<SharedPaneGroup>::const_iterator iGroup;
for (iGroup=maPaneGroups.begin(); iGroup!=maPaneGroups.end(); ++iGroup)
{
(*iGroup)->GetSubstitution()->Show();
(*iGroup)->DeactivatePanes();
(*iGroup)->HidePanes();
}
mpWindowManager->Update();
}
void PresenterPaneAnimatorBase::ResizePane (
const Reference<drawing::framework::XResourceId>& rxPaneId,
const geometry::RealRectangle2D& rBox)
{
PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
mpPaneContainer->FindPaneId(rxPaneId));
if (pDescriptor.get() != NULL)
{
mpWindowManager->SetPanePosSizeAbsolute (
rxPaneId->getResourceURL(),
rBox.X1,
rBox.Y1,
rBox.X2-rBox.X1,
rBox.Y2-rBox.Y1);
mpWindowManager->Layout();
if ( ! pDescriptor->maSpriteProvider.empty())
{
pDescriptor->maSpriteProvider()->Resize(GetSize(rBox));
}
}
}
void PresenterPaneAnimatorBase::RestoreFrozenWindows (void)
{
::std::vector<SharedPaneGroup>::const_iterator iGroup;
for (iGroup=maPaneGroups.begin(); iGroup!=maPaneGroups.end(); ++iGroup)
{
(*iGroup)->Restore();
(*iGroup)->ShowPanes();
(*iGroup)->ActivatePanes();
(*iGroup)->GetSubstitution()->Hide();
}
maPaneGroups.clear();
ActivatePane(mxCenterPaneId);
mpWindowManager->Update();
}
void PresenterPaneAnimatorBase::ActivatePane (
const Reference<drawing::framework::XResourceId>& rxPaneId)
{
PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
mpPaneContainer->FindPaneId(rxPaneId));
if (pDescriptor.get() != NULL)
pDescriptor->SetActivationState(true);
}
void PresenterPaneAnimatorBase::DeactivatePane (
const Reference<drawing::framework::XResourceId>& rxPaneId)
{
PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
mpPaneContainer->FindPaneId(rxPaneId));
if (pDescriptor.get() != NULL)
pDescriptor->SetActivationState(false);
}
//===== UnfoldInCenterAnimator ================================================
UnfoldInCenterAnimator::UnfoldInCenterAnimator (
const css::uno::Reference<css::drawing::framework::XResourceId>& rxPaneId,
const ::rtl::Reference<PresenterController>& rpPresenterController,
const bool bAnimate,
const EndActions& rShowEndActions,
const EndActions& rEndEndActions)
: PresenterPaneAnimatorBase(rxPaneId, rpPresenterController, bAnimate,
rShowEndActions, rEndEndActions)
{
}
UnfoldInCenterAnimator::~UnfoldInCenterAnimator (void)
{
}
void UnfoldInCenterAnimator::ShowPane (void)
{
OSL_ASSERT(mpWindowManager.get()!=NULL);
Reference<awt::XWindow> xParentWindow (mpWindowManager->GetParentWindow(), UNO_QUERY);
if ( ! xParentWindow.is())
return;
Reference<rendering::XSpriteCanvas> xCanvas (mpWindowManager->GetParentCanvas(), UNO_QUERY);
if ( ! xCanvas.is())
return;
Reference<rendering::XBitmap> xParentBitmap (xCanvas, UNO_QUERY);
if ( ! xParentBitmap.is())
return;
Reference<rendering::XGraphicDevice> xDevice(xCanvas->getDevice());
if ( ! xDevice.is())
return;
awt::Rectangle aWindowBox (xParentWindow->getPosSize());
// Create two pane groups that will be moved together. One contains the
// notes view, the other group contains all other panes.
SetupPaneGroups();
// Setup the places where the two pane groups are moved to.
maCenterPaneBox
= MovePanesAway(geometry::RealRectangle2D(0,200,aWindowBox.Width, aWindowBox.Height-200));
// Setup the final size of the new pane so that it fits into the space
// between the two pane groups.
ResizePane(mxCenterPaneId, maCenterPaneBox);
// Avoid that the center pane updates its previews while being animated.
DeactivatePane(mxCenterPaneId);
// Replace the pane groups with sprites that look like the panes but can
// be moved around much faster.
FreezePanes(xCanvas);
// The vertical center of the new pane.
const double nY0 ((maPaneGroups[0]->GetOriginalBoundingBox().Y2
+ maPaneGroups[1]->GetOriginalBoundingBox().Y1) / 2);
// Make sure that the new pane is painted once before the animation starts.
SpriteTransform(
mpPaneContainer,
mxCenterPaneId,
xParentWindow,
mpPresenterController->GetPaintManager(),
true,
maCenterPaneBox.X1,
nY0,
maCenterPaneBox.Y1,
0);
PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
mpPaneContainer->FindPaneId(mxCenterPaneId));
if (pDescriptor.get() != NULL)
{
mpPresenterController->GetPaintManager()->Invalidate(
pDescriptor->mxBorderWindow,
true);
}
// Animate the upper and lower window bitmaps.
::boost::shared_ptr<MultiAnimation> pMultiAnimation (
new MultiAnimation(mbDoAnimation ? 500 : 0));
// Animate the pane group sprites to be moved up or down.
vector<SharedPaneGroup>::const_iterator iGroup;
for (iGroup=maPaneGroups.begin(); iGroup!=maPaneGroups.end(); ++iGroup)
{
pMultiAnimation->AddAnimation(
::boost::bind(
InterpolatePosition,
::boost::protect(::boost::bind(
&PresenterSprite::MoveTo, (*iGroup)->GetSubstitution(), _1)),
_1,
GetLocation((*iGroup)->GetOriginalBoundingBox()),
GetLocation((*iGroup)->GetCurrentBoundingBox())));
}
// Animate the new center pane to expand.
pMultiAnimation->AddAnimation(
::boost::bind(
SpriteTransform,
mpPaneContainer,
mxCenterPaneId,
xParentWindow,
mpPresenterController->GetPaintManager(),
true,
maCenterPaneBox.X1,
nY0,
maCenterPaneBox.Y1,
_1));
// Call updateScreen after each animation step.
if (xCanvas.is())
pMultiAnimation->AddAnimation(
::boost::bind(&rendering::XSpriteCanvas::updateScreen, xCanvas, sal_False));
// Activate the panes when the animation is over.
pMultiAnimation->AddEndCallback(
::boost::bind(&PresenterPaneAnimatorBase::ActivatePanes, shared_from_this()));
EndActions::const_iterator iAction;
for (iAction=maShowEndActions.begin(); iAction!=maShowEndActions.end(); ++iAction)
pMultiAnimation->AddEndCallback(*iAction);
// Start the animation.
::boost::shared_ptr<PresenterAnimator> pAnimator (mpPresenterController->GetAnimator());
OSL_ASSERT(pAnimator.get()!=NULL);
pAnimator->AddAnimation(SharedPresenterAnimation(pMultiAnimation));
mpWindowManager->Update();
}
void UnfoldInCenterAnimator::HidePane (void)
{
OSL_ASSERT(mpWindowManager.get()!=NULL);
Reference<awt::XWindow> xParentWindow (mpWindowManager->GetParentWindow(), UNO_QUERY);
if ( ! xParentWindow.is())
return;
DeactivatePanes();
DeactivatePane(mxCenterPaneId);
::boost::shared_ptr<PresenterAnimator> pAnimator (mpPresenterController->GetAnimator());
const awt::Rectangle aWindowBox (xParentWindow->getPosSize());
const rendering::ViewState aViewState (
geometry::AffineMatrix2D(1,0,0, 0,1,0),
NULL);
const rendering::RenderState aRenderState (
geometry::AffineMatrix2D(1,0,0, 0,1,0),
NULL,
Sequence<double>(4),
rendering::CompositeOperation::SOURCE);
// Animate the uppder and lower window bitmaps.
Reference<rendering::XSpriteCanvas> xSpriteCanvas (mpWindowManager->GetParentCanvas(), UNO_QUERY);
::boost::shared_ptr<MultiAnimation> pMultiAnimation (new MultiAnimation(mbDoAnimation ? 500 : 1));
vector<SharedPaneGroup>::const_iterator iGroup;
for (iGroup=maPaneGroups.begin(); iGroup!=maPaneGroups.end(); ++iGroup)
{
pMultiAnimation->AddAnimation(
::boost::bind(
InterpolatePosition,
::boost::protect(::boost::bind(
&PresenterSprite::MoveTo, (*iGroup)->GetSubstitution(), _1)),
_1,
GetLocation((*iGroup)->GetCurrentBoundingBox()),
GetLocation((*iGroup)->GetOriginalBoundingBox())));
}
// Animate the new center pane to collapse.
const double nY0 ((maPaneGroups[0]->GetOriginalBoundingBox().Y2
+ maPaneGroups[1]->GetOriginalBoundingBox().Y1) / 2);
pMultiAnimation->AddAnimation(
::boost::bind(
SpriteTransform,
mpPaneContainer,
mxCenterPaneId,
xParentWindow,
mpPresenterController->GetPaintManager(),
false,
maCenterPaneBox.X1,
nY0,
maCenterPaneBox.Y1,
_1));
if (mbDoAnimation)
{
pMultiAnimation->AddAnimation(
::boost::bind(&rendering::XSpriteCanvas::updateScreen, xSpriteCanvas, sal_False));
}
pMultiAnimation->AddEndCallback(
::boost::bind(&PresenterPaneAnimatorBase::RestoreFrozenWindows, shared_from_this()));
EndActions::const_iterator iAction;
for (iAction=maHideEndActions.begin(); iAction!=maHideEndActions.end(); ++iAction)
pMultiAnimation->AddEndCallback(*iAction);
pAnimator->AddAnimation(SharedPresenterAnimation(pMultiAnimation));
}
void UnfoldInCenterAnimator::SetupPaneGroups (void)
{
maPaneGroups.clear();
// Setup the upper pane group.
SharedPaneGroup pUpperPanes (new PaneGroup());
pUpperPanes->AddPane(mpPaneContainer->FindPaneURL(
PresenterPaneFactory::msCurrentSlidePreviewPaneURL));
pUpperPanes->AddPane(mpPaneContainer->FindPaneURL(
PresenterPaneFactory::msNextSlidePreviewPaneURL));
pUpperPanes->AddPane(mpPaneContainer->FindPaneURL(
PresenterPaneFactory::msToolBarPaneURL));
pUpperPanes->AddPane(mpPaneContainer->FindPaneURL(
PresenterPaneFactory::msHelpPaneURL));
maPaneGroups.push_back(pUpperPanes);
// Setup the lower pane group.
SharedPaneGroup pLowerPanes (new PaneGroup());
pLowerPanes->AddPane(mpPaneContainer->FindPaneURL(
PresenterPaneFactory::msNotesPaneURL));
maPaneGroups.push_back(pLowerPanes);
}
geometry::RealRectangle2D UnfoldInCenterAnimator::MovePanesAway (
const geometry::RealRectangle2D& rFreeCenterArea)
{
SharedPaneGroup aUpperPanes = maPaneGroups[0];
SharedPaneGroup aLowerPanes = maPaneGroups[1];
// Move upper pane group out of the way.
const double nTop (rFreeCenterArea.Y1);
const double nUpperVerticalOffset (nTop - aUpperPanes->GetOriginalBoundingBox().Y2);
aUpperPanes->MovePanes(0, nUpperVerticalOffset, mpWindowManager);
// Move lower pane group out of the way.
const double nBottom (rFreeCenterArea.Y2);
const double nLowerVerticalOffset (nBottom - aLowerPanes->GetOriginalBoundingBox().Y1);
aLowerPanes->MovePanes(0, nLowerVerticalOffset, mpWindowManager);
return geometry::RealRectangle2D(
::std::min(
aUpperPanes->GetOriginalBoundingBox().X1,
aLowerPanes->GetOriginalBoundingBox().X1),
nTop+20,
::std::max(
aUpperPanes->GetOriginalBoundingBox().X2,
aLowerPanes->GetOriginalBoundingBox().X2),
nBottom-20);
}
//===== MoveInFromBottomAnimator ==============================================
MoveInFromBottomAnimator::MoveInFromBottomAnimator (
const css::uno::Reference<css::drawing::framework::XResourceId>& rxPaneId,
const ::rtl::Reference<PresenterController>& rpPresenterController,
const bool bAnimate,
const EndActions& rShowEndActions,
const EndActions& rEndEndActions)
: PresenterPaneAnimatorBase(rxPaneId, rpPresenterController, bAnimate,
rShowEndActions, rEndEndActions),
maNewPaneSprite()
{
}
MoveInFromBottomAnimator::~MoveInFromBottomAnimator (void)
{
}
void MoveInFromBottomAnimator::ShowPane (void)
{
OSL_ASSERT(mpWindowManager.get()!=NULL);
Reference<awt::XWindow> xParentWindow (mpWindowManager->GetParentWindow(), UNO_QUERY);
if ( ! xParentWindow.is())
return;
Reference<rendering::XSpriteCanvas> xCanvas (mpWindowManager->GetParentCanvas(), UNO_QUERY);
if ( ! xCanvas.is())
return;
Reference<rendering::XBitmap> xParentBitmap (xCanvas, UNO_QUERY);
if ( ! xParentBitmap.is())
return;
Reference<rendering::XGraphicDevice> xDevice(xCanvas->getDevice());
if ( ! xDevice.is())
return;
awt::Rectangle aWindowBox (xParentWindow->getPosSize());
// Create a pane group that just contains the notes view.
SharedPaneGroup pLowerPanes (new PaneGroup());
pLowerPanes->AddPane(mpPaneContainer->FindPaneURL(
PresenterPaneFactory::msNotesPaneURL));
maPaneGroups.push_back(pLowerPanes);
// Deactivate the panes that will take place in the animation.
pLowerPanes->DeactivatePanes();
DeactivatePane(mxCenterPaneId);
// Set the size of the new pane.
maCenterPaneBox = pLowerPanes->GetOriginalBoundingBox();
ResizePane(mxCenterPaneId, maCenterPaneBox);
geometry::RealPoint2D aStartLocation (maCenterPaneBox.X1, aWindowBox.Height);
geometry::RealPoint2D aEndLocation (maCenterPaneBox.X1, maCenterPaneBox.Y1);
// Get the sprite of the new pane, make it visible and move it to the
// start location.
PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
mpPaneContainer->FindPaneId(mxCenterPaneId));
if (pDescriptor.get() != NULL)
{
if (pDescriptor->mxBorderWindow.is())
pDescriptor->mxBorderWindow->setVisible(sal_True);
maNewPaneSprite = pDescriptor->maSpriteProvider();
if (maNewPaneSprite.get() != NULL)
{
maNewPaneSprite->MoveTo(aStartLocation);
maNewPaneSprite->Show();
}
xCanvas->updateScreen(sal_False);
}
CreateShowAnimation(
mxCenterPaneId,
maShowEndActions,
xCanvas,
mbDoAnimation,
aStartLocation,
aEndLocation);
mpWindowManager->Update();
}
void MoveInFromBottomAnimator::HidePane (void)
{
OSL_ASSERT(mpWindowManager.get()!=NULL);
Reference<awt::XWindow> xParentWindow (mpWindowManager->GetParentWindow(), UNO_QUERY);
if ( ! xParentWindow.is())
return;
Reference<rendering::XSpriteCanvas> xCanvas (mpWindowManager->GetParentCanvas(), UNO_QUERY);
if ( ! xCanvas.is())
return;
DeactivatePanes();
DeactivatePane(mxCenterPaneId);
SharedPaneGroup aPanes (maPaneGroups[0]);
aPanes->ShowPanes();
::boost::shared_ptr<MultiAnimation> pMultiAnimation (
new MultiAnimation(mbDoAnimation ? 500 : 0));
awt::Rectangle aWindowBox (xParentWindow->getPosSize());
// Animate the new center pane to collapse.
pMultiAnimation->AddAnimation(
::boost::bind(
InterpolatePosition,
::boost::protect(::boost::bind(&SpritePaneMove, mpPaneContainer, mxCenterPaneId, _1)),
_1,
geometry::RealPoint2D(maCenterPaneBox.X1, maCenterPaneBox.Y1),
geometry::RealPoint2D(maCenterPaneBox.X1, aWindowBox.Height)));
if (mbDoAnimation)
{
pMultiAnimation->AddAnimation(
::boost::bind(&rendering::XSpriteCanvas::updateScreen, xCanvas, sal_False));
}
pMultiAnimation->AddEndCallback(
::boost::bind(&PresenterPaneAnimatorBase::RestoreFrozenWindows, shared_from_this()));
EndActions::const_iterator iAction;
for (iAction=maHideEndActions.begin(); iAction!=maHideEndActions.end(); ++iAction)
pMultiAnimation->AddEndCallback(*iAction);
::boost::shared_ptr<PresenterAnimator> pAnimator (mpPresenterController->GetAnimator());
pAnimator->AddAnimation(SharedPresenterAnimation(pMultiAnimation));
}
void MoveInFromBottomAnimator::CreateShowAnimation (
const Reference<drawing::framework::XResourceId>& rxPaneId,
const EndOperators& rEndOperators,
const Reference<rendering::XSpriteCanvas>& rxSpriteCanvas,
const bool bAnimate,
const geometry::RealPoint2D& rStartLocation,
const geometry::RealPoint2D& rEndLocation)
{
// Animate the uppder and lower window bitmaps.
::boost::shared_ptr<MultiAnimation> pMultiAnimation (new MultiAnimation(bAnimate ? 500 : 0));
// Animate new pane to move in from the buttom.
pMultiAnimation->AddAnimation(
::boost::bind(
InterpolatePosition,
::boost::protect(::boost::bind(&SpritePaneMove, mpPaneContainer, rxPaneId, _1)),
_1,
rStartLocation,
rEndLocation));
// Call updateScreen after each animation step.
if (rxSpriteCanvas.is())
pMultiAnimation->AddAnimation(
::boost::bind(&rendering::XSpriteCanvas::updateScreen, rxSpriteCanvas, sal_False));
// Activate the panes when the animation is over.
pMultiAnimation->AddEndCallback(
::boost::bind(&PaneGroup::HidePanes, maPaneGroups[0]));
pMultiAnimation->AddEndCallback(
::boost::bind(&PresenterPaneAnimatorBase::ActivatePane, shared_from_this(), mxCenterPaneId));
EndActions::const_iterator iAction;
for (iAction=rEndOperators.begin(); iAction!=rEndOperators.end(); ++iAction)
pMultiAnimation->AddEndCallback(*iAction);
// Start the animation.
::boost::shared_ptr<PresenterAnimator> pAnimator (mpPresenterController->GetAnimator());
OSL_ASSERT(pAnimator.get()!=NULL);
pAnimator->AddAnimation(SharedPresenterAnimation(pMultiAnimation));
}
//===== TransparentOverlayAnimator ============================================
TransparentOverlayAnimator::TransparentOverlayAnimator (
const css::uno::Reference<css::drawing::framework::XResourceId>& rxPaneId,
const ::rtl::Reference<PresenterController>& rpPresenterController,
const bool bAnimate,
const EndActions& rShowEndActions,
const EndActions& rEndEndActions)
: PresenterPaneAnimatorBase(
rxPaneId,
rpPresenterController,
bAnimate,
rShowEndActions,
rEndEndActions),
maBackgroundSprite()
{
}
TransparentOverlayAnimator::~TransparentOverlayAnimator (void)
{
}
void TransparentOverlayAnimator::ShowPane (void)
{
EndActions::const_iterator iAction;
for (iAction=maShowEndActions.begin(); iAction!=maShowEndActions.end(); ++iAction)
(*iAction)();
CreateBackgroundSprite();
Reference<awt::XWindow> xParentWindow (mpWindowManager->GetParentWindow(), UNO_QUERY);
if (xParentWindow.is())
{
const awt::Rectangle aWindowBox (xParentWindow->getPosSize());
SharedPaneGroup pAllPanes (new PaneGroup());
pAllPanes->AddPane(mpPaneContainer->FindPaneURL(
PresenterPaneFactory::msCurrentSlidePreviewPaneURL));
pAllPanes->AddPane(mpPaneContainer->FindPaneURL(
PresenterPaneFactory::msNextSlidePreviewPaneURL));
pAllPanes->AddPane(mpPaneContainer->FindPaneURL(
PresenterPaneFactory::msToolBarPaneURL));
pAllPanes->AddPane(mpPaneContainer->FindPaneURL(
PresenterPaneFactory::msHelpPaneURL));
pAllPanes->AddPane(mpPaneContainer->FindPaneURL(
PresenterPaneFactory::msNotesPaneURL));
maPaneGroups.push_back(pAllPanes);
pAllPanes->DeactivatePanes();
mpWindowManager->Update();
}
PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
mpPaneContainer->FindPaneId(mxCenterPaneId));
if (pDescriptor.get() != NULL)
{
PresenterSpritePane* pPane = dynamic_cast<PresenterSpritePane*>(
pDescriptor->mxPane.get());
if (pPane != NULL)
pPane->ShowTransparentBorder();
pDescriptor->SetActivationState(true);
if (pDescriptor->mxBorderWindow.is())
pDescriptor->mxBorderWindow->setVisible(sal_True);
}
}
void TransparentOverlayAnimator::HidePane (void)
{
maPaneGroups[0]->ActivatePanes();
EndActions::const_iterator iAction;
for (iAction=maHideEndActions.begin(); iAction!=maHideEndActions.end(); ++iAction)
(*iAction)();
mpWindowManager->Update();
}
void TransparentOverlayAnimator::CreateBackgroundSprite (void)
{
Reference<awt::XWindow> xParentWindow (mpWindowManager->GetParentWindow(), UNO_QUERY);
Reference<rendering::XSpriteCanvas> xParentCanvas (mpWindowManager->GetParentCanvas(), UNO_QUERY);
if (xParentWindow.is() && xParentCanvas.is())
{
const awt::Rectangle aWindowBox (xParentWindow->getPosSize());
maBackgroundSprite.SetFactory(xParentCanvas);
maBackgroundSprite.Resize(
geometry::RealSize2D(aWindowBox.Width, aWindowBox.Height));
maBackgroundSprite.MoveTo(
geometry::RealPoint2D(aWindowBox.X, aWindowBox.Y));
maBackgroundSprite.SetAlpha(0.5);
maBackgroundSprite.Show();
Reference<rendering::XCanvas> xCanvas (maBackgroundSprite.GetCanvas());
if (xCanvas.is())
{
rendering::ViewState aViewState(
geometry::AffineMatrix2D(1,0,0, 0,1,0),
NULL);
rendering::RenderState aRenderState(
geometry::AffineMatrix2D(1,0,0, 0,1,0),
NULL,
Sequence<double>(4),
rendering::CompositeOperation::SOURCE);
PresenterCanvasHelper::SetDeviceColor(aRenderState, util::Color(0x80808080));
Reference<rendering::XPolyPolygon2D> xPolygon (
PresenterGeometryHelper::CreatePolygon(aWindowBox, xCanvas->getDevice()));
if (xPolygon.is())
xCanvas->fillPolyPolygon(
xPolygon,
aViewState,
aRenderState);
}
}
}
//===== PaneGroup =============================================================
PaneGroup::PaneGroup (void)
: maPanes(),
maOriginalBoundingBox(),
maCurrentBoundingBox(),
mpSubstitution(new PresenterSprite())
{
}
PaneGroup::~PaneGroup (void)
{
mpSubstitution.reset();
}
void PaneGroup::AddPane (const PresenterPaneContainer::SharedPaneDescriptor& rpPane)
{
OSL_ASSERT(rpPane.get() != NULL);
if (rpPane->mxBorderWindow.is())
{
PaneDescriptor aDescriptor (rpPane);
maPanes.push_back(aDescriptor);
maOriginalBoundingBox = PresenterGeometryHelper::Union(
maOriginalBoundingBox,
rpPane->mxBorderWindow->getPosSize());
}
}
void PaneGroup::CreateSubstitution (const Reference<rendering::XSpriteCanvas>& rxCanvas)
{
// Get the bitmap of the background.
Reference<rendering::XBitmap> xBackgroundBitmap (rxCanvas, UNO_QUERY);
if ( ! xBackgroundBitmap.is())
return;
// Create the sprite.
mpSubstitution->SetFactory(rxCanvas);
mpSubstitution->Resize(
geometry::RealSize2D(maOriginalBoundingBox.Width, maOriginalBoundingBox.Height));
// Fill it with the background inside the bounding box.
const rendering::ViewState aViewState (
geometry::AffineMatrix2D(1,0,0, 0,1,0),
NULL);
const rendering::RenderState aRenderState (
geometry::AffineMatrix2D(1,0,-maOriginalBoundingBox.X, 0,1,-maOriginalBoundingBox.Y),
NULL,
Sequence<double>(4),
rendering::CompositeOperation::SOURCE);
Reference<rendering::XCanvas> xSpriteCanvas (mpSubstitution->GetCanvas());
if (xSpriteCanvas.is())
xSpriteCanvas->drawBitmap(xBackgroundBitmap, aViewState, aRenderState);
}
void PaneGroup::Restore (void)
{
vector<PaneDescriptor>::iterator iPane;
for (iPane=maPanes.begin(); iPane!=maPanes.end(); ++iPane)
{
iPane->Restore();
}
}
::boost::shared_ptr<PresenterSprite> PaneGroup::GetSubstitution (void)
{
return mpSubstitution;
}
geometry::RealRectangle2D PaneGroup::GetOriginalBoundingBox (void) const
{
return geometry::RealRectangle2D(
maOriginalBoundingBox.X,
maOriginalBoundingBox.Y,
maOriginalBoundingBox.X + maOriginalBoundingBox.Width,
maOriginalBoundingBox.Y + maOriginalBoundingBox.Height);
}
geometry::RealRectangle2D PaneGroup::GetCurrentBoundingBox (void) const
{
return maCurrentBoundingBox;
}
void PaneGroup::MovePanes (
const double nXOffset,
const double nYOffset,
const ::rtl::Reference<PresenterWindowManager>& rpWindowManager
)
{
awt::Rectangle aBBox;
vector<PaneDescriptor>::iterator iPane;
for (iPane=maPanes.begin(); iPane!=maPanes.end(); ++iPane)
{
awt::Rectangle aBox (iPane->mpPaneDescriptor->mxBorderWindow->getPosSize());
aBox.X += sal_Int32(nXOffset);
aBox.Y += sal_Int32(nYOffset);
rpWindowManager->SetPanePosSizeAbsolute(
iPane->mpPaneDescriptor->mxPaneId->getResourceURL(),
aBox.X,
aBox.Y,
aBox.Width,
aBox.Height);
aBBox = PresenterGeometryHelper::Union(aBBox, aBox);
}
maCurrentBoundingBox = geometry::RealRectangle2D(
aBBox.X, aBBox.Y, aBBox.X+aBBox.Width, aBBox.Y+aBBox.Height);
}
void PaneGroup::ActivatePanes (void)
{
vector<PaneDescriptor>::iterator iPane;
for (iPane=maPanes.begin(); iPane!=maPanes.end(); ++iPane)
{
iPane->mpPaneDescriptor->SetActivationState(true);
}
}
void PaneGroup::DeactivatePanes (void)
{
vector<PaneDescriptor>::iterator iPane;
for (iPane=maPanes.begin(); iPane!=maPanes.end(); ++iPane)
{
iPane->mpPaneDescriptor->SetActivationState(false);
}
}
void PaneGroup::ShowPanes (void)
{
vector<PaneDescriptor>::iterator iPane;
for (iPane=maPanes.begin(); iPane!=maPanes.end(); ++iPane)
{
iPane->mpPaneDescriptor->mxBorderWindow->setVisible(sal_True);
iPane->mpPaneDescriptor->mxContentWindow->setVisible(sal_True);
}
}
void PaneGroup::HidePanes (void)
{
vector<PaneDescriptor>::iterator iPane;
for (iPane=maPanes.begin(); iPane!=maPanes.end(); ++iPane)
{
iPane->mpPaneDescriptor->mxBorderWindow->setVisible(sal_False);
iPane->mpPaneDescriptor->mxContentWindow->setVisible(sal_False);
}
}
//===== PaneDescriptor ========================================================
PaneDescriptor::PaneDescriptor (const PresenterPaneContainer::SharedPaneDescriptor& rpDescriptor)
: mpPaneDescriptor(rpDescriptor),
mnLeft(rpDescriptor->mnLeft),
mnTop(rpDescriptor->mnTop),
mnRight(rpDescriptor->mnRight),
mnBottom(rpDescriptor->mnBottom)
{
}
void PaneDescriptor::Restore (void) const
{
mpPaneDescriptor->mnLeft = mnLeft;
mpPaneDescriptor->mnTop = mnTop;
mpPaneDescriptor->mnRight = mnRight;
mpPaneDescriptor->mnBottom = mnBottom;
}
//===== MultiAnimation ========================================================
MultiAnimation::MultiAnimation (const sal_uInt32 nDuration)
: PresenterAnimation(0, nDuration, 1000/50),
maAnimations()
{
}
void MultiAnimation::AddAnimation (const Animation& rAnimation)
{
maAnimations.push_back(rAnimation);
}
void MultiAnimation::Run (const double nProgress, const sal_uInt64 nCurrentTime)
{
(void)nCurrentTime;
vector<Animation>::const_iterator iAnimation (maAnimations.begin());
vector<Animation>::const_iterator iEnd (maAnimations.end());
for ( ; iAnimation!=iEnd; ++iAnimation)
(*iAnimation)(nProgress);
}
//===== functors ==============================================================
void InterpolatePosition (
const ::boost::function<void(geometry::RealPoint2D)>& rSetter,
double nP,
const geometry::RealPoint2D rInitialBox,
const geometry::RealPoint2D rFinalBox)
{
const double nQ (1 - nP);
OSL_TRACE("InterpolatePosition %f\n", nP);
rSetter(
geometry::RealPoint2D(
nQ * rInitialBox.X + nP * rFinalBox.X,
nQ * rInitialBox.Y + nP * rFinalBox.Y));
}
template<typename T>
void InterpolateValue (
const ::boost::function<void(T)>& rSetter,
double nP,
const T aInitialValue,
const T aFinalValue)
{
const double nQ (1 - nP);
rSetter(T(nQ * aInitialValue + nP * aFinalValue));
}
void SpriteTransform(
const rtl::Reference<PresenterPaneContainer>& rpPaneContainer,
const Reference<XResourceId>& rxPaneId,
const Reference<awt::XWindow>& rxSpriteOwnerWindow,
const ::boost::shared_ptr<PresenterPaintManager>& rpPaintManager,
const bool bAppear,
const double nX,
const double nInitialTop,
const double nFinalTop,
const double nP)
{
OSL_ASSERT(rpPaintManager.get()!=NULL);
PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
rpPaneContainer->FindPaneId(rxPaneId));
if (pDescriptor.get() != NULL
&& ! pDescriptor->maSpriteProvider.empty()
&& pDescriptor->mxBorderWindow.is())
{
::boost::shared_ptr<PresenterSprite> pSprite (pDescriptor->maSpriteProvider());
if (pSprite.get())
{
// There seems to be a problem with sprites not correctly
// invalidating the background when being transformed. As a
// workaround invalidate the background in the bounding box of
// the sprite before the transformation.
rpPaintManager->Invalidate(
rxSpriteOwnerWindow,
awt::Rectangle(
sal::static_int_cast<sal_Int32>(pSprite->GetLocation().X),
sal::static_int_cast<sal_Int32>(pSprite->GetLocation().Y),
sal::static_int_cast<sal_Int32>(pSprite->GetSize().Width),
sal::static_int_cast<sal_Int32>(pSprite->GetSize().Height)));
const double nYScale (bAppear ? nP : 1-nP);
pSprite->Transform(geometry::AffineMatrix2D(
1, 0, 0,
0, nYScale, 0));
pSprite->MoveTo(
geometry::RealPoint2D(nX, nYScale*nFinalTop + (1-nYScale)*nInitialTop));
pSprite->Show();
pDescriptor->mxBorderWindow->setVisible(sal_True);
}
}
}
void SpritePaneMove (
const rtl::Reference<PresenterPaneContainer>& rpPaneContainer,
const Reference<XResourceId>& rxPaneId,
const geometry::RealPoint2D& rLocation)
{
PresenterPaneContainer::SharedPaneDescriptor pDescriptor (
rpPaneContainer->FindPaneId(rxPaneId));
if (pDescriptor.get() != NULL
&& ! pDescriptor->maSpriteProvider.empty()
&& pDescriptor->mxBorderWindow.is())
{
::boost::shared_ptr<PresenterSprite> pSprite (pDescriptor->maSpriteProvider());
if (pSprite.get() != NULL)
{
pDescriptor->mxBorderWindow->setVisible(sal_True);
pSprite->MoveTo(rLocation);
}
}
}
geometry::RealPoint2D GetLocation (const geometry::RealRectangle2D& rBox)
{
return geometry::RealPoint2D(rBox.X1, rBox.Y1);
}
geometry::RealSize2D GetSize (const geometry::RealRectangle2D& rBox)
{
return geometry::RealSize2D(rBox.X2-rBox.X1, rBox.Y2-rBox.Y1);
}
} // end of anonymous namespace
} } // end of namespace ::sdext::presenter