summaryrefslogtreecommitdiff
path: root/toolkit
diff options
context:
space:
mode:
authorVladimir Glazounov <vg@openoffice.org>2005-02-17 09:21:18 +0000
committerVladimir Glazounov <vg@openoffice.org>2005-02-17 09:21:18 +0000
commit44b0b7035b8a889bea7cc438cf3267bfe454244c (patch)
tree3fd97e86bd2f725e11f59d9db1adea2950c36498 /toolkit
parent7a2c344ab9fd5a1700efd4877666106c81bc0070 (diff)
INTEGRATION: CWS dba23 (1.49.28); FILE MERGED
2005/02/11 12:41:04 oj 1.49.28.4: RESYNC: (1.50-1.51); FILE MERGED 2005/01/26 11:29:41 fs 1.49.28.3: RESYNC: (1.49-1.50); FILE MERGED 2005/01/18 15:44:43 fs 1.49.28.2: #i40647# +mnDrawingOntoParent: prevent recursive calls to certain branches of ::draw 2005/01/13 14:53:50 fs 1.49.28.1: #i40583# notify all events to XMouseListeners asynchronously
Diffstat (limited to 'toolkit')
-rw-r--r--toolkit/source/awt/vclxwindow.cxx197
1 files changed, 166 insertions, 31 deletions
diff --git a/toolkit/source/awt/vclxwindow.cxx b/toolkit/source/awt/vclxwindow.cxx
index cfa0e3246d6c..4768c5c47153 100644
--- a/toolkit/source/awt/vclxwindow.cxx
+++ b/toolkit/source/awt/vclxwindow.cxx
@@ -2,9 +2,9 @@
*
* $RCSfile: vclxwindow.cxx,v $
*
- * $Revision: 1.51 $
+ * $Revision: 1.52 $
*
- * last change: $Author: rt $ $Date: 2005-01-31 08:58:15 $
+ * last change: $Author: vg $ $Date: 2005-02-17 10:21:18 $
*
* The Contents of this file are made available subject to the terms of
* either of the following licenses
@@ -152,12 +152,127 @@
#include <vcl/dockwin.hxx>
#endif
+#ifndef COMPHELPER_ASYNCNOTIFICATION_HXX
+#include <comphelper/asyncnotification.hxx>
+#endif
+
using ::com::sun::star::style::VerticalAlignment;
using ::com::sun::star::style::VerticalAlignment_TOP;
using ::com::sun::star::style::VerticalAlignment_MIDDLE;
using ::com::sun::star::style::VerticalAlignment_BOTTOM;
using ::com::sun::star::style::VerticalAlignment_MAKE_FIXED_SIZE;
+//====================================================================
+//= VCLXWindowImpl
+//====================================================================
+#define EVENT_MOUSE_PRESSED 0
+#define EVENT_MOUSE_RELEASED 1
+#define EVENT_MOUSE_ENTERED 2
+#define EVENT_MOUSE_EXITED 3
+
+class SAL_DLLPRIVATE VCLXWindowImpl : public ::comphelper::IEventProcessor
+{
+private:
+ typedef ::comphelper::EventObjectHolder< ::com::sun::star::awt::MouseEvent >
+ MouseEventType;
+ typedef ::com::sun::star::uno::Reference< ::com::sun::star::lang::XComponent >
+ ComponentReference;
+
+private:
+ VCLXWindow& mrAntiImpl;
+ ::vos::IMutex& mrMutex;
+ ::comphelper::AsyncEventNotifier* mpAsyncNotifier;
+
+public:
+ /** ctor
+ @param _pAntiImpl
+ the <type>VCLXWindow</type> instance which the object belongs to. Must
+ live longer then the object just being constructed.
+ */
+ VCLXWindowImpl( VCLXWindow& _rAntiImpl, ::vos::IMutex& _rMutex );
+
+ /** asynchronously notifies a mousePressed event to the VCLXWindow's XMouseListeners
+ */
+ void notifyMouseEvent( const ::com::sun::star::awt::MouseEvent& _rMouseEvent, sal_uInt16 _nType );
+
+ /** notifies the object that its VCLXWindow is being disposed
+ */
+ void disposing();
+
+protected:
+ // IEventProcessor
+ virtual void processEvent( const ::comphelper::EventDescription& _rEvent );
+ virtual ComponentReference getComponent();
+};
+
+//--------------------------------------------------------------------
+VCLXWindowImpl::VCLXWindowImpl( VCLXWindow& _rAntiImpl, ::vos::IMutex& _rMutex )
+ :mrAntiImpl( _rAntiImpl )
+ ,mrMutex( _rMutex )
+ ,mpAsyncNotifier( NULL )
+{
+}
+
+//--------------------------------------------------------------------
+void VCLXWindowImpl::disposing()
+{
+ ::vos::OGuard aGuard( mrMutex );
+ if ( mpAsyncNotifier )
+ {
+ mpAsyncNotifier->release();
+ mpAsyncNotifier = NULL;
+ }
+}
+
+//--------------------------------------------------------------------
+void VCLXWindowImpl::notifyMouseEvent( const ::com::sun::star::awt::MouseEvent& _rMouseEvent, sal_uInt16 _nType )
+{
+ ::vos::OGuard aGuard( mrMutex );
+ if ( mrAntiImpl.GetMouseListeners().getLength() )
+ {
+ if ( !mpAsyncNotifier )
+ {
+ mpAsyncNotifier = new ::comphelper::AsyncEventNotifier( this );
+ mpAsyncNotifier->acquire();
+ mpAsyncNotifier->create();
+ }
+ mpAsyncNotifier->addEvent( new MouseEventType( _rMouseEvent, _nType ) );
+ }
+}
+
+//--------------------------------------------------------------------
+void VCLXWindowImpl::processEvent( const ::comphelper::EventDescription& _rEvent )
+{
+ const MouseEventType aEventDescriptor( static_cast< const MouseEventType& >( _rEvent ) );
+ const ::com::sun::star::awt::MouseEvent& rEvent( aEventDescriptor.getEventObject() );
+ switch ( aEventDescriptor.getEventType() )
+ {
+ case EVENT_MOUSE_PRESSED:
+ mrAntiImpl.GetMouseListeners().mousePressed( rEvent );
+ break;
+ case EVENT_MOUSE_RELEASED:
+ mrAntiImpl.GetMouseListeners().mouseReleased( rEvent );
+ break;
+ case EVENT_MOUSE_ENTERED:
+ mrAntiImpl.GetMouseListeners().mouseEntered( rEvent );
+ break;
+ case EVENT_MOUSE_EXITED:
+ mrAntiImpl.GetMouseListeners().mouseExited( rEvent );
+ break;
+ default:
+ DBG_ERROR( "VCLXWindowImpl::processEvent: what kind of event *is* this?" );
+ }
+}
+
+//--------------------------------------------------------------------
+VCLXWindowImpl::ComponentReference VCLXWindowImpl::getComponent()
+{
+ return static_cast< ::com::sun::star::awt::XWindow* >( &mrAntiImpl );
+}
+
+//====================================================================
+//====================================================================
+
// Mit Out-Parameter besser als Rueckgabewert, wegen Ref-Objekt...
void ImplInitWindowEvent( ::com::sun::star::awt::WindowEvent& rEvent, Window* pWindow )
@@ -229,10 +344,14 @@ VCLXWindow::VCLXWindow()
maPaintListeners( *this ),
maContainerListeners( *this ),
maTopWindowListeners( *this ),
- mnListenerLockLevel( 0 )
+ mnListenerLockLevel( 0 ),
+ mpImpl( NULL ),
+ mbDrawingOntoParent( false )
{
DBG_CTOR( VCLXWindow, 0 );
+ mpImpl = new VCLXWindowImpl( *this, GetMutex() );
+
mbDisposing = sal_False;
mbDesignMode = sal_False;
mbSynthesizingVCLEvent = sal_False;
@@ -248,6 +367,8 @@ VCLXWindow::~VCLXWindow()
GetWindow()->SetWindowPeer( NULL, NULL );
GetWindow()->SetAccessible( NULL );
}
+
+ DELETEZ( mpImpl );
}
void VCLXWindow::SetWindow( Window* pWindow )
@@ -524,7 +645,7 @@ void VCLXWindow::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent )
aEvent.Source = (::cppu::OWeakObject*)this;
ImplInitMouseEvent( aEvent, aMEvt );
aEvent.PopupTrigger = sal_True;
- GetMouseListeners().mousePressed( aEvent );
+ mpImpl->notifyMouseEvent( aEvent, EVENT_MOUSE_PRESSED );
}
}
break;
@@ -537,10 +658,10 @@ void VCLXWindow::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent )
aEvent.Source = (::cppu::OWeakObject*)this;
ImplInitMouseEvent( aEvent, *pMouseEvt );
- if ( pMouseEvt->IsEnterWindow() )
- GetMouseListeners().mouseEntered( aEvent );
- else
- GetMouseListeners().mouseExited( aEvent );
+ mpImpl->notifyMouseEvent(
+ aEvent,
+ pMouseEvt->IsEnterWindow() ? EVENT_MOUSE_ENTERED : EVENT_MOUSE_EXITED
+ );
}
if ( GetMouseMotionListeners().getLength() && !pMouseEvt->IsEnterWindow() && !pMouseEvt->IsLeaveWindow() )
@@ -564,7 +685,7 @@ void VCLXWindow::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent )
::com::sun::star::awt::MouseEvent aEvent;
aEvent.Source = (::cppu::OWeakObject*)this;
ImplInitMouseEvent( aEvent, *(MouseEvent*)rVclWindowEvent.GetData() );
- GetMouseListeners().mousePressed( aEvent );
+ mpImpl->notifyMouseEvent( aEvent, EVENT_MOUSE_PRESSED );
}
}
break;
@@ -575,7 +696,7 @@ void VCLXWindow::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent )
::com::sun::star::awt::MouseEvent aEvent;
aEvent.Source = (::cppu::OWeakObject*)this;
ImplInitMouseEvent( aEvent, *(MouseEvent*)rVclWindowEvent.GetData() );
- GetMouseListeners().mouseReleased( aEvent );
+ mpImpl->notifyMouseEvent( aEvent, EVENT_MOUSE_RELEASED );
}
}
break;
@@ -797,6 +918,8 @@ void VCLXWindow::dispose( ) throw(::com::sun::star::uno::RuntimeException)
{
mbDisposing = sal_True;
+ mpImpl->disposing();
+
::com::sun::star::lang::EventObject aObj;
aObj.Source = static_cast< ::cppu::OWeakObject* >( this );
@@ -1857,32 +1980,44 @@ void VCLXWindow::draw( sal_Int32 nX, sal_Int32 nY ) throw(::com::sun::star::uno:
if ( pWindow->GetParent() && !pWindow->IsSystemWindow() && ( pWindow->GetParent() == pDev ) )
{
- BOOL bWasVisible = pWindow->IsVisible();
- Point aOldPos( pWindow->GetPosPixel() );
-
- if ( bWasVisible && aOldPos == aPos )
+ // #i40647# don't draw here if this is a recursive call
+ // sometimes this is called recursively, because the Update call on the parent
+ // (strangely) triggers another paint. Prevent a stack overflow here
+ // Yes, this is only fixing symptoms for the moment ....
+ // #i40647# / 2005-01-18 / frank.schoenheit@sun.com
+ if ( !mbDrawingOntoParent )
{
- pWindow->Update();
- return;
- }
+ mbDrawingOntoParent = true;
+
+ BOOL bWasVisible = pWindow->IsVisible();
+ Point aOldPos( pWindow->GetPosPixel() );
+
+ if ( bWasVisible && aOldPos == aPos )
+ {
+ pWindow->Update();
+ return;
+ }
- pWindow->SetPosPixel( aPos );
+ pWindow->SetPosPixel( aPos );
- // Erstmal ein Update auf den Parent, damit nicht beim Update
- // auf dieses Fenster noch ein Paint vom Parent abgearbeitet wird,
- // wo dann ggf. dieses Fenster sofort wieder gehidet wird.
- if( pWindow->GetParent() )
- pWindow->GetParent()->Update();
+ // Erstmal ein Update auf den Parent, damit nicht beim Update
+ // auf dieses Fenster noch ein Paint vom Parent abgearbeitet wird,
+ // wo dann ggf. dieses Fenster sofort wieder gehidet wird.
+ if( pWindow->GetParent() )
+ pWindow->GetParent()->Update();
- pWindow->Show();
- pWindow->Update();
- pWindow->SetParentUpdateMode( sal_False );
- pWindow->Hide();
- pWindow->SetParentUpdateMode( sal_True );
+ pWindow->Show();
+ pWindow->Update();
+ pWindow->SetParentUpdateMode( sal_False );
+ pWindow->Hide();
+ pWindow->SetParentUpdateMode( sal_True );
- pWindow->SetPosPixel( aOldPos );
- if ( bWasVisible )
- pWindow->Show( TRUE );
+ pWindow->SetPosPixel( aOldPos );
+ if ( bWasVisible )
+ pWindow->Show( TRUE );
+
+ mbDrawingOntoParent = false;
+ }
}
else if ( pDev )
{