From da9acaf848c36deb03ccdacf664b84c59992abbe Mon Sep 17 00:00:00 2001 From: Kurt Zenker Date: Thu, 3 Apr 2008 15:01:20 +0000 Subject: INTEGRATION: CWS presenterview (1.1.2); FILE ADDED 2008/02/26 15:10:30 af 1.1.2.3: #i18486# Removed OSL_TRACEs. 2008/01/23 15:16:53 af 1.1.2.2: #i18486# Fixed Linux compilation problems. 2008/01/21 15:41:19 af 1.1.2.1: #i18486# Initial revision. --- .../presenter/PresenterPaneBorderManager.cxx | 575 +++++++++++++++++++++ 1 file changed, 575 insertions(+) create mode 100644 sdext/source/presenter/PresenterPaneBorderManager.cxx (limited to 'sdext/source/presenter/PresenterPaneBorderManager.cxx') diff --git a/sdext/source/presenter/PresenterPaneBorderManager.cxx b/sdext/source/presenter/PresenterPaneBorderManager.cxx new file mode 100644 index 000000000000..689492defea5 --- /dev/null +++ b/sdext/source/presenter/PresenterPaneBorderManager.cxx @@ -0,0 +1,575 @@ +/************************************************************************* + * + * OpenOffice.org - a multi-platform office productivity suite + * + * $RCSfile: PresenterPaneBorderManager.cxx,v $ + * + * $Revision: 1.2 $ + * + * last change: $Author: kz $ $Date: 2008-04-03 16:01:20 $ + * + * The Contents of this file are made available subject to + * the terms of GNU Lesser General Public License Version 2.1. + * + * + * GNU Lesser General Public License Version 2.1 + * ============================================= + * Copyright 2005 by Sun Microsystems, Inc. + * 901 San Antonio Road, Palo Alto, CA 94303, USA + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + ************************************************************************/ + +#include "PresenterPaneBorderManager.hxx" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace ::com::sun::star; +using namespace ::com::sun::star::uno; +using ::rtl::OUString; + +namespace sdext { namespace presenter { + +//===== Service =============================================================== + + +OUString PresenterPaneBorderManager::getImplementationName_static (void) +{ + return OUString::createFromAscii("com.sun.star.comp.Draw.PresenterPaneBorderManager"); +} + + + + +Sequence PresenterPaneBorderManager::getSupportedServiceNames_static (void) +{ + static const ::rtl::OUString sServiceName( + ::rtl::OUString::createFromAscii("com.sun.star.drawing.PresenterPaneBorderManager")); + return Sequence(&sServiceName, 1); +} + + + + +Reference PresenterPaneBorderManager::Create (const Reference& rxContext) + SAL_THROW((css::uno::Exception)) +{ + return Reference(static_cast(new PresenterPaneBorderManager(rxContext))); +} + + + + +//===== PresenterPaneBorderManager ============================================ + +PresenterPaneBorderManager::PresenterPaneBorderManager ( + const Reference& rxContext) + : PresenterPaneBorderManagerInterfaceBase(m_aMutex), + mxComponentContext(rxContext), + mxPresenterHelper(), + maWindowList(), + mnPointerType(), + maDragAnchor(), + meDragType(Outside), + mxOuterDragWindow(), + mxInnerDragWindow(), + mxPointer() +{ + Reference xFactory (rxContext->getServiceManager()); + if (xFactory.is()) + { + mxPointer = Reference( + xFactory->createInstanceWithContext( + OUString::createFromAscii("com.sun.star.awt.Pointer"), + rxContext), + UNO_QUERY_THROW); + + mxPresenterHelper = Reference( + xFactory->createInstanceWithContext( + OUString::createFromAscii("com.sun.star.comp.Draw.PresenterHelper"), + rxContext), + UNO_QUERY_THROW); + } +} + + + + +PresenterPaneBorderManager::~PresenterPaneBorderManager (void) +{ +} + + + + +void PresenterPaneBorderManager::disposing (void) +{ + WindowList::const_iterator iDescriptor; + for (iDescriptor=maWindowList.begin(); iDescriptor!=maWindowList.end(); ++iDescriptor) + { + iDescriptor->first->removeMouseListener(this); + iDescriptor->first->removeMouseMotionListener(this); + } + maWindowList.clear(); +} + + + + +namespace { +const static sal_Int32 mnOutside = 0; +const static sal_Int32 mnLeft = 0x01; +const static sal_Int32 mnHorizontalCenter = 0x02; +const static sal_Int32 mnRight = 0x04; +const static sal_Int32 mnTop = 0x10; +const static sal_Int32 mnVerticalCenter = 0x20; +const static sal_Int32 mnBottom = 0x40; +} + +PresenterPaneBorderManager::BorderElement + PresenterPaneBorderManager::ClassifyBorderElementUnderMouse ( + const Reference& rxOuterWindow, + const Reference& rxInnerWindow, + const awt::Point aPosition) const +{ + OSL_ASSERT(rxOuterWindow.is()); + OSL_ASSERT(rxInnerWindow.is()); + + awt::Rectangle aOuterBox (rxOuterWindow->getPosSize()); + const awt::Rectangle aInnerBox (rxInnerWindow->getPosSize()); + + // Coordinates of the pointer position are given in the window + // coordinate system. Therefore the upper left corner of the outer box + // is the origin. + aOuterBox.X = 0; + aOuterBox.Y = 0; + + sal_Int32 nCode = 0; + + // Add horizontal classification to nCode. + if (aPosition.X < aInnerBox.X) + if (aPosition.X < aOuterBox.X) + nCode = mnOutside; + else + nCode = mnLeft; + else if (aPosition.X >= aInnerBox.X+aInnerBox.Width) + if (aPosition.X >= aOuterBox.X+aOuterBox.Width) + nCode = mnOutside; + else + nCode = mnRight; + else + nCode = mnHorizontalCenter; + + // Add vertical classification to nCode. + if (aPosition.Y < aInnerBox.Y) + if (aPosition.Y < aOuterBox.Y) + nCode |= mnOutside; + else + nCode |= mnTop; + else if (aPosition.Y >= aInnerBox.Y+aInnerBox.Height) + if (aPosition.Y >= aOuterBox.Y+aOuterBox.Height) + nCode |= mnOutside; + else + nCode |= mnBottom; + else + nCode |= mnVerticalCenter; + + // Translate bits in nCode into BorderElement value. + switch (nCode) + { + case mnOutside | mnOutside: + case mnOutside | mnLeft: + case mnOutside | mnRight: + case mnOutside | mnHorizontalCenter: + case mnTop | mnOutside: + case mnBottom | mnOutside: + case mnVerticalCenter | mnOutside: + default: + return Outside; + + case mnVerticalCenter | mnHorizontalCenter: + return Content; + + case mnTop | mnLeft: + return TopLeft; + + case mnTop | mnRight: + return TopRight; + + case mnTop | mnHorizontalCenter: + return Top; + + case mnBottom | mnLeft: + return BottomLeft; + + case mnBottom | mnRight: + return BottomRight; + + case mnBottom | mnHorizontalCenter: + return Bottom; + + case mnVerticalCenter | mnLeft: + return Left; + + case mnVerticalCenter | mnRight: + return Right; + } +} + + + + +//----- XInitialization ------------------------------------------------------- + +void SAL_CALL PresenterPaneBorderManager::initialize (const Sequence& rArguments) + throw (Exception, RuntimeException) +{ + ThrowIfDisposed(); + + if (rArguments.getLength()%2 == 1 && mxComponentContext.is()) + { + try + { + mxParentWindow = Reference(rArguments[0], UNO_QUERY_THROW); + + // Get the outer and inner windows from the argument list and + // build a window list of it. + for (sal_Int32 nIndex=1; nIndex xOuterWindow (rArguments[nIndex], UNO_QUERY_THROW); + Reference xInnerWindow (rArguments[nIndex+1], UNO_QUERY_THROW); + + maWindowList.push_back(WindowDescriptor(xOuterWindow,xInnerWindow)); + + xOuterWindow->addMouseListener(this); + xOuterWindow->addMouseMotionListener(this); + } + } + catch (RuntimeException&) + { + PresenterPaneBorderManager::disposing(); + throw; + } + } + else + { + throw RuntimeException( + OUString::createFromAscii("PresenterPane: invalid number of arguments"), + static_cast(this)); + } +} + + + + +//----- XMouseListener -------------------------------------------------------- + +void SAL_CALL PresenterPaneBorderManager::mousePressed (const css::awt::MouseEvent& rEvent) + throw (css::uno::RuntimeException) +{ + ThrowIfDisposed(); + ::osl::MutexGuard aGuard (::osl::Mutex::getGlobalMutex()); + + // Find window descriptor of the window that has been clicked. + WindowList::const_iterator iDescriptor; + for (iDescriptor=maWindowList.begin(); iDescriptor!=maWindowList.end(); ++iDescriptor) + if (iDescriptor->first == rEvent.Source) + break; + + if (iDescriptor != maWindowList.end()) + { + // Prepare dragging. + mxOuterDragWindow = iDescriptor->first; + mxInnerDragWindow = iDescriptor->second; + OSL_ASSERT(mxOuterDragWindow.is() && mxInnerDragWindow.is()); + const awt::Rectangle aOuterBox (mxOuterDragWindow->getPosSize()); + maDragAnchor.X = rEvent.X + aOuterBox.X; + maDragAnchor.Y = rEvent.Y + aOuterBox.Y; + meDragType = ClassifyBorderElementUnderMouse( + mxOuterDragWindow, + mxInnerDragWindow, + awt::Point(rEvent.X, rEvent.Y)); + } +} + + + + +void SAL_CALL PresenterPaneBorderManager::mouseReleased (const css::awt::MouseEvent& rEvent) + throw (css::uno::RuntimeException) +{ + (void)rEvent; + ThrowIfDisposed(); + ::osl::MutexGuard aGuard (::osl::Mutex::getGlobalMutex()); + + ReleaseMouse(mxOuterDragWindow); + meDragType = PresenterPaneBorderManager::Outside; + mxOuterDragWindow = NULL; + mxInnerDragWindow = NULL; +} + + + + +void SAL_CALL PresenterPaneBorderManager::mouseEntered (const css::awt::MouseEvent& rEvent) + throw (css::uno::RuntimeException) +{ + (void)rEvent; +} + + + + +void SAL_CALL PresenterPaneBorderManager::mouseExited (const css::awt::MouseEvent& rEvent) + throw (css::uno::RuntimeException) +{ + (void)rEvent; + ThrowIfDisposed(); + ::osl::MutexGuard aGuard (::osl::Mutex::getGlobalMutex()); + + ReleaseMouse(mxOuterDragWindow); + meDragType = PresenterPaneBorderManager::Outside; + mxOuterDragWindow = NULL; + mxInnerDragWindow = NULL; +} + + + + +//----- XMouseMotionListener -------------------------------------------------- + +void SAL_CALL PresenterPaneBorderManager::mouseMoved (const css::awt::MouseEvent& rEvent) + throw (css::uno::RuntimeException) +{ + ThrowIfDisposed(); + ::osl::MutexGuard aGuard (::osl::Mutex::getGlobalMutex()); + + WindowList::const_iterator iDescriptor; + for (iDescriptor=maWindowList.begin(); iDescriptor!=maWindowList.end(); ++iDescriptor) + if (iDescriptor->first == rEvent.Source) + break; + if (iDescriptor != maWindowList.end()) + { + // Choose pointer shape according to position in the window border. + switch (ClassifyBorderElementUnderMouse( + iDescriptor->first, + iDescriptor->second, + awt::Point(rEvent.X,rEvent.Y))) + { + case PresenterPaneBorderManager::Top: + mnPointerType = awt::SystemPointer::MOVE; + break; + case PresenterPaneBorderManager::TopLeft: + mnPointerType = awt::SystemPointer::WINDOW_NWSIZE; + break; + case PresenterPaneBorderManager::TopRight: + mnPointerType = awt::SystemPointer::WINDOW_NESIZE; + break; + case PresenterPaneBorderManager::Left: + mnPointerType = awt::SystemPointer::WINDOW_WSIZE; + break; + case PresenterPaneBorderManager::Right: + mnPointerType = awt::SystemPointer::WINDOW_ESIZE; + break; + case PresenterPaneBorderManager::BottomLeft: + mnPointerType = awt::SystemPointer::WINDOW_SWSIZE; + break; + case PresenterPaneBorderManager::BottomRight: + mnPointerType = awt::SystemPointer::WINDOW_SESIZE; + break; + case PresenterPaneBorderManager::Bottom: + mnPointerType = awt::SystemPointer::WINDOW_SSIZE; + break; + + case PresenterPaneBorderManager::Content: + case PresenterPaneBorderManager::Outside: + default: + mnPointerType = awt::SystemPointer::ARROW; + break; + } + + // Make the pointer shape visible. + Reference xPeer (iDescriptor->first, UNO_QUERY); + if (xPeer.is()) + { + if (mxPointer.is()) + mxPointer->setType(mnPointerType); + xPeer->setPointer(mxPointer); + } + } +} + + + + +void SAL_CALL PresenterPaneBorderManager::mouseDragged (const css::awt::MouseEvent& rEvent) + throw (css::uno::RuntimeException) +{ + ThrowIfDisposed(); + ::osl::MutexGuard aGuard (::osl::Mutex::getGlobalMutex()); + + if ( ! mxOuterDragWindow.is()) + return; + + CaptureMouse(mxOuterDragWindow); + + const awt::Rectangle aOldBox (mxOuterDragWindow->getPosSize()); + const sal_Int32 nX = rEvent.X + aOldBox.X; + const sal_Int32 nY = rEvent.Y + aOldBox.Y; + const sal_Int32 nDiffX = nX - maDragAnchor.X; + const sal_Int32 nDiffY = nY - maDragAnchor.Y; + maDragAnchor.X = nX; + maDragAnchor.Y = nY; + + const sal_Int32 nOldRight = aOldBox.X + aOldBox.Width; + const sal_Int32 nOldBottom = aOldBox.Y + aOldBox.Height; + + awt::Rectangle aBox (aOldBox); + sal_Int32 nRight = aBox.X + aBox.Width; + sal_Int32 nBottom = aBox.Y + aBox.Height; + + // Update position and/or size according to initial pointer position + // inside the window border. + switch (meDragType) + { + case PresenterPaneBorderManager::Top: + aBox.X += nDiffX; aBox.Y += nDiffY; + nRight += nDiffX; nBottom += nDiffY; + break; + case PresenterPaneBorderManager::TopLeft: + aBox.X += nDiffX; aBox.Y += nDiffY; + break; + case PresenterPaneBorderManager::TopRight: + nRight += nDiffX; aBox.Y += nDiffY; + break; + case PresenterPaneBorderManager::Left: + aBox.X += nDiffX; + break; + case PresenterPaneBorderManager::Right: + nRight += nDiffX; + break; + case PresenterPaneBorderManager::BottomLeft: + aBox.X += nDiffX; nBottom += nDiffY; + break; + case PresenterPaneBorderManager::BottomRight: + nRight += nDiffX; nBottom += nDiffY; + break; + case PresenterPaneBorderManager::Bottom: + nBottom += nDiffY; + break; + default: break; + } + + aBox.Width = nRight - aBox.X; + aBox.Height = nBottom - aBox.Y; + if (aBox.Width > 20 + && aBox.Height > 20) + { + // Set position and/or size of the border window to the new values. + sal_Int16 nFlags (0); + if (aBox.X != aOldBox.X) + nFlags |= awt::PosSize::X; + if (aBox.Y != aOldBox.Y) + nFlags |= awt::PosSize::Y; + if (aBox.Width != aOldBox.Width) + nFlags |= awt::PosSize::WIDTH; + if (aBox.Height != aOldBox.Height) + nFlags |= awt::PosSize::HEIGHT; + mxOuterDragWindow->setPosSize(aBox.X, aBox.Y, aBox.Width, aBox.Height, nFlags); + + // Invalidate that is or was covered by the border window before and + // after the move/resize. + Reference xPeer (mxParentWindow, UNO_QUERY); + if (xPeer.is()) + { + const sal_Int32 nLeft = ::std::min(aOldBox.X,aBox.X); + const sal_Int32 nTop = ::std::min(aOldBox.Y,aBox.Y); + const sal_Int32 nWidth = ::std::max(nOldRight,nRight) - nLeft; + const sal_Int32 nHeight = ::std::max(nOldBottom,nBottom) - nTop; + xPeer->invalidateRect( + ::awt::Rectangle(nLeft,nTop,nWidth-1,nHeight-1), + awt::InvalidateStyle::TRANSPARENT); + } + } +} + + + + +//----- lang::XEventListener -------------------------------------------------- + +void SAL_CALL PresenterPaneBorderManager::disposing (const lang::EventObject& rEvent) + throw (RuntimeException) +{ + WindowList::iterator iDescriptor; + for (iDescriptor=maWindowList.begin(); iDescriptor!=maWindowList.end(); ++iDescriptor) + if (iDescriptor->first == rEvent.Source) + { + maWindowList.erase(iDescriptor); + break; + } +} + + + + +//----------------------------------------------------------------------------- + + +void PresenterPaneBorderManager::CaptureMouse (const Reference& rxWindow) +{ + if (mxPresenterHelper.is()) + mxPresenterHelper->captureMouse(rxWindow); +} + + + + +void PresenterPaneBorderManager::ReleaseMouse (const Reference& rxWindow) +{ + if (mxPresenterHelper.is()) + mxPresenterHelper->releaseMouse(rxWindow); +} + + + + +void PresenterPaneBorderManager::ThrowIfDisposed (void) + throw (::com::sun::star::lang::DisposedException) +{ + if (rBHelper.bDisposed || rBHelper.bInDispose) + { + throw lang::DisposedException ( + ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM( + "PresenterPaneBorderManager object has already been disposed")), + static_cast(this)); + } +} + + + + +} } // end of namespace ::sd::presenter -- cgit