1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: PresenterPaneBorderManager.cxx,v $
13 * This file is part of OpenOffice.org.
15 * OpenOffice.org is free software: you can redistribute it and/or modify
16 * it under the terms of the GNU Lesser General Public License version 3
17 * only, as published by the Free Software Foundation.
19 * OpenOffice.org is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU Lesser General Public License version 3 for more details
23 * (a copy is included in the LICENSE file that accompanied this code).
25 * You should have received a copy of the GNU Lesser General Public License
26 * version 3 along with OpenOffice.org. If not, see
27 * <http://www.openoffice.org/license.html>
28 * for a copy of the LGPLv3 License.
30 ************************************************************************/
32 // MARKER(update_precomp.py): autogen include statement, do not remove
33 #include "precompiled_sdext.hxx"
35 // The body of this file is only used when PresenterWindowManager defines
36 // the preprocessor symbol ENABLE_PANE_RESIZING, which by default is not the
38 #ifdef ENABLE_PANE_RESIZING
40 #include "PresenterPaneBorderManager.hxx"
41 #include "PresenterController.hxx"
42 #include "PresenterPaintManager.hxx"
43 #include <com/sun/star/awt/PosSize.hpp>
44 #include <com/sun/star/awt/SystemPointer.hpp>
45 #include <com/sun/star/awt/WindowAttribute.hpp>
46 #include <com/sun/star/awt/WindowDescriptor.hpp>
47 #include <com/sun/star/awt/WindowClass.hpp>
48 #include <com/sun/star/awt/XWindow2.hpp>
49 #include <com/sun/star/awt/XWindowPeer.hpp>
50 #include <com/sun/star/lang/XMultiComponentFactory.hpp>
51 #include <cppuhelper/compbase1.hxx>
52 #include <osl/mutex.hxx>
53 #include <boost/weak_ptr.hpp>
55 using namespace ::com::sun::star
;
56 using namespace ::com::sun::star::uno
;
57 using ::rtl::OUString
;
59 namespace sdext
{ namespace presenter
{
61 //===== Service ===============================================================
64 OUString
PresenterPaneBorderManager::getImplementationName_static (void)
66 return OUString::createFromAscii("com.sun.star.comp.Draw.PresenterPaneBorderManager");
72 Sequence
<OUString
> PresenterPaneBorderManager::getSupportedServiceNames_static (void)
74 static const ::rtl::OUString
sServiceName(
75 ::rtl::OUString::createFromAscii("com.sun.star.drawing.PresenterPaneBorderManager"));
76 return Sequence
<rtl::OUString
>(&sServiceName
, 1);
82 Reference
<XInterface
> PresenterPaneBorderManager::Create (const Reference
<uno::XComponentContext
>& rxContext
)
83 SAL_THROW((css::uno::Exception
))
85 return Reference
<XInterface
>(static_cast<XWeak
*>(
86 new PresenterPaneBorderManager(rxContext
, NULL
)));
92 //===== PresenterPaneBorderManager ============================================
94 PresenterPaneBorderManager::PresenterPaneBorderManager (
95 const Reference
<XComponentContext
>& rxContext
,
96 const ::rtl::Reference
<PresenterController
>& rpPresenterController
)
97 : PresenterPaneBorderManagerInterfaceBase(m_aMutex
),
98 mpPresenterController(rpPresenterController
),
99 mxComponentContext(rxContext
),
109 Reference
<lang::XMultiComponentFactory
> xFactory (rxContext
->getServiceManager());
112 mxPointer
= Reference
<awt::XPointer
>(
113 xFactory
->createInstanceWithContext(
114 OUString::createFromAscii("com.sun.star.awt.Pointer"),
118 mxPresenterHelper
= Reference
<drawing::XPresenterHelper
>(
119 xFactory
->createInstanceWithContext(
120 OUString::createFromAscii("com.sun.star.comp.Draw.PresenterHelper"),
129 PresenterPaneBorderManager::~PresenterPaneBorderManager (void)
136 void PresenterPaneBorderManager::disposing (void)
138 WindowList::const_iterator iDescriptor
;
139 for (iDescriptor
=maWindowList
.begin(); iDescriptor
!=maWindowList
.end(); ++iDescriptor
)
141 iDescriptor
->first
->removeMouseListener(this);
142 iDescriptor
->first
->removeMouseMotionListener(this);
144 maWindowList
.clear();
151 const static sal_Int32 mnOutside
= 0;
152 const static sal_Int32 mnLeft
= 0x01;
153 const static sal_Int32 mnHorizontalCenter
= 0x02;
154 const static sal_Int32 mnRight
= 0x04;
155 const static sal_Int32 mnTop
= 0x10;
156 const static sal_Int32 mnVerticalCenter
= 0x20;
157 const static sal_Int32 mnBottom
= 0x40;
160 PresenterPaneBorderManager::BorderElement
161 PresenterPaneBorderManager::ClassifyBorderElementUnderMouse (
162 const Reference
<awt::XWindow
>& rxOuterWindow
,
163 const Reference
<awt::XWindow
>& rxInnerWindow
,
164 const awt::Point aPosition
) const
166 OSL_ASSERT(rxOuterWindow
.is());
167 OSL_ASSERT(rxInnerWindow
.is());
169 awt::Rectangle
aOuterBox (rxOuterWindow
->getPosSize());
170 const awt::Rectangle
aInnerBox (rxInnerWindow
->getPosSize());
172 // Coordinates of the pointer position are given in the window
173 // coordinate system. Therefore the upper left corner of the outer box
180 // Add horizontal classification to nCode.
181 if (aPosition
.X
< aInnerBox
.X
)
182 if (aPosition
.X
< aOuterBox
.X
)
186 else if (aPosition
.X
>= aInnerBox
.X
+aInnerBox
.Width
)
187 if (aPosition
.X
>= aOuterBox
.X
+aOuterBox
.Width
)
192 nCode
= mnHorizontalCenter
;
194 // Add vertical classification to nCode.
195 if (aPosition
.Y
< aInnerBox
.Y
)
196 if (aPosition
.Y
< aOuterBox
.Y
)
200 else if (aPosition
.Y
>= aInnerBox
.Y
+aInnerBox
.Height
)
201 if (aPosition
.Y
>= aOuterBox
.Y
+aOuterBox
.Height
)
206 nCode
|= mnVerticalCenter
;
208 // Translate bits in nCode into BorderElement value.
211 case mnOutside
| mnOutside
:
212 case mnOutside
| mnLeft
:
213 case mnOutside
| mnRight
:
214 case mnOutside
| mnHorizontalCenter
:
215 case mnTop
| mnOutside
:
216 case mnBottom
| mnOutside
:
217 case mnVerticalCenter
| mnOutside
:
221 case mnVerticalCenter
| mnHorizontalCenter
:
227 case mnTop
| mnRight
:
230 case mnTop
| mnHorizontalCenter
:
233 case mnBottom
| mnLeft
:
236 case mnBottom
| mnRight
:
239 case mnBottom
| mnHorizontalCenter
:
242 case mnVerticalCenter
| mnLeft
:
245 case mnVerticalCenter
| mnRight
:
253 //----- XInitialization -------------------------------------------------------
255 void SAL_CALL
PresenterPaneBorderManager::initialize (const Sequence
<Any
>& rArguments
)
256 throw (Exception
, RuntimeException
)
260 if (rArguments
.getLength()%2 == 1 && mxComponentContext
.is())
264 mxParentWindow
= Reference
<awt::XWindow
>(rArguments
[0], UNO_QUERY_THROW
);
266 // Get the outer and inner windows from the argument list and
267 // build a window list of it.
268 for (sal_Int32 nIndex
=1; nIndex
<rArguments
.getLength(); nIndex
+=2)
270 Reference
<awt::XWindow
> xOuterWindow (rArguments
[nIndex
], UNO_QUERY_THROW
);
271 Reference
<awt::XWindow
> xInnerWindow (rArguments
[nIndex
+1], UNO_QUERY_THROW
);
273 maWindowList
.push_back(WindowDescriptor(xOuterWindow
,xInnerWindow
));
275 xOuterWindow
->addMouseListener(this);
276 xOuterWindow
->addMouseMotionListener(this);
279 catch (RuntimeException
&)
281 PresenterPaneBorderManager::disposing();
287 throw RuntimeException(
288 OUString::createFromAscii("PresenterPane: invalid number of arguments"),
289 static_cast<XWeak
*>(this));
296 //----- XMouseListener --------------------------------------------------------
298 void SAL_CALL
PresenterPaneBorderManager::mousePressed (const css::awt::MouseEvent
& rEvent
)
299 throw (css::uno::RuntimeException
)
302 ::osl::MutexGuard
aGuard (::osl::Mutex::getGlobalMutex());
304 // Find window descriptor of the window that has been clicked.
305 WindowList::const_iterator iDescriptor
;
306 for (iDescriptor
=maWindowList
.begin(); iDescriptor
!=maWindowList
.end(); ++iDescriptor
)
307 if (iDescriptor
->first
== rEvent
.Source
)
310 if (iDescriptor
!= maWindowList
.end())
313 mxOuterDragWindow
= iDescriptor
->first
;
314 mxInnerDragWindow
= iDescriptor
->second
;
315 OSL_ASSERT(mxOuterDragWindow
.is() && mxInnerDragWindow
.is());
316 const awt::Rectangle
aOuterBox (mxOuterDragWindow
->getPosSize());
317 maDragAnchor
.X
= rEvent
.X
+ aOuterBox
.X
;
318 maDragAnchor
.Y
= rEvent
.Y
+ aOuterBox
.Y
;
319 meDragType
= ClassifyBorderElementUnderMouse(
322 awt::Point(rEvent
.X
, rEvent
.Y
));
329 void SAL_CALL
PresenterPaneBorderManager::mouseReleased (const css::awt::MouseEvent
& rEvent
)
330 throw (css::uno::RuntimeException
)
334 ::osl::MutexGuard
aGuard (::osl::Mutex::getGlobalMutex());
336 ReleaseMouse(mxOuterDragWindow
);
337 meDragType
= PresenterPaneBorderManager::Outside
;
338 mxOuterDragWindow
= NULL
;
339 mxInnerDragWindow
= NULL
;
345 void SAL_CALL
PresenterPaneBorderManager::mouseEntered (const css::awt::MouseEvent
& rEvent
)
346 throw (css::uno::RuntimeException
)
354 void SAL_CALL
PresenterPaneBorderManager::mouseExited (const css::awt::MouseEvent
& rEvent
)
355 throw (css::uno::RuntimeException
)
359 ::osl::MutexGuard
aGuard (::osl::Mutex::getGlobalMutex());
361 ReleaseMouse(mxOuterDragWindow
);
362 meDragType
= PresenterPaneBorderManager::Outside
;
363 mxOuterDragWindow
= NULL
;
364 mxInnerDragWindow
= NULL
;
370 //----- XMouseMotionListener --------------------------------------------------
372 void SAL_CALL
PresenterPaneBorderManager::mouseMoved (const css::awt::MouseEvent
& rEvent
)
373 throw (css::uno::RuntimeException
)
376 ::osl::MutexGuard
aGuard (::osl::Mutex::getGlobalMutex());
378 WindowList::const_iterator iDescriptor
;
379 for (iDescriptor
=maWindowList
.begin(); iDescriptor
!=maWindowList
.end(); ++iDescriptor
)
380 if (iDescriptor
->first
== rEvent
.Source
)
382 if (iDescriptor
!= maWindowList
.end())
384 // Choose pointer shape according to position in the window border.
385 switch (ClassifyBorderElementUnderMouse(
388 awt::Point(rEvent
.X
,rEvent
.Y
)))
390 case PresenterPaneBorderManager::Top
:
391 mnPointerType
= awt::SystemPointer::MOVE
;
393 case PresenterPaneBorderManager::TopLeft
:
394 mnPointerType
= awt::SystemPointer::WINDOW_NWSIZE
;
396 case PresenterPaneBorderManager::TopRight
:
397 mnPointerType
= awt::SystemPointer::WINDOW_NESIZE
;
399 case PresenterPaneBorderManager::Left
:
400 mnPointerType
= awt::SystemPointer::WINDOW_WSIZE
;
402 case PresenterPaneBorderManager::Right
:
403 mnPointerType
= awt::SystemPointer::WINDOW_ESIZE
;
405 case PresenterPaneBorderManager::BottomLeft
:
406 mnPointerType
= awt::SystemPointer::WINDOW_SWSIZE
;
408 case PresenterPaneBorderManager::BottomRight
:
409 mnPointerType
= awt::SystemPointer::WINDOW_SESIZE
;
411 case PresenterPaneBorderManager::Bottom
:
412 mnPointerType
= awt::SystemPointer::WINDOW_SSIZE
;
415 case PresenterPaneBorderManager::Content
:
416 case PresenterPaneBorderManager::Outside
:
418 mnPointerType
= awt::SystemPointer::ARROW
;
422 // Make the pointer shape visible.
423 Reference
<awt::XWindowPeer
> xPeer (iDescriptor
->first
, UNO_QUERY
);
427 mxPointer
->setType(mnPointerType
);
428 xPeer
->setPointer(mxPointer
);
436 void SAL_CALL
PresenterPaneBorderManager::mouseDragged (const css::awt::MouseEvent
& rEvent
)
437 throw (css::uno::RuntimeException
)
440 ::osl::MutexGuard
aGuard (::osl::Mutex::getGlobalMutex());
442 if ( ! mxOuterDragWindow
.is())
445 CaptureMouse(mxOuterDragWindow
);
447 const awt::Rectangle
aOldBox (mxOuterDragWindow
->getPosSize());
448 const sal_Int32 nX
= rEvent
.X
+ aOldBox
.X
;
449 const sal_Int32 nY
= rEvent
.Y
+ aOldBox
.Y
;
450 const sal_Int32 nDiffX
= nX
- maDragAnchor
.X
;
451 const sal_Int32 nDiffY
= nY
- maDragAnchor
.Y
;
455 const sal_Int32 nOldRight
= aOldBox
.X
+ aOldBox
.Width
;
456 const sal_Int32 nOldBottom
= aOldBox
.Y
+ aOldBox
.Height
;
458 awt::Rectangle
aBox (aOldBox
);
459 sal_Int32 nRight
= aBox
.X
+ aBox
.Width
;
460 sal_Int32 nBottom
= aBox
.Y
+ aBox
.Height
;
462 // Update position and/or size according to initial pointer position
463 // inside the window border.
466 case PresenterPaneBorderManager::Top
:
467 aBox
.X
+= nDiffX
; aBox
.Y
+= nDiffY
;
468 nRight
+= nDiffX
; nBottom
+= nDiffY
;
470 case PresenterPaneBorderManager::TopLeft
:
471 aBox
.X
+= nDiffX
; aBox
.Y
+= nDiffY
;
473 case PresenterPaneBorderManager::TopRight
:
474 nRight
+= nDiffX
; aBox
.Y
+= nDiffY
;
476 case PresenterPaneBorderManager::Left
:
479 case PresenterPaneBorderManager::Right
:
482 case PresenterPaneBorderManager::BottomLeft
:
483 aBox
.X
+= nDiffX
; nBottom
+= nDiffY
;
485 case PresenterPaneBorderManager::BottomRight
:
486 nRight
+= nDiffX
; nBottom
+= nDiffY
;
488 case PresenterPaneBorderManager::Bottom
:
494 aBox
.Width
= nRight
- aBox
.X
;
495 aBox
.Height
= nBottom
- aBox
.Y
;
499 // Set position and/or size of the border window to the new values.
500 sal_Int16
nFlags (0);
501 if (aBox
.X
!= aOldBox
.X
)
502 nFlags
|= awt::PosSize::X
;
503 if (aBox
.Y
!= aOldBox
.Y
)
504 nFlags
|= awt::PosSize::Y
;
505 if (aBox
.Width
!= aOldBox
.Width
)
506 nFlags
|= awt::PosSize::WIDTH
;
507 if (aBox
.Height
!= aOldBox
.Height
)
508 nFlags
|= awt::PosSize::HEIGHT
;
509 mxOuterDragWindow
->setPosSize(aBox
.X
, aBox
.Y
, aBox
.Width
, aBox
.Height
, nFlags
);
511 // Invalidate that is or was covered by the border window before and
512 // after the move/resize.
513 if (mpPresenterController
.get() != NULL
)
515 const sal_Int32 nLeft
= ::std::min(aOldBox
.X
,aBox
.X
);
516 const sal_Int32 nTop
= ::std::min(aOldBox
.Y
,aBox
.Y
);
517 const sal_Int32 nWidth
= ::std::max(nOldRight
,nRight
) - nLeft
;
518 const sal_Int32 nHeight
= ::std::max(nOldBottom
,nBottom
) - nTop
;
520 OSL_ASSERT(mpPresenterController
->GetPaintManager().get()!=NULL
);
521 mpPresenterController
->GetPaintManager()->Invalidate(
523 ::awt::Rectangle(nLeft
,nTop
,nWidth
-1,nHeight
-1));
531 //----- lang::XEventListener --------------------------------------------------
533 void SAL_CALL
PresenterPaneBorderManager::disposing (const lang::EventObject
& rEvent
)
534 throw (RuntimeException
)
536 WindowList::iterator iDescriptor
;
537 for (iDescriptor
=maWindowList
.begin(); iDescriptor
!=maWindowList
.end(); ++iDescriptor
)
538 if (iDescriptor
->first
== rEvent
.Source
)
540 maWindowList
.erase(iDescriptor
);
548 //-----------------------------------------------------------------------------
551 void PresenterPaneBorderManager::CaptureMouse (const Reference
<awt::XWindow
>& rxWindow
)
553 if (mxPresenterHelper
.is())
554 mxPresenterHelper
->captureMouse(rxWindow
);
560 void PresenterPaneBorderManager::ReleaseMouse (const Reference
<awt::XWindow
>& rxWindow
)
562 if (mxPresenterHelper
.is())
563 mxPresenterHelper
->releaseMouse(rxWindow
);
569 void PresenterPaneBorderManager::ThrowIfDisposed (void)
570 throw (::com::sun::star::lang::DisposedException
)
572 if (rBHelper
.bDisposed
|| rBHelper
.bInDispose
)
574 throw lang::DisposedException (
575 ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
576 "PresenterPaneBorderManager object has already been disposed")),
577 static_cast<uno::XWeak
*>(this));
584 } } // end of namespace ::sd::presenter
586 #endif // ENABLE_PANE_RESIZING