xref: /trunk/main/avmedia/source/viewer/mediawindow_impl.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 #include "mediawindow_impl.hxx"
29 #include "mediaevent_impl.hxx"
30 #include "mediamisc.hxx"
31 #include "mediawindow.hrc"
32 #include "helpids.hrc"
33 
34 #include <algorithm>
35 #include <cmath>
36 #include <osl/mutex.hxx>
37 #include <tools/time.hxx>
38 #include <vcl/svapp.hxx>
39 
40 #ifndef _COM_SUN_STAR_AWT_SYSTEMPOINTER_HDL_
41 #include <com/sun/star/awt/SystemPointer.hdl>
42 #endif
43 #ifndef _COM_SUN_STAR_LANG_XCOMPONENT_HDL_
44 #include <com/sun/star/lang/XComponent.hdl>
45 #endif
46 
47 #define AVMEDIA_TOOLBOXITEM_PREV    0x0001
48 #define AVMEDIA_TOOLBOXITEM_PLAY    0x0002
49 #define AVMEDIA_TOOLBOXITEM_PAUSE   0x0004
50 #define AVMEDIA_TOOLBOXITEM_STOP    0x0008
51 #define AVMEDIA_TOOLBOXITEM_NEXT    0x0010
52 #define AVMEDIA_TOOLBOXITEM_MUTE    0x0100
53 
54 #define AVMEDIA_FFW_PLAYRATE        4
55 
56 using namespace ::com::sun::star;
57 
58 namespace avmedia { namespace priv {
59 
60 // ----------------------
61 // - MediaWindowControl -
62 // ----------------------
63 
64 MediaWindowControl::MediaWindowControl( Window* pParent ) :
65     MediaControl( pParent, MEDIACONTROLSTYLE_MULTILINE )
66 {
67 }
68 
69 // ---------------------------------------------------------------------
70 
71 MediaWindowControl::~MediaWindowControl()
72 {
73 }
74 
75 // ---------------------------------------------------------------------
76 
77 void MediaWindowControl::update()
78 {
79     MediaItem aItem;
80 
81     static_cast< MediaWindowImpl* >( GetParent() )->updateMediaItem( aItem );
82     setState( aItem );
83 }
84 
85 // ---------------------------------------------------------------------
86 
87 void  MediaWindowControl::execute( const MediaItem& rItem )
88 {
89     static_cast< MediaWindowImpl* >( GetParent() )->executeMediaItem( rItem );
90 }
91 
92 // --------------------
93 // - MediaChildWindow -
94 // --------------------
95 
96 MediaChildWindow::MediaChildWindow( Window* pParent ) :
97     SystemChildWindow( pParent, WB_CLIPCHILDREN )
98 {
99 }
100 
101 // ---------------------------------------------------------------------
102 
103 MediaChildWindow::~MediaChildWindow()
104 {
105 }
106 
107 // ---------------------------------------------------------------------
108 
109 void MediaChildWindow::MouseMove( const MouseEvent& rMEvt )
110 {
111     const MouseEvent aTransformedEvent( GetParent()->ScreenToOutputPixel( OutputToScreenPixel( rMEvt.GetPosPixel() ) ),
112                                         rMEvt.GetClicks(), rMEvt.GetMode(), rMEvt.GetButtons(), rMEvt.GetModifier() );
113 
114     SystemChildWindow::MouseMove( rMEvt );
115     GetParent()->MouseMove( aTransformedEvent );
116 }
117 
118 // ---------------------------------------------------------------------
119 
120 void MediaChildWindow::MouseButtonDown( const MouseEvent& rMEvt )
121 {
122     const MouseEvent aTransformedEvent( GetParent()->ScreenToOutputPixel( OutputToScreenPixel( rMEvt.GetPosPixel() ) ),
123                                         rMEvt.GetClicks(), rMEvt.GetMode(), rMEvt.GetButtons(), rMEvt.GetModifier() );
124 
125     SystemChildWindow::MouseButtonDown( rMEvt );
126     GetParent()->MouseButtonDown( aTransformedEvent );
127 }
128 
129 // ---------------------------------------------------------------------
130 
131 void MediaChildWindow::MouseButtonUp( const MouseEvent& rMEvt )
132 {
133     const MouseEvent aTransformedEvent( GetParent()->ScreenToOutputPixel( OutputToScreenPixel( rMEvt.GetPosPixel() ) ),
134                                         rMEvt.GetClicks(), rMEvt.GetMode(), rMEvt.GetButtons(), rMEvt.GetModifier() );
135 
136     SystemChildWindow::MouseButtonUp( rMEvt );
137     GetParent()->MouseButtonUp( aTransformedEvent );
138 }
139 
140 // ---------------------------------------------------------------------
141 
142 void MediaChildWindow::KeyInput( const KeyEvent& rKEvt )
143 {
144     SystemChildWindow::KeyInput( rKEvt );
145     GetParent()->KeyInput( rKEvt );
146 }
147 
148 // ---------------------------------------------------------------------
149 
150 void MediaChildWindow::KeyUp( const KeyEvent& rKEvt )
151 {
152     SystemChildWindow::KeyUp( rKEvt );
153     GetParent()->KeyUp( rKEvt );
154 }
155 
156 // ---------------------------------------------------------------------
157 
158 void MediaChildWindow::Command( const CommandEvent& rCEvt )
159 {
160     const CommandEvent aTransformedEvent( GetParent()->ScreenToOutputPixel( OutputToScreenPixel( rCEvt.GetMousePosPixel() ) ),
161                                           rCEvt.GetCommand(), rCEvt.IsMouseEvent(), rCEvt.GetData() );
162 
163     SystemChildWindow::Command( rCEvt );
164     GetParent()->Command( aTransformedEvent );
165 }
166 
167 // ----------------------
168 // - MediaWindowImpl -
169 // ----------------------
170 
171 MediaWindowImpl::MediaWindowImpl( Window* pParent, MediaWindow* pMediaWindow, bool bInternalMediaControl ) :
172     Control( pParent ),
173     MediaWindowBaseImpl( pMediaWindow ),
174     DropTargetHelper( this ),
175     DragSourceHelper( this ),
176     mxEventsIf( static_cast< ::cppu::OWeakObject* >( mpEvents = new MediaEventListenersImpl( maChildWindow ) ) ),
177     maChildWindow( this ),
178     mpMediaWindowControl( bInternalMediaControl ? new MediaWindowControl( this ) : NULL ),
179     mpEmptyBmpEx( NULL ),
180     mpAudioBmpEx( NULL )
181 {
182     maChildWindow.SetBackground( Color( COL_BLACK ) );
183     maChildWindow.SetHelpId( HID_AVMEDIA_PLAYERWINDOW );
184     maChildWindow.Hide();
185 
186     if( mpMediaWindowControl )
187     {
188         mpMediaWindowControl->SetSizePixel( mpMediaWindowControl->getMinSizePixel() );
189         mpMediaWindowControl->Show();
190     }
191 }
192 
193 // ---------------------------------------------------------------------
194 
195 MediaWindowImpl::~MediaWindowImpl()
196 {
197     delete mpEmptyBmpEx;
198     delete mpAudioBmpEx;
199     delete mpMediaWindowControl;
200 }
201 
202 // ---------------------------------------------------------------------
203 
204 void MediaWindowImpl::cleanUp()
205 {
206     uno::Reference< media::XPlayerWindow > xPlayerWindow( getPlayerWindow() );
207 
208     mpEvents->cleanUp();
209 
210     if( xPlayerWindow.is() )
211     {
212         xPlayerWindow->removeKeyListener( uno::Reference< awt::XKeyListener >( mxEventsIf, uno::UNO_QUERY ) );
213         xPlayerWindow->removeMouseListener( uno::Reference< awt::XMouseListener >( mxEventsIf, uno::UNO_QUERY ) );
214         xPlayerWindow->removeMouseMotionListener( uno::Reference< awt::XMouseMotionListener >( mxEventsIf, uno::UNO_QUERY ) );
215 
216         uno::Reference< lang::XComponent > xComponent( xPlayerWindow, uno::UNO_QUERY );
217 
218         if( xComponent.is() )
219             xComponent->dispose();
220 
221         setPlayerWindow( NULL );
222     }
223 
224     MediaWindowBaseImpl::cleanUp();
225 }
226 
227 // ---------------------------------------------------------------------
228 
229 void MediaWindowImpl::onURLChanged()
230 {
231     if( getPlayer().is() )
232     {
233         uno::Reference< media::XPlayerWindow > xPlayerWindow;
234 
235         const Point         aPoint;
236         const Size          aSize( maChildWindow.GetSizePixel() );
237         const sal_IntPtr    nWndHandle = (sal_IntPtr) maChildWindow.GetParentWindowHandle( isMediaWindowJavaBased() );
238 
239         try
240         {
241             if( nWndHandle != 0 )
242             {
243                 uno::Sequence< uno::Any > aArgs( 3 );
244 
245                 aArgs[ 0 ] = uno::makeAny( nWndHandle );
246                 aArgs[ 1 ] = uno::makeAny( awt::Rectangle( aPoint.X(), aPoint.Y(), aSize.Width(), aSize.Height() ) );
247                 aArgs[ 2 ] = uno::makeAny( reinterpret_cast< sal_IntPtr >( &maChildWindow ) );
248 
249                 xPlayerWindow = getPlayer()->createPlayerWindow( aArgs );
250             }
251         }
252         catch( uno::RuntimeException )
253         {
254             // happens eg, on MacOSX where Java frames cannot be created from X11 window handles
255         }
256 
257         setPlayerWindow( xPlayerWindow );
258 
259         if( xPlayerWindow.is() )
260         {
261             xPlayerWindow->addKeyListener( uno::Reference< awt::XKeyListener >( mxEventsIf, uno::UNO_QUERY ) );
262             xPlayerWindow->addMouseListener( uno::Reference< awt::XMouseListener >( mxEventsIf, uno::UNO_QUERY ) );
263             xPlayerWindow->addMouseMotionListener( uno::Reference< awt::XMouseMotionListener >( mxEventsIf, uno::UNO_QUERY ) );
264             xPlayerWindow->addFocusListener( uno::Reference< awt::XFocusListener >( mxEventsIf, uno::UNO_QUERY ) );
265         }
266     }
267     else
268         setPlayerWindow( NULL );
269 
270     if( getPlayerWindow().is() )
271         maChildWindow.Show();
272     else
273         maChildWindow.Hide();
274 
275     if( mpMediaWindowControl )
276     {
277         MediaItem aItem;
278 
279         updateMediaItem( aItem );
280         mpMediaWindowControl->setState( aItem );
281     }
282 }
283 
284 // ---------------------------------------------------------------------
285 
286 void MediaWindowImpl::update()
287 {
288     uno::Reference< media::XPlayerWindow > xPlayerWindow( getPlayerWindow() );
289 
290     if( xPlayerWindow.is() )
291         xPlayerWindow->update();
292 }
293 
294 // ---------------------------------------------------------------------
295 
296 void MediaWindowImpl::setPosSize( const Rectangle& rRect )
297 {
298     SetPosSizePixel( rRect.TopLeft(), rRect.GetSize() );
299 }
300 
301 // ---------------------------------------------------------------------
302 
303 void MediaWindowImpl::setPointer( const Pointer& rPointer )
304 {
305     uno::Reference< media::XPlayerWindow >  xPlayerWindow( getPlayerWindow() );
306 
307     SetPointer( rPointer );
308     maChildWindow.SetPointer( rPointer );
309 
310     if( xPlayerWindow.is() )
311     {
312         long nPointer;
313 
314         switch( rPointer.GetStyle() )
315         {
316             case( POINTER_CROSS ): nPointer = awt::SystemPointer::CROSS; break;
317             case( POINTER_HAND ): nPointer = awt::SystemPointer::HAND; break;
318             case( POINTER_MOVE ): nPointer = awt::SystemPointer::MOVE; break;
319             case( POINTER_WAIT ): nPointer = awt::SystemPointer::WAIT; break;
320 
321             default: nPointer = awt::SystemPointer::ARROW; break;
322         }
323 
324         xPlayerWindow->setPointerType( nPointer );
325     }
326 }
327 
328 // ---------------------------------------------------------------------
329 
330 const Pointer& MediaWindowImpl::getPointer() const
331 {
332     return GetPointer();
333 }
334 
335 // ---------------------------------------------------------------------
336 
337 bool MediaWindowImpl::hasInternalMediaControl() const
338 {
339     return( mpMediaWindowControl != NULL );
340 }
341 
342 // ---------------------------------------------------------------------
343 
344 void MediaWindowImpl::Resize()
345 {
346     uno::Reference< media::XPlayerWindow >  xPlayerWindow( getPlayerWindow() );
347     const Size                              aCurSize( GetOutputSizePixel() );
348     const sal_Int32                         nOffset( mpMediaWindowControl ? AVMEDIA_CONTROLOFFSET : 0 );
349     Size                                    aPlayerWindowSize( aCurSize.Width() - ( nOffset << 1 ),
350                                                                aCurSize.Height() - ( nOffset << 1 ) );
351 
352     if( mpMediaWindowControl )
353     {
354         const sal_Int32 nControlHeight = mpMediaWindowControl->GetSizePixel().Height();
355         const sal_Int32 nControlY = ::std::max( aCurSize.Height() - nControlHeight - nOffset, 0L );
356 
357         aPlayerWindowSize.Height() = ( nControlY - ( nOffset << 1 ) );
358         mpMediaWindowControl->SetPosSizePixel( Point( nOffset, nControlY ), Size( aCurSize.Width() - ( nOffset << 1 ), nControlHeight ) );
359     }
360 
361     if( xPlayerWindow.is() )
362         xPlayerWindow->setPosSize( 0, 0, aPlayerWindowSize.Width(), aPlayerWindowSize.Height(), 0 );
363 
364     maChildWindow.SetPosSizePixel( Point( nOffset, nOffset ), aPlayerWindowSize );
365 }
366 
367 // ---------------------------------------------------------------------
368 
369 void MediaWindowImpl::StateChanged( StateChangedType eType )
370 {
371     uno::Reference< media::XPlayerWindow > xPlayerWindow( getPlayerWindow() );
372 
373     if( xPlayerWindow.is() )
374     {
375         // stop playing when going disabled or hidden
376         switch( eType )
377         {
378             case STATE_CHANGE_VISIBLE:
379             {
380                 stopPlayingInternal( !IsVisible() );
381                 xPlayerWindow->setVisible( IsVisible() );
382             }
383             break;
384 
385             case STATE_CHANGE_ENABLE:
386             {
387                 stopPlayingInternal( !IsEnabled() );
388                 xPlayerWindow->setEnable( IsEnabled() );
389             }
390             break;
391 
392             default:
393             break;
394         }
395     }
396 }
397 
398 // ---------------------------------------------------------------------
399 
400 void MediaWindowImpl::Paint( const Rectangle& )
401 {
402     BitmapEx* pLogo = NULL;
403 
404     if( !getPlayer().is() )
405     {
406         if( !mpEmptyBmpEx )
407             mpEmptyBmpEx = new BitmapEx( AVMEDIA_RESID( AVMEDIA_BMP_EMPTYLOGO ) );
408 
409         pLogo = mpEmptyBmpEx;
410     }
411     else if( !getPlayerWindow().is() )
412     {
413         if( !mpAudioBmpEx )
414             mpAudioBmpEx = new BitmapEx( AVMEDIA_RESID( AVMEDIA_BMP_AUDIOLOGO ) );
415 
416         pLogo = mpAudioBmpEx;
417     }
418 
419     const Point     aBasePos( maChildWindow.GetPosPixel() );
420     const Rectangle aVideoRect( aBasePos, maChildWindow.GetSizePixel() );
421 
422     if( pLogo && !pLogo->IsEmpty() && ( aVideoRect.GetWidth() > 0 ) && ( aVideoRect.GetHeight() > 0 ) )
423     {
424         Size        aLogoSize( pLogo->GetSizePixel() );
425         const Color aBackgroundColor( 67, 67, 67 );
426 
427         SetLineColor( aBackgroundColor );
428         SetFillColor( aBackgroundColor );
429         DrawRect( aVideoRect );
430 
431         if( ( aLogoSize.Width() > aVideoRect.GetWidth() || aLogoSize.Height() > aVideoRect.GetHeight() ) &&
432             ( aLogoSize.Height() > 0 ) )
433         {
434             const double fLogoWH = (double) aLogoSize.Width() / aLogoSize.Height();
435 
436             if( fLogoWH < ( (double) aVideoRect.GetWidth() / aVideoRect.GetHeight() ) )
437             {
438                 aLogoSize.Width() = (long) ( aVideoRect.GetHeight() * fLogoWH );
439                 aLogoSize.Height()= aVideoRect.GetHeight();
440             }
441             else
442             {
443                 aLogoSize.Width() = aVideoRect.GetWidth();
444                 aLogoSize.Height()= (long) ( aVideoRect.GetWidth() / fLogoWH );
445             }
446         }
447 
448         DrawBitmapEx( Point( aBasePos.X() + ( ( aVideoRect.GetWidth() - aLogoSize.Width() ) >> 1 ),
449                              aBasePos.Y() + ( ( aVideoRect.GetHeight() - aLogoSize.Height() ) >> 1 ) ),
450                       aLogoSize, *pLogo );
451     }
452 }
453 
454 // ---------------------------------------------------------------------
455 
456 void MediaWindowImpl::GetFocus()
457 {
458 }
459 
460 // ---------------------------------------------------------------------
461 
462 void MediaWindowImpl::MouseMove( const MouseEvent& rMEvt )
463 {
464     MediaWindow* pMediaWindow = getMediaWindow();
465 
466     if( pMediaWindow )
467         pMediaWindow->MouseMove( rMEvt );
468 }
469 
470 // ---------------------------------------------------------------------
471 
472 void MediaWindowImpl::MouseButtonDown( const MouseEvent& rMEvt )
473 {
474     MediaWindow* pMediaWindow = getMediaWindow();
475 
476     if( pMediaWindow )
477         pMediaWindow->MouseButtonDown( rMEvt );
478 }
479 
480 // ---------------------------------------------------------------------
481 
482 void MediaWindowImpl::MouseButtonUp( const MouseEvent& rMEvt )
483 {
484     MediaWindow* pMediaWindow = getMediaWindow();
485 
486     if( pMediaWindow )
487         pMediaWindow->MouseButtonUp( rMEvt );
488 }
489 
490 // ---------------------------------------------------------------------
491 
492 void MediaWindowImpl::KeyInput( const KeyEvent& rKEvt )
493 {
494     MediaWindow* pMediaWindow = getMediaWindow();
495 
496     if( pMediaWindow )
497         pMediaWindow->KeyInput( rKEvt );
498 }
499 
500 // ---------------------------------------------------------------------
501 
502 void MediaWindowImpl::KeyUp( const KeyEvent& rKEvt )
503 {
504     MediaWindow* pMediaWindow = getMediaWindow();
505 
506     if( pMediaWindow )
507         pMediaWindow->KeyUp( rKEvt );
508 }
509 
510 // ---------------------------------------------------------------------
511 
512 void MediaWindowImpl::Command( const CommandEvent& rCEvt )
513 {
514     MediaWindow* pMediaWindow = getMediaWindow();
515 
516     if( pMediaWindow )
517         pMediaWindow->Command( rCEvt );
518 }
519 
520 // ---------------------------------------------------------------------
521 
522 sal_Int8 MediaWindowImpl::AcceptDrop( const AcceptDropEvent& rEvt )
523 {
524     MediaWindow* pMediaWindow = getMediaWindow();
525     return( pMediaWindow ? pMediaWindow->AcceptDrop( rEvt ) : 0 );
526 }
527 
528 // ---------------------------------------------------------------------
529 
530 sal_Int8 MediaWindowImpl::ExecuteDrop( const ExecuteDropEvent& rEvt )
531 {
532     MediaWindow* pMediaWindow = getMediaWindow();
533     return( pMediaWindow ? pMediaWindow->ExecuteDrop( rEvt ) : 0 );
534 }
535 
536 // ---------------------------------------------------------------------
537 
538 void MediaWindowImpl::StartDrag( sal_Int8 nAction, const Point& rPosPixel )
539 {
540     MediaWindow* pMediaWindow = getMediaWindow();
541 
542     if( pMediaWindow )
543         pMediaWindow->StartDrag( nAction, rPosPixel );
544 }
545 
546 } // namespace priv
547 } // namespace avmedia
548