1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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 // The body of this file is only used when PresenterWindowManager defines
21 // the preprocessor symbol ENABLE_PANE_RESIZING, which by default is not the
23 #ifdef ENABLE_PANE_RESIZING
25 #include "PresenterPaneBorderManager.hxx"
26 #include "PresenterController.hxx"
27 #include "PresenterPaintManager.hxx"
28 #include <com/sun/star/awt/PosSize.hpp>
29 #include <com/sun/star/awt/SystemPointer.hpp>
30 #include <com/sun/star/awt/WindowAttribute.hpp>
31 #include <com/sun/star/awt/WindowDescriptor.hpp>
32 #include <com/sun/star/awt/WindowClass.hpp>
33 #include <com/sun/star/awt/XWindow2.hpp>
34 #include <com/sun/star/awt/XWindowPeer.hpp>
35 #include <com/sun/star/lang/XMultiComponentFactory.hpp>
36 #include <cppuhelper/compbase1.hxx>
37 #include <osl/mutex.hxx>
39 using namespace ::com::sun::star
;
40 using namespace ::com::sun::star::uno
;
42 namespace sdext
{ namespace presenter
{
44 //===== Service ===============================================================
46 OUString
PresenterPaneBorderManager::getImplementationName_static()
48 return OUString("com.sun.star.comp.Draw.PresenterPaneBorderManager");
51 Sequence
<OUString
> PresenterPaneBorderManager::getSupportedServiceNames_static()
53 static const OUString
sServiceName(
54 "com.sun.star.drawing.PresenterPaneBorderManager");
55 return Sequence
<OUString
>(&sServiceName
, 1);
58 Reference
<XInterface
> PresenterPaneBorderManager::Create (const Reference
<uno::XComponentContext
>& rxContext
)
60 return Reference
<XInterface
>(static_cast<XWeak
*>(
61 new PresenterPaneBorderManager(rxContext
, NULL
)));
64 //===== PresenterPaneBorderManager ============================================
66 PresenterPaneBorderManager::PresenterPaneBorderManager (
67 const Reference
<XComponentContext
>& rxContext
,
68 const ::rtl::Reference
<PresenterController
>& rpPresenterController
)
69 : PresenterPaneBorderManagerInterfaceBase(m_aMutex
),
70 mpPresenterController(rpPresenterController
),
71 mxComponentContext(rxContext
),
81 Reference
<lang::XMultiComponentFactory
> xFactory (rxContext
->getServiceManager());
84 mxPointer
= awt::Pointer::create(rxContext
);
86 mxPresenterHelper
= Reference
<drawing::XPresenterHelper
>(
87 xFactory
->createInstanceWithContext(
88 OUString("com.sun.star.comp.Draw.PresenterHelper"),
94 PresenterPaneBorderManager::~PresenterPaneBorderManager()
98 void PresenterPaneBorderManager::disposing()
100 WindowList::const_iterator iDescriptor
;
101 for (iDescriptor
=maWindowList
.begin(); iDescriptor
!=maWindowList
.end(); ++iDescriptor
)
103 iDescriptor
->first
->removeMouseListener(this);
104 iDescriptor
->first
->removeMouseMotionListener(this);
106 maWindowList
.clear();
110 const static sal_Int32 mnOutside
= 0;
111 const static sal_Int32 mnLeft
= 0x01;
112 const static sal_Int32 mnHorizontalCenter
= 0x02;
113 const static sal_Int32 mnRight
= 0x04;
114 const static sal_Int32 mnTop
= 0x10;
115 const static sal_Int32 mnVerticalCenter
= 0x20;
116 const static sal_Int32 mnBottom
= 0x40;
119 PresenterPaneBorderManager::BorderElement
120 PresenterPaneBorderManager::ClassifyBorderElementUnderMouse (
121 const Reference
<awt::XWindow
>& rxOuterWindow
,
122 const Reference
<awt::XWindow
>& rxInnerWindow
,
123 const awt::Point aPosition
) const
125 OSL_ASSERT(rxOuterWindow
.is());
126 OSL_ASSERT(rxInnerWindow
.is());
128 awt::Rectangle
aOuterBox (rxOuterWindow
->getPosSize());
129 const awt::Rectangle
aInnerBox (rxInnerWindow
->getPosSize());
131 // Coordinates of the pointer position are given in the window
132 // coordinate system. Therefore the upper left corner of the outer box
139 // Add horizontal classification to nCode.
140 if (aPosition
.X
< aInnerBox
.X
)
141 if (aPosition
.X
< aOuterBox
.X
)
145 else if (aPosition
.X
>= aInnerBox
.X
+aInnerBox
.Width
)
146 if (aPosition
.X
>= aOuterBox
.X
+aOuterBox
.Width
)
151 nCode
= mnHorizontalCenter
;
153 // Add vertical classification to nCode.
154 if (aPosition
.Y
< aInnerBox
.Y
)
155 if (aPosition
.Y
< aOuterBox
.Y
)
159 else if (aPosition
.Y
>= aInnerBox
.Y
+aInnerBox
.Height
)
160 if (aPosition
.Y
>= aOuterBox
.Y
+aOuterBox
.Height
)
165 nCode
|= mnVerticalCenter
;
167 // Translate bits in nCode into BorderElement value.
171 case mnOutside
| mnLeft
:
172 case mnOutside
| mnRight
:
173 case mnOutside
| mnHorizontalCenter
:
174 case mnTop
| mnOutside
:
175 case mnBottom
| mnOutside
:
176 case mnVerticalCenter
| mnOutside
:
180 case mnVerticalCenter
| mnHorizontalCenter
:
186 case mnTop
| mnRight
:
189 case mnTop
| mnHorizontalCenter
:
192 case mnBottom
| mnLeft
:
195 case mnBottom
| mnRight
:
198 case mnBottom
| mnHorizontalCenter
:
201 case mnVerticalCenter
| mnLeft
:
204 case mnVerticalCenter
| mnRight
:
209 //----- XInitialization -------------------------------------------------------
211 void SAL_CALL
PresenterPaneBorderManager::initialize (const Sequence
<Any
>& rArguments
)
212 throw (Exception
, RuntimeException
)
216 if (rArguments
.getLength()%2 == 1 && mxComponentContext
.is())
220 mxParentWindow
= Reference
<awt::XWindow
>(rArguments
[0], UNO_QUERY_THROW
);
222 // Get the outer and inner windows from the argument list and
223 // build a window list of it.
224 for (sal_Int32 nIndex
=1; nIndex
<rArguments
.getLength(); nIndex
+=2)
226 Reference
<awt::XWindow
> xOuterWindow (rArguments
[nIndex
], UNO_QUERY_THROW
);
227 Reference
<awt::XWindow
> xInnerWindow (rArguments
[nIndex
+1], UNO_QUERY_THROW
);
229 maWindowList
.push_back(WindowDescriptor(xOuterWindow
,xInnerWindow
));
231 xOuterWindow
->addMouseListener(this);
232 xOuterWindow
->addMouseMotionListener(this);
235 catch (RuntimeException
&)
237 PresenterPaneBorderManager::disposing();
243 throw RuntimeException(
244 "PresenterPane: invalid number of arguments",
245 static_cast<XWeak
*>(this));
249 //----- XMouseListener --------------------------------------------------------
251 void SAL_CALL
PresenterPaneBorderManager::mousePressed (const css::awt::MouseEvent
& rEvent
)
252 throw (css::uno::RuntimeException
)
255 ::osl::MutexGuard
aGuard (::osl::Mutex::getGlobalMutex());
257 // Find window descriptor of the window that has been clicked.
258 WindowList::const_iterator iDescriptor
;
259 for (iDescriptor
=maWindowList
.begin(); iDescriptor
!=maWindowList
.end(); ++iDescriptor
)
260 if (iDescriptor
->first
== rEvent
.Source
)
263 if (iDescriptor
!= maWindowList
.end())
266 mxOuterDragWindow
= iDescriptor
->first
;
267 mxInnerDragWindow
= iDescriptor
->second
;
268 OSL_ASSERT(mxOuterDragWindow
.is() && mxInnerDragWindow
.is());
269 const awt::Rectangle
aOuterBox (mxOuterDragWindow
->getPosSize());
270 maDragAnchor
.X
= rEvent
.X
+ aOuterBox
.X
;
271 maDragAnchor
.Y
= rEvent
.Y
+ aOuterBox
.Y
;
272 meDragType
= ClassifyBorderElementUnderMouse(
275 awt::Point(rEvent
.X
, rEvent
.Y
));
279 void SAL_CALL
PresenterPaneBorderManager::mouseReleased (const css::awt::MouseEvent
& rEvent
)
280 throw (css::uno::RuntimeException
)
284 ::osl::MutexGuard
aGuard (::osl::Mutex::getGlobalMutex());
286 ReleaseMouse(mxOuterDragWindow
);
287 meDragType
= PresenterPaneBorderManager::Outside
;
288 mxOuterDragWindow
= NULL
;
289 mxInnerDragWindow
= NULL
;
292 void SAL_CALL
PresenterPaneBorderManager::mouseEntered (const css::awt::MouseEvent
& rEvent
)
293 throw (css::uno::RuntimeException
)
298 void SAL_CALL
PresenterPaneBorderManager::mouseExited (const css::awt::MouseEvent
& rEvent
)
299 throw (css::uno::RuntimeException
)
303 ::osl::MutexGuard
aGuard (::osl::Mutex::getGlobalMutex());
305 ReleaseMouse(mxOuterDragWindow
);
306 meDragType
= PresenterPaneBorderManager::Outside
;
307 mxOuterDragWindow
= NULL
;
308 mxInnerDragWindow
= NULL
;
311 //----- XMouseMotionListener --------------------------------------------------
313 void SAL_CALL
PresenterPaneBorderManager::mouseMoved (const css::awt::MouseEvent
& rEvent
)
314 throw (css::uno::RuntimeException
)
317 ::osl::MutexGuard
aGuard (::osl::Mutex::getGlobalMutex());
319 WindowList::const_iterator iDescriptor
;
320 for (iDescriptor
=maWindowList
.begin(); iDescriptor
!=maWindowList
.end(); ++iDescriptor
)
321 if (iDescriptor
->first
== rEvent
.Source
)
323 if (iDescriptor
!= maWindowList
.end())
325 // Choose pointer shape according to position in the window border.
326 switch (ClassifyBorderElementUnderMouse(
329 awt::Point(rEvent
.X
,rEvent
.Y
)))
331 case PresenterPaneBorderManager::Top
:
332 mnPointerType
= awt::SystemPointer::MOVE
;
334 case PresenterPaneBorderManager::TopLeft
:
335 mnPointerType
= awt::SystemPointer::WINDOW_NWSIZE
;
337 case PresenterPaneBorderManager::TopRight
:
338 mnPointerType
= awt::SystemPointer::WINDOW_NESIZE
;
340 case PresenterPaneBorderManager::Left
:
341 mnPointerType
= awt::SystemPointer::WINDOW_WSIZE
;
343 case PresenterPaneBorderManager::Right
:
344 mnPointerType
= awt::SystemPointer::WINDOW_ESIZE
;
346 case PresenterPaneBorderManager::BottomLeft
:
347 mnPointerType
= awt::SystemPointer::WINDOW_SWSIZE
;
349 case PresenterPaneBorderManager::BottomRight
:
350 mnPointerType
= awt::SystemPointer::WINDOW_SESIZE
;
352 case PresenterPaneBorderManager::Bottom
:
353 mnPointerType
= awt::SystemPointer::WINDOW_SSIZE
;
356 case PresenterPaneBorderManager::Content
:
357 case PresenterPaneBorderManager::Outside
:
359 mnPointerType
= awt::SystemPointer::ARROW
;
363 // Make the pointer shape visible.
364 Reference
<awt::XWindowPeer
> xPeer (iDescriptor
->first
, UNO_QUERY
);
368 mxPointer
->setType(mnPointerType
);
369 xPeer
->setPointer(mxPointer
);
374 void SAL_CALL
PresenterPaneBorderManager::mouseDragged (const css::awt::MouseEvent
& rEvent
)
375 throw (css::uno::RuntimeException
)
378 ::osl::MutexGuard
aGuard (::osl::Mutex::getGlobalMutex());
380 if ( ! mxOuterDragWindow
.is())
383 CaptureMouse(mxOuterDragWindow
);
385 const awt::Rectangle
aOldBox (mxOuterDragWindow
->getPosSize());
386 const sal_Int32 nX
= rEvent
.X
+ aOldBox
.X
;
387 const sal_Int32 nY
= rEvent
.Y
+ aOldBox
.Y
;
388 const sal_Int32 nDiffX
= nX
- maDragAnchor
.X
;
389 const sal_Int32 nDiffY
= nY
- maDragAnchor
.Y
;
393 const sal_Int32 nOldRight
= aOldBox
.X
+ aOldBox
.Width
;
394 const sal_Int32 nOldBottom
= aOldBox
.Y
+ aOldBox
.Height
;
396 awt::Rectangle
aBox (aOldBox
);
397 sal_Int32 nRight
= aBox
.X
+ aBox
.Width
;
398 sal_Int32 nBottom
= aBox
.Y
+ aBox
.Height
;
400 // Update position and/or size according to initial pointer position
401 // inside the window border.
404 case PresenterPaneBorderManager::Top
:
405 aBox
.X
+= nDiffX
; aBox
.Y
+= nDiffY
;
406 nRight
+= nDiffX
; nBottom
+= nDiffY
;
408 case PresenterPaneBorderManager::TopLeft
:
409 aBox
.X
+= nDiffX
; aBox
.Y
+= nDiffY
;
411 case PresenterPaneBorderManager::TopRight
:
412 nRight
+= nDiffX
; aBox
.Y
+= nDiffY
;
414 case PresenterPaneBorderManager::Left
:
417 case PresenterPaneBorderManager::Right
:
420 case PresenterPaneBorderManager::BottomLeft
:
421 aBox
.X
+= nDiffX
; nBottom
+= nDiffY
;
423 case PresenterPaneBorderManager::BottomRight
:
424 nRight
+= nDiffX
; nBottom
+= nDiffY
;
426 case PresenterPaneBorderManager::Bottom
:
432 aBox
.Width
= nRight
- aBox
.X
;
433 aBox
.Height
= nBottom
- aBox
.Y
;
437 // Set position and/or size of the border window to the new values.
438 sal_Int16
nFlags (0);
439 if (aBox
.X
!= aOldBox
.X
)
440 nFlags
|= awt::PosSize::X
;
441 if (aBox
.Y
!= aOldBox
.Y
)
442 nFlags
|= awt::PosSize::Y
;
443 if (aBox
.Width
!= aOldBox
.Width
)
444 nFlags
|= awt::PosSize::WIDTH
;
445 if (aBox
.Height
!= aOldBox
.Height
)
446 nFlags
|= awt::PosSize::HEIGHT
;
447 mxOuterDragWindow
->setPosSize(aBox
.X
, aBox
.Y
, aBox
.Width
, aBox
.Height
, nFlags
);
449 // Invalidate that is or was covered by the border window before and
450 // after the move/resize.
451 if (mpPresenterController
.get() != NULL
)
453 const sal_Int32 nLeft
= ::std::min(aOldBox
.X
,aBox
.X
);
454 const sal_Int32 nTop
= ::std::min(aOldBox
.Y
,aBox
.Y
);
455 const sal_Int32 nWidth
= ::std::max(nOldRight
,nRight
) - nLeft
;
456 const sal_Int32 nHeight
= ::std::max(nOldBottom
,nBottom
) - nTop
;
458 OSL_ASSERT(mpPresenterController
->GetPaintManager().get()!=NULL
);
459 mpPresenterController
->GetPaintManager()->Invalidate(
461 ::awt::Rectangle(nLeft
,nTop
,nWidth
-1,nHeight
-1));
466 //----- lang::XEventListener --------------------------------------------------
468 void SAL_CALL
PresenterPaneBorderManager::disposing (const lang::EventObject
& rEvent
)
469 throw (RuntimeException
)
471 WindowList::iterator iDescriptor
;
472 for (iDescriptor
=maWindowList
.begin(); iDescriptor
!=maWindowList
.end(); ++iDescriptor
)
473 if (iDescriptor
->first
== rEvent
.Source
)
475 maWindowList
.erase(iDescriptor
);
482 void PresenterPaneBorderManager::CaptureMouse (const Reference
<awt::XWindow
>& rxWindow
)
484 if (mxPresenterHelper
.is())
485 mxPresenterHelper
->captureMouse(rxWindow
);
488 void PresenterPaneBorderManager::ReleaseMouse (const Reference
<awt::XWindow
>& rxWindow
)
490 if (mxPresenterHelper
.is())
491 mxPresenterHelper
->releaseMouse(rxWindow
);
494 void PresenterPaneBorderManager::ThrowIfDisposed()
495 throw (::com::sun::star::lang::DisposedException
)
497 if (rBHelper
.bDisposed
|| rBHelper
.bInDispose
)
499 throw lang::DisposedException (
500 "PresenterPaneBorderManager object has already been disposed",
501 static_cast<uno::XWeak
*>(this));
505 } } // end of namespace ::sd::presenter
507 #endif // ENABLE_PANE_RESIZING
509 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */