bump product version to 4.1.6.2
[LibreOffice.git] / sd / source / ui / dlg / animobjs.cxx
blob09272d3dbeec2fe4fc3b6a73245fe679ab92327c
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <com/sun/star/presentation/AnimationEffect.hpp>
21 #include <com/sun/star/presentation/AnimationSpeed.hpp>
22 #include <svx/xoutbmp.hxx>
23 #include <time.h>
24 #include <svl/eitem.hxx>
25 #include <svx/svdograf.hxx>
26 #include <svx/svdogrp.hxx>
27 #include <sfx2/basedlgs.hxx>
28 #include <sfx2/dispatch.hxx>
29 #include <sfx2/progress.hxx>
30 #include <vcl/msgbox.hxx>
31 #include "anminfo.hxx"
32 #include "animobjs.hxx"
33 #include "animobjs.hrc"
34 #include "app.hrc"
35 #include "strings.hrc"
36 #include "sdresid.hxx"
37 #include "View.hxx"
38 #include "drawdoc.hxx"
39 #include "sdpage.hxx"
40 #include "res_bmp.hrc"
41 #include "ViewShell.hxx"
43 #include <vcl/svapp.hxx>
45 #include <string>
46 #include <algorithm>
48 using namespace ::com::sun::star;
50 namespace sd {
52 /**
53 * SdDisplay - Control
55 SdDisplay::SdDisplay( Window* pWin, SdResId Id ) :
56 Control( pWin, Id ),
57 aScale( 1, 1 )
59 SetMapMode( MAP_PIXEL );
60 const StyleSettings& rStyles = Application::GetSettings().GetStyleSettings();
61 SetBackground( Wallpaper( Color( rStyles.GetFieldColor() ) ) );
64 // -----------------------------------------------------------------------
66 SdDisplay::~SdDisplay()
70 // -----------------------------------------------------------------------
72 void SdDisplay::SetBitmapEx( BitmapEx* pBmpEx )
74 if( pBmpEx )
76 aBitmapEx = *pBmpEx;
78 else
80 const StyleSettings& rStyles = Application::GetSettings().GetStyleSettings();
81 const Color aFillColor = rStyles.GetFieldColor();
82 aBitmapEx.Erase(aFillColor);
86 // -----------------------------------------------------------------------
88 void SdDisplay::Paint( const Rectangle& )
90 Point aPt;
91 Size aSize = GetOutputSize();
92 Size aBmpSize = aBitmapEx.GetBitmap().GetSizePixel();
93 aBmpSize.Width() = (long) ( (double) aBmpSize.Width() * (double) aScale );
94 aBmpSize.Height() = (long) ( (double) aBmpSize.Height() * (double) aScale );
96 if( aBmpSize.Width() < aSize.Width() )
97 aPt.X() = ( aSize.Width() - aBmpSize.Width() ) / 2;
98 if( aBmpSize.Height() < aSize.Height() )
99 aPt.Y() = ( aSize.Height() - aBmpSize.Height() ) / 2;
101 aBitmapEx.Draw( this, aPt, aBmpSize );
104 // -----------------------------------------------------------------------
106 void SdDisplay::SetScale( const Fraction& rFrac )
108 aScale = rFrac;
111 void SdDisplay::DataChanged( const DataChangedEvent& rDCEvt )
113 Control::DataChanged( rDCEvt );
115 if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_STYLE) )
117 const StyleSettings& rStyles = Application::GetSettings().GetStyleSettings();
118 SetBackground( Wallpaper( Color( rStyles.GetFieldColor() ) ) );
119 SetDrawMode( GetSettings().GetStyleSettings().GetHighContrastMode()
120 ? ViewShell::OUTPUT_DRAWMODE_CONTRAST
121 : ViewShell::OUTPUT_DRAWMODE_COLOR );
126 * AnimationWindow - FloatingWindow
128 AnimationWindow::AnimationWindow( SfxBindings* pInBindings,
129 SfxChildWindow *pCW, Window* pParent, const SdResId& rSdResId ) :
130 SfxDockingWindow ( pInBindings, pCW, pParent, rSdResId ),
131 aCtlDisplay ( this, SdResId( CTL_DISPLAY ) ),
132 aBtnFirst ( this, SdResId( BTN_FIRST ) ),
133 aBtnReverse ( this, SdResId( BTN_REVERSE ) ),
134 aBtnStop ( this, SdResId( BTN_STOP ) ),
135 aBtnPlay ( this, SdResId( BTN_PLAY ) ),
136 aBtnLast ( this, SdResId( BTN_LAST ) ),
137 aNumFldBitmap ( this, SdResId( NUM_FLD_BITMAP ) ),
138 aTimeField ( this, SdResId( TIME_FIELD ) ),
139 aLbLoopCount ( this, SdResId( LB_LOOP_COUNT ) ),
140 aGrpBitmap ( this, SdResId( GRP_BITMAP ) ),
141 aBtnGetOneObject ( this, SdResId( BTN_GET_ONE_OBJECT ) ),
142 aBtnGetAllObjects ( this, SdResId( BTN_GET_ALL_OBJECTS ) ),
143 aBtnRemoveBitmap ( this, SdResId( BTN_REMOVE_BITMAP ) ),
144 aBtnRemoveAll ( this, SdResId( BTN_REMOVE_ALL ) ),
145 aFtCount ( this, SdResId( FT_COUNT ) ),
146 aFiCount ( this, SdResId( FI_COUNT ) ),
147 aGrpAnimation ( this, SdResId( GRP_ANIMATION_GROUP ) ),
148 aRbtGroup ( this, SdResId( RBT_GROUP ) ),
149 aRbtBitmap ( this, SdResId( RBT_BITMAP ) ),
150 aFtAdjustment ( this, SdResId( FT_ADJUSTMENT ) ),
151 aLbAdjustment ( this, SdResId( LB_ADJUSTMENT ) ),
152 aBtnCreateGroup ( this, SdResId( BTN_CREATE_GROUP ) ),
153 aBtnHelp ( this, SdResId( BTN_HELP ) ),
156 pWin ( pParent ),
157 m_nCurrentFrame ( EMPTY_FRAMELIST ),
159 bMovie ( sal_False ),
160 bAllObjects ( sal_False ),
162 pBindings ( pInBindings )
164 aCtlDisplay.SetAccessibleName(String (SdResId(STR_DISPLAY)));
165 FreeResource();
166 //undo SfxDockingWindow HelpId clear hack
167 reverseUniqueHelpIdHack(*this);
169 // create new document with page
170 pMyDoc = new SdDrawDocument(DOCUMENT_TYPE_IMPRESS, NULL);
171 SdPage* pPage = (SdPage*) pMyDoc->AllocPage(sal_False);
172 pMyDoc->InsertPage(pPage);
174 pControllerItem = new AnimationControllerItem( SID_ANIMATOR_STATE, this, pBindings );
176 // as long as not in the resource
177 aTimeField.SetFormat( TIMEF_SEC_CS );
179 aBtnFirst.SetClickHdl( LINK( this, AnimationWindow, ClickFirstHdl ) );
180 aBtnReverse.SetClickHdl( LINK( this, AnimationWindow, ClickPlayHdl ) );
181 aBtnStop.SetClickHdl( LINK( this, AnimationWindow, ClickStopHdl ) );
182 aBtnPlay.SetClickHdl( LINK( this, AnimationWindow, ClickPlayHdl ) );
183 aBtnLast.SetClickHdl( LINK( this, AnimationWindow, ClickLastHdl ) );
185 aBtnGetOneObject.SetClickHdl( LINK( this, AnimationWindow, ClickGetObjectHdl ) );
186 aBtnGetAllObjects.SetClickHdl( LINK( this, AnimationWindow, ClickGetObjectHdl ) );
187 aBtnRemoveBitmap.SetClickHdl( LINK( this, AnimationWindow, ClickRemoveBitmapHdl ) );
188 aBtnRemoveAll.SetClickHdl( LINK( this, AnimationWindow, ClickRemoveBitmapHdl ) );
190 aRbtGroup.SetClickHdl( LINK( this, AnimationWindow, ClickRbtHdl ) );
191 aRbtBitmap.SetClickHdl( LINK( this, AnimationWindow, ClickRbtHdl ) );
192 aBtnCreateGroup.SetClickHdl( LINK( this, AnimationWindow, ClickCreateGroupHdl ) );
193 aNumFldBitmap.SetModifyHdl( LINK( this, AnimationWindow, ModifyBitmapHdl ) );
194 aTimeField.SetModifyHdl( LINK( this, AnimationWindow, ModifyTimeHdl ) );
196 // disable 3D border
197 aCtlDisplay.SetBorderStyle(WINDOW_BORDER_MONO);
198 aDisplaySize = aCtlDisplay.GetOutputSize();
200 aSize = GetOutputSizePixel();
201 SetMinOutputSizePixel( aSize );
203 ResetAttrs();
205 // the animator is empty; no animation group can be created
206 aBtnCreateGroup.Disable();
208 aBtnGetOneObject.SetAccessibleRelationMemberOf( &aGrpBitmap );
209 aBtnGetAllObjects.SetAccessibleRelationMemberOf( &aGrpBitmap );
210 aBtnRemoveBitmap.SetAccessibleRelationMemberOf( &aGrpBitmap );
211 aBtnRemoveAll.SetAccessibleRelationMemberOf( &aGrpBitmap );
214 // -----------------------------------------------------------------------
216 AnimationWindow::~AnimationWindow()
218 delete pControllerItem;
220 for (size_t i = 0; i < m_FrameList.size(); ++i)
222 delete m_FrameList[i].first;
223 delete m_FrameList[i].second;
225 m_FrameList.clear();
226 m_nCurrentFrame = EMPTY_FRAMELIST;
228 // delete the clones
229 delete pMyDoc;
232 // -----------------------------------------------------------------------
234 IMPL_LINK_NOARG(AnimationWindow, ClickFirstHdl)
236 m_nCurrentFrame = (m_FrameList.empty()) ? EMPTY_FRAMELIST : 0;
237 UpdateControl();
239 return( 0L );
242 // -----------------------------------------------------------------------
244 IMPL_LINK_NOARG(AnimationWindow, ClickStopHdl)
246 bMovie = sal_False;
247 return( 0L );
250 // -----------------------------------------------------------------------
252 IMPL_LINK( AnimationWindow, ClickPlayHdl, void *, p )
254 ScopeLockGuard aGuard( maPlayLock );
256 bMovie = sal_True;
257 sal_Bool bDisableCtrls = sal_False;
258 size_t const nCount = m_FrameList.size();
259 sal_Bool bReverse = p == &aBtnReverse;
261 // it is difficult to find it later on
262 sal_Bool bRbtGroupEnabled = aRbtGroup.IsEnabled();
263 sal_Bool bBtnGetAllObjectsEnabled = aBtnGetAllObjects.IsEnabled();
264 sal_Bool bBtnGetOneObjectEnabled = aBtnGetOneObject.IsEnabled();
266 // calculate overall time
267 Time aTime( 0 );
268 long nFullTime;
269 if( aRbtBitmap.IsChecked() )
271 for (size_t i = 0; i < nCount; ++i)
273 aTime += *m_FrameList[i].second;
275 nFullTime = aTime.GetMSFromTime();
277 else
279 nFullTime = nCount * 100;
280 aTime.MakeTimeFromMS( nFullTime );
283 // StatusBarManager from 1 second
284 SfxProgress* pProgress = NULL;
285 if( nFullTime >= 1000 )
287 bDisableCtrls = sal_True;
288 aBtnStop.Enable();
289 aBtnStop.Update();
290 OUString aStr("Animator:"); // here we should think about something smart
291 pProgress = new SfxProgress( NULL, aStr, nFullTime );
294 sal_uLong nTmpTime = 0;
295 size_t i = 0;
296 sal_Bool bCount = i < nCount;
297 if( bReverse )
299 i = nCount - 1;
301 while( bCount && bMovie )
303 // make list and view consistent
304 assert(0 < i && i < m_FrameList.size());
305 m_nCurrentFrame = i;
307 UpdateControl(bDisableCtrls);
309 if( aRbtBitmap.IsChecked() )
311 Time *const pTime = m_FrameList[i].second;
312 assert(pTime);
314 aTimeField.SetTime( *pTime );
315 sal_uLong nTime = pTime->GetMSFromTime();
317 WaitInEffect( nTime, nTmpTime, pProgress );
318 nTmpTime += nTime;
320 else
322 WaitInEffect( 100, nTmpTime, pProgress );
323 nTmpTime += 100;
325 if( bReverse )
327 if (i == 0)
329 // Terminate loop.
330 bCount = false;
332 else
334 --i;
337 else
339 i++;
340 if (i >= nCount)
342 // Terminate loop.
343 bCount = false;
344 // Move i back into valid range.
345 i = nCount - 1;
350 // to re-enable the controls
351 bMovie = sal_False;
352 if (nCount > 0)
354 assert(i == m_nCurrentFrame);
355 UpdateControl();
358 if( pProgress )
360 delete pProgress;
361 aBtnStop.Disable();
364 aRbtGroup.Enable( bRbtGroupEnabled );
365 aBtnGetAllObjects.Enable( bBtnGetAllObjectsEnabled );
366 aBtnGetOneObject.Enable( bBtnGetOneObjectEnabled );
368 return( 0L );
371 // -----------------------------------------------------------------------
373 IMPL_LINK_NOARG(AnimationWindow, ClickLastHdl)
375 m_nCurrentFrame =
376 (m_FrameList.empty()) ? EMPTY_FRAMELIST : m_FrameList.size() - 1 ;
377 UpdateControl();
379 return( 0L );
382 // -----------------------------------------------------------------------
384 IMPL_LINK( AnimationWindow, ClickRbtHdl, void *, p )
386 if (m_FrameList.empty() || p == &aRbtGroup || aRbtGroup.IsChecked())
388 aTimeField.SetText( String() );
389 aTimeField.Enable( sal_False );
390 aLbLoopCount.Enable( sal_False );
392 else if( p == &aRbtBitmap || aRbtBitmap.IsChecked() )
394 sal_uLong n = static_cast<sal_uLong>(aNumFldBitmap.GetValue());
395 if( n > 0 )
397 Time *const pTime = m_FrameList[n - 1].second;
398 if( pTime )
399 aTimeField.SetTime( *pTime );
401 aTimeField.Enable();
402 aLbLoopCount.Enable();
405 return( 0L );
408 // -----------------------------------------------------------------------
410 IMPL_LINK( AnimationWindow, ClickGetObjectHdl, void *, pBtn )
412 bAllObjects = pBtn == &aBtnGetAllObjects;
414 // Code now in AddObj()
415 SfxBoolItem aItem( SID_ANIMATOR_ADD, sal_True );
417 GetBindings().GetDispatcher()->Execute(
418 SID_ANIMATOR_ADD, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD, &aItem, 0L );
419 return( 0L );
422 // -----------------------------------------------------------------------
424 IMPL_LINK( AnimationWindow, ClickRemoveBitmapHdl, void *, pBtn )
426 SdPage* pPage = pMyDoc->GetSdPage(0, PK_STANDARD);
427 SdrObject* pObject;
429 if( pBtn == &aBtnRemoveBitmap )
431 delete m_FrameList[m_nCurrentFrame].first;
432 delete m_FrameList[m_nCurrentFrame].second;
433 m_FrameList.erase(m_FrameList.begin() + m_nCurrentFrame);
435 pObject = pPage->GetObj(m_nCurrentFrame);
436 // Through acquisition of the AnimatedGIFs, objects does not need to
437 // exist.
438 if( pObject )
440 pObject = pPage->RemoveObject(m_nCurrentFrame);
441 DBG_ASSERT(pObject, "Clone not found during deletion");
442 SdrObject::Free( pObject );
443 pPage->RecalcObjOrdNums();
446 if (m_nCurrentFrame >= m_FrameList.size())
448 assert(m_FrameList.empty());
449 m_nCurrentFrame = EMPTY_FRAMELIST;
452 else // delete everything
454 WarningBox aWarnBox( this, WB_YES_NO, String( SdResId( STR_ASK_DELETE_ALL_PICTURES ) ) );
455 short nReturn = aWarnBox.Execute();
457 if( nReturn == RET_YES )
459 // clear frame list
460 for (size_t i = m_FrameList.size(); i > 0; )
462 --i;
463 delete m_FrameList[i].first;
465 pObject = pPage->GetObj( i );
466 if( pObject )
468 pObject = pPage->RemoveObject( i );
469 DBG_ASSERT(pObject, "Clone not found during deletion");
470 SdrObject::Free( pObject );
471 //pPage->RecalcObjOrdNums();
474 delete m_FrameList[i].second;
476 m_FrameList.clear();
477 m_nCurrentFrame = EMPTY_FRAMELIST;
481 // can we create a animation group
482 if (m_FrameList.empty())
484 aBtnCreateGroup.Disable();
485 // if previous disabled by acquisition of AnimatedGIFs:
486 //aRbtBitmap.Enable();
487 aRbtGroup.Enable();
490 // calculate and set zoom for DisplayWin
491 Fraction aFrac( GetScale() );
492 aCtlDisplay.SetScale( aFrac );
494 UpdateControl();
496 return( 0L );
499 // -----------------------------------------------------------------------
501 IMPL_LINK_NOARG(AnimationWindow, ClickCreateGroupHdl)
503 // Code now in CreatePresObj()
504 SfxBoolItem aItem( SID_ANIMATOR_CREATE, sal_True );
506 GetBindings().GetDispatcher()->Execute(
507 SID_ANIMATOR_CREATE, SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD, &aItem, 0L );
508 return( 0L );
511 // -----------------------------------------------------------------------
513 IMPL_LINK_NOARG(AnimationWindow, ModifyBitmapHdl)
515 sal_uLong nBmp = static_cast<sal_uLong>(aNumFldBitmap.GetValue());
517 if (nBmp > m_FrameList.size())
519 nBmp = m_FrameList.size();
522 m_nCurrentFrame = nBmp - 1;
524 UpdateControl();
526 return( 0L );
529 // -----------------------------------------------------------------------
531 IMPL_LINK_NOARG(AnimationWindow, ModifyTimeHdl)
533 sal_uLong nPos = static_cast<sal_uLong>(aNumFldBitmap.GetValue() - 1);
535 Time *const pTime = m_FrameList[nPos].second;
537 *pTime = aTimeField.GetTime();
539 return( 0L );
542 // -----------------------------------------------------------------------
544 void AnimationWindow::UpdateControl(bool const bDisableCtrls)
546 if (!m_FrameList.empty())
548 BitmapEx aBmp(*m_FrameList[m_nCurrentFrame].first);
550 SdPage* pPage = pMyDoc->GetSdPage(0, PK_STANDARD);
551 SdrObject *const pObject =
552 static_cast<SdrObject*>(pPage->GetObj(m_nCurrentFrame));
553 if( pObject )
555 VirtualDevice aVD;
556 Rectangle aObjRect( pObject->GetCurrentBoundRect() );
557 Size aObjSize( aObjRect.GetSize() );
558 Point aOrigin( Point( -aObjRect.Left(), -aObjRect.Top() ) );
559 MapMode aMap( aVD.GetMapMode() );
560 aMap.SetMapUnit( MAP_100TH_MM );
561 aMap.SetOrigin( aOrigin );
562 aVD.SetMapMode( aMap );
563 aVD.SetOutputSize( aObjSize );
564 const StyleSettings& rStyles = Application::GetSettings().GetStyleSettings();
565 aVD.SetBackground( Wallpaper( rStyles.GetFieldColor() ) );
566 aVD.SetDrawMode( rStyles.GetHighContrastMode()
567 ? ViewShell::OUTPUT_DRAWMODE_CONTRAST
568 : ViewShell::OUTPUT_DRAWMODE_COLOR );
569 aVD.Erase();
570 pObject->SingleObjectPainter( aVD );
571 aBmp = BitmapEx( aVD.GetBitmap( aObjRect.TopLeft(), aObjSize ) );
575 aCtlDisplay.SetBitmapEx( &aBmp );
577 else
579 aCtlDisplay.SetBitmapEx(0);
581 aCtlDisplay.Invalidate();
582 aCtlDisplay.Update();
584 aFiCount.SetText(OUString::valueOf(
585 static_cast<sal_Int64>(m_FrameList.size())));
587 if (!m_FrameList.empty() && !bMovie)
589 aNumFldBitmap.SetValue(m_nCurrentFrame + 1);
591 // if there is at least 1 object in the list
592 aBtnFirst.Enable();
593 aBtnReverse.Enable();
594 aBtnPlay.Enable();
595 aBtnLast.Enable();
596 aNumFldBitmap.Enable();
597 aTimeField.Enable();
598 aLbLoopCount.Enable();
599 aBtnRemoveBitmap.Enable();
600 aBtnRemoveAll.Enable();
602 else
604 // if no object is in the list
605 aBtnFirst.Enable( sal_False );
606 aBtnReverse.Enable( sal_False );
607 aBtnPlay.Enable( sal_False );
608 aBtnLast.Enable( sal_False );
609 aNumFldBitmap.Enable( sal_False );
610 aTimeField.Enable( sal_False );
611 aLbLoopCount.Enable( sal_False );
612 aBtnRemoveBitmap.Enable( sal_False );
613 aBtnRemoveAll.Enable( sal_False );
615 //aFtAdjustment.Enable();
616 //aLbAdjustment.Enable();
619 if( bMovie && bDisableCtrls )
621 aBtnGetOneObject.Enable( sal_False );
622 aBtnGetAllObjects.Enable( sal_False );
623 aRbtGroup.Enable( sal_False );
624 aRbtBitmap.Enable( sal_False );
625 aBtnCreateGroup.Enable( sal_False );
626 aFtAdjustment.Enable( sal_False );
627 aLbAdjustment.Enable( sal_False );
629 else
631 // enable 'group object' only if it is not a Animated GIF
632 if (m_FrameList.empty())
634 aRbtGroup.Enable();
637 aRbtBitmap.Enable();
638 aBtnCreateGroup.Enable(!m_FrameList.empty());
639 aFtAdjustment.Enable( sal_True );
640 aLbAdjustment.Enable( sal_True );
643 ClickRbtHdl( NULL );
646 // -----------------------------------------------------------------------
648 void AnimationWindow::ResetAttrs()
650 aRbtGroup.Check();
651 aLbAdjustment.SelectEntryPos( BA_CENTER );
652 // LoopCount
653 aLbLoopCount.SelectEntryPos( aLbLoopCount.GetEntryCount() - 1);
655 UpdateControl();
658 // -----------------------------------------------------------------------
660 void AnimationWindow::WaitInEffect( sal_uLong nMilliSeconds, sal_uLong nTime,
661 SfxProgress* pProgress ) const
663 clock_t aEnd = Time::GetSystemTicks() + nMilliSeconds;
664 clock_t aCurrent = Time::GetSystemTicks();
665 while (aCurrent < aEnd)
667 aCurrent = Time::GetSystemTicks();
669 if( pProgress )
670 pProgress->SetState( nTime + nMilliSeconds + aCurrent - aEnd );
672 Application::Reschedule();
674 if( !bMovie )
675 return;
679 // -----------------------------------------------------------------------
681 Fraction AnimationWindow::GetScale()
683 Fraction aFrac;
684 size_t const nCount = m_FrameList.size();
685 if (nCount > 0)
687 aBmpSize.Width() = 0;
688 aBmpSize.Height() = 0;
689 for (size_t i = 0; i < nCount; i++)
691 BitmapEx *const pBitmap = m_FrameList[i].first;
692 Size aTempSize( pBitmap->GetBitmap().GetSizePixel() );
693 aBmpSize.Width() = std::max( aBmpSize.Width(), aTempSize.Width() );
694 aBmpSize.Height() = std::max( aBmpSize.Height(), aTempSize.Height() );
697 aBmpSize.Width() += 10;
698 aBmpSize.Height() += 10;
700 aFrac = Fraction( std::min( (double)aDisplaySize.Width() / (double)aBmpSize.Width(),
701 (double)aDisplaySize.Height() / (double)aBmpSize.Height() ) );
703 return( aFrac );
706 // -----------------------------------------------------------------------
708 void AnimationWindow::Resize()
710 if ( !IsFloatingMode() ||
711 !GetFloatingWindow()->IsRollUp() )
713 Size aWinSize( GetOutputSizePixel() ); // former rSize in Resizing()
715 Size aDiffSize;
716 aDiffSize.Width() = aWinSize.Width() - aSize.Width();
717 aDiffSize.Height() = aWinSize.Height() - aSize.Height();
719 // resize display controls
720 aDisplaySize.Width() += aDiffSize.Width();
721 aDisplaySize.Height() += aDiffSize.Height();
722 aCtlDisplay.SetOutputSizePixel( aDisplaySize );
724 Point aPt;
725 aPt.Y() = aDiffSize.Height();
727 // move other controls
728 aBtnFirst.Hide();
729 aBtnReverse.Hide();
730 aBtnStop.Hide();
731 aBtnPlay.Hide();
732 aBtnLast.Hide();
733 aTimeField.Hide();
734 aLbLoopCount.Hide();
735 aNumFldBitmap.Hide();
736 aFtCount.Hide();
737 aFiCount.Hide();
738 aBtnGetOneObject.Hide();
739 aBtnGetAllObjects.Hide();
740 aBtnRemoveBitmap.Hide();
741 aBtnRemoveAll.Hide();
742 aGrpBitmap.Hide();
743 aRbtGroup.Hide();
744 aRbtBitmap.Hide();
745 aFtAdjustment.Hide();
746 aLbAdjustment.Hide();
747 aBtnCreateGroup.Hide();
748 aGrpAnimation.Hide();
751 aBtnFirst.SetPosPixel( aBtnFirst.GetPosPixel() + aPt );
752 aBtnReverse.SetPosPixel( aBtnReverse.GetPosPixel() + aPt );
753 aBtnStop.SetPosPixel( aBtnStop.GetPosPixel() + aPt );
754 aBtnPlay.SetPosPixel( aBtnPlay.GetPosPixel() + aPt );
755 aBtnLast.SetPosPixel( aBtnLast.GetPosPixel() + aPt );
756 aNumFldBitmap.SetPosPixel( aNumFldBitmap.GetPosPixel() + aPt );
757 aTimeField.SetPosPixel( aTimeField.GetPosPixel() + aPt );
758 aLbLoopCount.SetPosPixel( aLbLoopCount.GetPosPixel() + aPt );
759 aFtCount.SetPosPixel( aFtCount.GetPosPixel() + aPt );
760 aFiCount.SetPosPixel( aFiCount.GetPosPixel() + aPt );
761 aRbtGroup.SetPosPixel( aRbtGroup.GetPosPixel() + aPt );
762 aRbtBitmap.SetPosPixel( aRbtBitmap.GetPosPixel() + aPt );
763 aFtAdjustment.SetPosPixel( aFtAdjustment.GetPosPixel() + aPt );
764 aLbAdjustment.SetPosPixel( aLbAdjustment.GetPosPixel() + aPt );
765 aBtnGetOneObject.SetPosPixel( aBtnGetOneObject.GetPosPixel() + aPt );
766 aBtnGetAllObjects.SetPosPixel( aBtnGetAllObjects.GetPosPixel() + aPt );
767 aBtnRemoveBitmap.SetPosPixel( aBtnRemoveBitmap.GetPosPixel() + aPt );
768 aBtnRemoveAll.SetPosPixel( aBtnRemoveAll.GetPosPixel() + aPt );
769 aBtnCreateGroup.SetPosPixel( aBtnCreateGroup.GetPosPixel() + aPt );
770 aGrpBitmap.SetPosPixel( aGrpBitmap.GetPosPixel() + aPt );
771 aGrpAnimation.SetPosPixel( aGrpAnimation.GetPosPixel() + aPt );
773 // calculate and set zoom for DisplayWin
774 Fraction aFrac( GetScale() );
775 aCtlDisplay.SetScale( aFrac );
777 aBtnFirst.Show();
778 aBtnReverse.Show();
779 aBtnStop.Show();
780 aBtnPlay.Show();
781 aBtnLast.Show();
782 aNumFldBitmap.Show();
783 aTimeField.Show();
784 aLbLoopCount.Show();
785 aFtCount.Show();
786 aFiCount.Show();
787 aFtAdjustment.Show();
788 aLbAdjustment.Show();
789 aBtnGetOneObject.Show();
790 aBtnGetAllObjects.Show();
791 aBtnRemoveBitmap.Show();
792 aBtnRemoveAll.Show();
793 aGrpBitmap.Show();
794 aRbtGroup.Show();
795 aRbtBitmap.Show();
796 aFtAdjustment.Show();
797 aLbAdjustment.Show();
798 aBtnCreateGroup.Show();
799 aGrpAnimation.Show();
801 aSize = aWinSize;
803 SfxDockingWindow::Resize();
806 // -----------------------------------------------------------------------
808 sal_Bool AnimationWindow::Close()
810 if( maPlayLock.isLocked() )
812 return sal_False;
814 else
816 SfxBoolItem aItem( SID_ANIMATION_OBJECTS, sal_False );
818 GetBindings().GetDispatcher()->Execute(
819 SID_ANIMATION_OBJECTS, SFX_CALLMODE_ASYNCHRON | SFX_CALLMODE_RECORD, &aItem, 0L );
821 SfxDockingWindow::Close();
823 return sal_True;
827 // -----------------------------------------------------------------------
829 void AnimationWindow::FillInfo( SfxChildWinInfo& rInfo ) const
831 SfxDockingWindow::FillInfo( rInfo ) ;
834 // -----------------------------------------------------------------------
836 void AnimationWindow::AddObj (::sd::View& rView )
838 // finish text entry mode to ensure that bitmap is identical with object
839 if( rView.IsTextEdit() )
840 rView.SdrEndTextEdit();
842 // clone object(s) and insert the clone(s) into the list
843 const SdrMarkList& rMarkList = rView.GetMarkedObjectList();
844 sal_uLong nMarkCount = rMarkList.GetMarkCount();
845 SdPage* pPage = pMyDoc->GetSdPage(0, PK_STANDARD);
846 sal_uLong nCloneCount = pPage->GetObjCount();
848 if (nMarkCount > 0)
850 // If it is ONE animation object or one group object, which was
851 // 'individually taken', we insert the objects separately
852 sal_Bool bAnimObj = sal_False;
853 if( nMarkCount == 1 )
855 SdrMark* pMark = rMarkList.GetMark(0);
856 SdrObject* pObject = pMark->GetMarkedSdrObj();
857 SdAnimationInfo* pAnimInfo = rView.GetDoc().GetAnimationInfo( pObject );
858 sal_uInt32 nInv = pObject->GetObjInventor();
859 sal_uInt16 nId = pObject->GetObjIdentifier();
861 // Animated Bitmap (GIF)
862 if( nInv == SdrInventor && nId == OBJ_GRAF && ( (SdrGrafObj*) pObject )->IsAnimated() )
864 const SdrGrafObj* pGrafObj = (SdrGrafObj*) pObject;
865 Graphic aGraphic( pGrafObj->GetTransformedGraphic() );
866 sal_uInt16 nCount = 0;
868 if( aGraphic.IsAnimated() )
869 nCount = aGraphic.GetAnimation().Count();
871 if( nCount > 0 )
873 const Animation aAnimation( aGraphic.GetAnimation() );
875 for( sal_uInt16 i = 0; i < nCount; i++ )
877 const AnimationBitmap& rAnimBmp = aAnimation.Get( i );
879 BitmapEx *const pBitmapEx =
880 new BitmapEx(rAnimBmp.aBmpEx);
882 // LoopCount
883 if( i == 0 )
885 long nLoopCount = aAnimation.GetLoopCount();
887 if( !nLoopCount ) // endless
888 aLbLoopCount.SelectEntryPos( aLbLoopCount.GetEntryCount() - 1);
889 else
890 aLbLoopCount.SelectEntry(OUString::valueOf( nLoopCount ) );
893 long nTime = rAnimBmp.nWait;
894 Time* pTime = new Time( 0, 0, nTime / 100, nTime % 100 );
895 m_FrameList.insert(
896 m_FrameList.begin() + m_nCurrentFrame + 1,
897 ::std::make_pair(pBitmapEx, pTime));
899 // increment => next one inserted after this one
900 ++m_nCurrentFrame;
902 // if a animated GIF is taken, only such one can be created
903 aRbtBitmap.Check();
904 aRbtGroup.Enable( sal_False );
905 bAnimObj = sal_True;
908 else if( bAllObjects || ( pAnimInfo && pAnimInfo->mbIsMovie ) )
910 // several objects
911 SdrObjList* pObjList = ((SdrObjGroup*)pObject)->GetSubList();
913 for( sal_uInt16 nObject = 0; nObject < pObjList->GetObjCount(); nObject++ )
915 SdrObject* pSnapShot = (SdrObject*) pObjList->GetObj( (sal_uLong) nObject );
917 BitmapEx *const pBitmapEx = new BitmapEx(
918 SdrExchangeView::GetObjGraphic(
919 pSnapShot->GetModel(), pSnapShot).GetBitmapEx() );
921 Time* pTime = new Time( aTimeField.GetTime() );
923 m_FrameList.insert(
924 m_FrameList.begin() + m_nCurrentFrame + 1,
925 ::std::make_pair(pBitmapEx, pTime));
927 // increment => next one inserted after this one
928 ++m_nCurrentFrame;
930 // Clone
931 pPage->InsertObject(pSnapShot->Clone(), m_nCurrentFrame);
933 bAnimObj = sal_True;
936 // also one single animated object
937 if( !bAnimObj && !( bAllObjects && nMarkCount > 1 ) )
939 BitmapEx *const pBitmapEx =
940 new BitmapEx(rView.GetAllMarkedGraphic().GetBitmapEx());
942 Time* pTime = new Time( aTimeField.GetTime() );
944 m_FrameList.insert(
945 m_FrameList.begin() + m_nCurrentFrame + 1,
946 ::std::make_pair(pBitmapEx, pTime));
949 // one single object
950 if( nMarkCount == 1 && !bAnimObj )
952 SdrMark* pMark = rMarkList.GetMark(0);
953 SdrObject* pObject = pMark->GetMarkedSdrObj();
954 SdrObject* pClone = pObject->Clone();
955 pPage->InsertObject(pClone, m_nCurrentFrame + 1);
957 // several objects: group the clones
958 else if (nMarkCount > 1)
960 // take objects separately
961 if( bAllObjects )
963 for( sal_uLong nObject= 0; nObject < nMarkCount; nObject++ )
965 // Clone
966 SdrObject* pObject = rMarkList.GetMark( nObject )->GetMarkedSdrObj();
968 BitmapEx *const pBitmapEx = new BitmapEx(
969 SdrExchangeView::GetObjGraphic(
970 pObject->GetModel(), pObject).GetBitmapEx() );
972 Time* pTime = new Time( aTimeField.GetTime() );
974 m_FrameList.insert(
975 m_FrameList.begin() + m_nCurrentFrame + 1,
976 ::std::make_pair(pBitmapEx, pTime));
978 // increment => next one inserted after this one
979 ++m_nCurrentFrame;
981 pPage->InsertObject(pObject->Clone(), m_nCurrentFrame);
983 bAnimObj = sal_True; // that we don't change again
985 else
987 SdrObjGroup* pCloneGroup = new SdrObjGroup;
988 SdrObjList* pObjList = pCloneGroup->GetSubList();
990 for (sal_uLong nObject= 0; nObject < nMarkCount; nObject++)
991 pObjList->InsertObject(rMarkList.GetMark(nObject)->GetMarkedSdrObj()->Clone(), LIST_APPEND);
993 pPage->InsertObject(pCloneGroup, m_nCurrentFrame + 1);
997 if( !bAnimObj )
999 ++m_nCurrentFrame;
1002 // if there was nothing in the animator before but now is something
1003 // there, we can create a animation group
1004 if (nCloneCount == 0 && !m_FrameList.empty())
1006 aBtnCreateGroup.Enable();
1009 // calculate and set zoom for DisplayWin
1010 Fraction aFrac( GetScale() );
1011 aCtlDisplay.SetScale( aFrac );
1013 UpdateControl();
1017 // -----------------------------------------------------------------------
1019 void AnimationWindow::CreateAnimObj (::sd::View& rView )
1021 ::Window* pOutWin = static_cast< ::Window*>(rView.GetFirstOutputDevice()); // GetWin( 0 );
1022 DBG_ASSERT( pOutWin, "Window does not exist!" );
1024 // find window center
1025 const MapMode aMap100( MAP_100TH_MM );
1026 Size aMaxSizeLog;
1027 Size aMaxSizePix;
1028 Size aTemp( pOutWin->GetOutputSizePixel() );
1029 const Point aWindowCenter( pOutWin->PixelToLogic( Point( aTemp.Width() >> 1, aTemp.Height() >> 1 ) ) );
1030 const OutputDevice* pDefDev = Application::GetDefaultDevice();
1031 const size_t nCount = m_FrameList.size();
1032 BitmapAdjustment eBA = (BitmapAdjustment) aLbAdjustment.GetSelectEntryPos();
1034 // find biggest bitmap
1035 for (size_t i = 0; i < nCount; ++i)
1037 const BitmapEx& rBmpEx = *m_FrameList[i].first;
1038 const Graphic aGraphic( rBmpEx );
1039 Size aTmpSizeLog;
1040 const Size aTmpSizePix( rBmpEx.GetSizePixel() );
1042 if ( aGraphic.GetPrefMapMode().GetMapUnit() == MAP_PIXEL )
1043 aTmpSizeLog = pDefDev->PixelToLogic( aGraphic.GetPrefSize(), aMap100 );
1044 else
1045 aTmpSizeLog = pDefDev->LogicToLogic( aGraphic.GetPrefSize(), aGraphic.GetPrefMapMode(), aMap100 );
1047 aMaxSizeLog.Width() = std::max( aMaxSizeLog.Width(), aTmpSizeLog.Width() );
1048 aMaxSizeLog.Height() = std::max( aMaxSizeLog.Height(), aTmpSizeLog.Height() );
1050 aMaxSizePix.Width() = std::max( aMaxSizePix.Width(), aTmpSizePix.Width() );
1051 aMaxSizePix.Height() = std::max( aMaxSizePix.Height(), aTmpSizePix.Height() );
1054 SdrPageView* pPV = rView.GetSdrPageView();
1056 if( aRbtBitmap.IsChecked() )
1058 // create bitmap group (Animated GIF)
1059 Animation aAnimation;
1060 Point aPt;
1062 for (size_t i = 0; i < nCount; ++i)
1064 Time *const pTime = m_FrameList[i].second;
1065 long nTime = pTime->GetNanoSec();
1066 nTime += pTime->GetSec() * 100;
1068 BitmapEx const*const pBitmapEx = m_FrameList[i].first;
1070 // calculate offset for the specified direction
1071 const Size aBitmapSize( pBitmapEx->GetSizePixel() );
1073 switch( eBA )
1075 case BA_LEFT_UP:
1076 break;
1078 case BA_LEFT:
1079 aPt.Y() = (aMaxSizePix.Height() - aBitmapSize.Height()) >> 1;
1080 break;
1082 case BA_LEFT_DOWN:
1083 aPt.Y() = aMaxSizePix.Height() - aBitmapSize.Height();
1084 break;
1086 case BA_UP:
1087 aPt.X() = (aMaxSizePix.Width() - aBitmapSize.Width()) >> 1;
1088 break;
1090 case BA_CENTER:
1091 aPt.X() = (aMaxSizePix.Width() - aBitmapSize.Width()) >> 1;
1092 aPt.Y() = (aMaxSizePix.Height() - aBitmapSize.Height()) >> 1;
1093 break;
1095 case BA_DOWN:
1096 aPt.X() = (aMaxSizePix.Width() - aBitmapSize.Width()) >> 1;
1097 aPt.Y() = aMaxSizePix.Height() - aBitmapSize.Height();
1098 break;
1100 case BA_RIGHT_UP:
1101 aPt.X() = aMaxSizePix.Width() - aBitmapSize.Width();
1102 break;
1104 case BA_RIGHT:
1105 aPt.X() = aMaxSizePix.Width() - aBitmapSize.Width();
1106 aPt.Y() = (aMaxSizePix.Height() - aBitmapSize.Height()) >> 1;
1107 break;
1109 case BA_RIGHT_DOWN:
1110 aPt.X() = aMaxSizePix.Width() - aBitmapSize.Width();
1111 aPt.Y() = aMaxSizePix.Height() - aBitmapSize.Height();
1112 break;
1116 // find LoopCount (number of passes)
1117 AnimationBitmap aAnimBmp;
1118 long nLoopCount = 0L;
1119 sal_uInt16 nPos = aLbLoopCount.GetSelectEntryPos();
1121 if( nPos != LISTBOX_ENTRY_NOTFOUND && nPos != aLbLoopCount.GetEntryCount() - 1 ) // endless
1122 nLoopCount = (long) aLbLoopCount.GetSelectEntry().ToInt32();
1124 aAnimBmp.aBmpEx = *pBitmapEx;
1125 aAnimBmp.aPosPix = aPt;
1126 aAnimBmp.aSizePix = aBitmapSize;
1127 aAnimBmp.nWait = nTime;
1128 aAnimBmp.eDisposal = DISPOSE_BACK;
1129 aAnimBmp.bUserInput = sal_False;
1131 aAnimation.Insert( aAnimBmp );
1132 aAnimation.SetDisplaySizePixel( aMaxSizePix );
1133 aAnimation.SetLoopCount( nLoopCount );
1136 SdrGrafObj* pGrafObj = new SdrGrafObj( Graphic( aAnimation ) );
1137 const Point aOrg( aWindowCenter.X() - ( aMaxSizeLog.Width() >> 1 ), aWindowCenter.Y() - ( aMaxSizeLog.Height() >> 1 ) );
1139 pGrafObj->SetLogicRect( Rectangle( aOrg, aMaxSizeLog ) );
1140 rView.InsertObjectAtView( pGrafObj, *pPV, SDRINSERT_SETDEFLAYER);
1142 else
1144 // calculate offset for the specified direction
1145 Size aOffset;
1146 SdrObject * pClone = NULL;
1147 SdPage* pPage = pMyDoc->GetSdPage(0, PK_STANDARD);
1149 for (size_t i = 0; i < nCount; ++i)
1151 pClone = pPage->GetObj(i);
1152 Rectangle aRect( pClone->GetSnapRect() );
1154 switch( eBA )
1156 case BA_LEFT_UP:
1157 break;
1159 case BA_LEFT:
1160 aOffset.Height() = (aMaxSizeLog.Height() - aRect.GetHeight()) / 2;
1161 break;
1163 case BA_LEFT_DOWN:
1164 aOffset.Height() = aMaxSizeLog.Height() - aRect.GetHeight();
1165 break;
1167 case BA_UP:
1168 aOffset.Width() = (aMaxSizeLog.Width() - aRect.GetWidth()) / 2;
1169 break;
1171 case BA_CENTER:
1172 aOffset.Width() = (aMaxSizeLog.Width() - aRect.GetWidth()) / 2;
1173 aOffset.Height() = (aMaxSizeLog.Height() - aRect.GetHeight()) / 2;
1174 break;
1176 case BA_DOWN:
1177 aOffset.Width() = (aMaxSizeLog.Width() - aRect.GetWidth()) / 2;
1178 aOffset.Height() = aMaxSizeLog.Height() - aRect.GetHeight();
1179 break;
1181 case BA_RIGHT_UP:
1182 aOffset.Width() = aMaxSizeLog.Width() - aRect.GetWidth();
1183 break;
1185 case BA_RIGHT:
1186 aOffset.Width() = aMaxSizeLog.Width() - aRect.GetWidth();
1187 aOffset.Height() = (aMaxSizeLog.Height() - aRect.GetHeight()) / 2;
1188 break;
1190 case BA_RIGHT_DOWN:
1191 aOffset.Width() = aMaxSizeLog.Width() - aRect.GetWidth();
1192 aOffset.Height() = aMaxSizeLog.Height() - aRect.GetHeight();
1193 break;
1196 // Unfortunately, SetSnapRect is not implemented for ellipses !!!
1197 Point aMovePt( aWindowCenter + Point( aOffset.Width(), aOffset.Height() ) - aRect.TopLeft() );
1198 Size aMoveSize( aMovePt.X(), aMovePt.Y() );
1199 pClone->NbcMove( aMoveSize );
1202 // create animation group
1203 SdrObjGroup* pGroup = new SdrObjGroup;
1204 SdrObjList* pObjList = pGroup->GetSubList();
1206 for (size_t i = 0; i < nCount; i++)
1208 // the clone remains in the animatior; we insert a clone of the
1209 // clone into the group
1210 pClone = pPage->GetObj(i);
1211 SdrObject* pCloneOfClone = pClone->Clone();
1212 //SdrObject* pCloneOfClone = pPage->GetObj(i)->Clone();
1213 pObjList->InsertObject(pCloneOfClone, LIST_APPEND);
1216 // until now the top left corner of the group is in the window center;
1217 // correct the position by half of the size of the group
1218 aTemp = aMaxSizeLog;
1219 aTemp.Height() = - aTemp.Height() / 2;
1220 aTemp.Width() = - aTemp.Width() / 2;
1221 pGroup->NbcMove(aTemp);
1223 // create animation information
1224 SdAnimationInfo* pInfo = SdDrawDocument::GetShapeUserData(*pGroup,true);
1225 pInfo->meEffect = presentation::AnimationEffect_NONE;
1226 pInfo->meSpeed = presentation::AnimationSpeed_MEDIUM;
1227 pInfo->mbActive = sal_True;
1228 pInfo->mbIsMovie = sal_True;
1229 pInfo->maBlueScreen = COL_WHITE;
1231 rView.InsertObjectAtView( pGroup, *pPV, SDRINSERT_SETDEFLAYER);
1234 ClickFirstHdl( this );
1237 void AnimationWindow::DataChanged( const DataChangedEvent& rDCEvt )
1239 SfxDockingWindow::DataChanged( rDCEvt );
1241 if ( (rDCEvt.GetType() == DATACHANGED_SETTINGS) && (rDCEvt.GetFlags() & SETTINGS_STYLE) )
1243 UpdateControl();
1248 * ControllerItem for Animator
1250 AnimationControllerItem::AnimationControllerItem(
1251 sal_uInt16 _nId,
1252 AnimationWindow* pAnimWin,
1253 SfxBindings* _pBindings)
1254 : SfxControllerItem( _nId, *_pBindings ),
1255 pAnimationWin( pAnimWin )
1259 // -----------------------------------------------------------------------
1261 void AnimationControllerItem::StateChanged( sal_uInt16 nSId,
1262 SfxItemState eState, const SfxPoolItem* pItem )
1264 if( eState >= SFX_ITEM_AVAILABLE && nSId == SID_ANIMATOR_STATE )
1266 const SfxUInt16Item* pStateItem = PTR_CAST( SfxUInt16Item, pItem );
1267 DBG_ASSERT( pStateItem, "SfxUInt16Item expected");
1268 sal_uInt16 nState = pStateItem->GetValue();
1270 pAnimationWin->aBtnGetOneObject.Enable( nState & 1 );
1271 pAnimationWin->aBtnGetAllObjects.Enable( nState & 2 );
1276 } // end of namespace sd
1278 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */