| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_sdext.hxx" |
| |
| #include "PresenterScrollBar.hxx" |
| #include "PresenterBitmapContainer.hxx" |
| #include "PresenterCanvasHelper.hxx" |
| #include "PresenterGeometryHelper.hxx" |
| #include "PresenterPaintManager.hxx" |
| #include "PresenterTimer.hxx" |
| #include "PresenterUIPainter.hxx" |
| #include <com/sun/star/awt/PosSize.hpp> |
| #include <com/sun/star/awt/WindowAttribute.hpp> |
| #include <com/sun/star/awt/XWindowPeer.hpp> |
| #include <com/sun/star/awt/XToolkit.hpp> |
| #include <com/sun/star/rendering/CompositeOperation.hpp> |
| #include <com/sun/star/rendering/TexturingMode.hpp> |
| #include <com/sun/star/rendering/XPolyPolygon2D.hpp> |
| #include <boost/bind.hpp> |
| #include <boost/enable_shared_from_this.hpp> |
| #include <boost/weak_ptr.hpp> |
| #include <math.h> |
| |
| using namespace ::com::sun::star; |
| using namespace ::com::sun::star::uno; |
| using ::rtl::OUString; |
| |
| #define A2S(pString) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(pString))) |
| |
| const static double gnScrollBarGap (10); |
| |
| namespace sdext { namespace presenter { |
| |
| //===== PresenterScrollBar::MousePressRepeater ================================ |
| |
| class PresenterScrollBar::MousePressRepeater |
| : public ::boost::enable_shared_from_this<MousePressRepeater> |
| { |
| public: |
| MousePressRepeater (const ::rtl::Reference<PresenterScrollBar>& rpScrollBar); |
| void Dispose (void); |
| void Start (const PresenterScrollBar::Area& reArea); |
| void Stop (void); |
| void SetMouseArea (const PresenterScrollBar::Area& reArea); |
| |
| private: |
| void Callback (const TimeValue& rCurrentTime); |
| void Execute (void); |
| |
| sal_Int32 mnMousePressRepeaterTaskId; |
| ::rtl::Reference<PresenterScrollBar> mpScrollBar; |
| PresenterScrollBar::Area meMouseArea; |
| }; |
| |
| |
| |
| |
| //===== PresenterScrollBar ==================================================== |
| |
| boost::weak_ptr<PresenterBitmapContainer> PresenterScrollBar::mpSharedBitmaps; |
| |
| PresenterScrollBar::PresenterScrollBar ( |
| const Reference<XComponentContext>& rxComponentContext, |
| const Reference<awt::XWindow>& rxParentWindow, |
| const ::boost::shared_ptr<PresenterPaintManager>& rpPaintManager, |
| const ::boost::function<void(double)>& rThumbMotionListener) |
| : PresenterScrollBarInterfaceBase(m_aMutex), |
| mxComponentContext(rxComponentContext), |
| mxParentWindow(rxParentWindow), |
| mxWindow(), |
| mxCanvas(), |
| mxPresenterHelper(), |
| mpPaintManager(rpPaintManager), |
| mnThumbPosition(0), |
| mnTotalSize(0), |
| mnThumbSize(0), |
| mnLineHeight(10), |
| maDragAnchor(-1,-1), |
| maThumbMotionListener(rThumbMotionListener), |
| meButtonDownArea(None), |
| meMouseMoveArea(None), |
| mbIsNotificationActive(false), |
| mpBitmaps(), |
| mpPrevButtonDescriptor(), |
| mpNextButtonDescriptor(), |
| mpPagerStartDescriptor(), |
| mpPagerCenterDescriptor(), |
| mpPagerEndDescriptor(), |
| mpThumbStartDescriptor(), |
| mpThumbCenterDescriptor(), |
| mpThumbEndDescriptor(), |
| mpMousePressRepeater(new MousePressRepeater(this)), |
| mpBackgroundBitmap(), |
| mpCanvasHelper(new PresenterCanvasHelper()) |
| { |
| try |
| { |
| Reference<lang::XMultiComponentFactory> xFactory (rxComponentContext->getServiceManager()); |
| if ( ! xFactory.is()) |
| throw RuntimeException(); |
| |
| mxPresenterHelper = Reference<drawing::XPresenterHelper>( |
| xFactory->createInstanceWithContext( |
| OUString::createFromAscii("com.sun.star.comp.Draw.PresenterHelper"), |
| rxComponentContext), |
| UNO_QUERY_THROW); |
| |
| if (mxPresenterHelper.is()) |
| mxWindow = mxPresenterHelper->createWindow(rxParentWindow, |
| sal_False, |
| sal_False, |
| sal_False, |
| sal_False); |
| |
| // Make the background transparent. The slide show paints its own background. |
| Reference<awt::XWindowPeer> xPeer (mxWindow, UNO_QUERY_THROW); |
| if (xPeer.is()) |
| { |
| xPeer->setBackground(0xff000000); |
| } |
| |
| mxWindow->setVisible(sal_True); |
| mxWindow->addWindowListener(this); |
| mxWindow->addPaintListener(this); |
| mxWindow->addMouseListener(this); |
| mxWindow->addMouseMotionListener(this); |
| } |
| catch (RuntimeException&) |
| { |
| } |
| } |
| |
| |
| |
| |
| PresenterScrollBar::~PresenterScrollBar (void) |
| { |
| } |
| |
| |
| |
| |
| void SAL_CALL PresenterScrollBar::disposing (void) |
| { |
| mpMousePressRepeater->Dispose(); |
| |
| if (mxWindow.is()) |
| { |
| mxWindow->removeWindowListener(this); |
| mxWindow->removePaintListener(this); |
| mxWindow->removeMouseListener(this); |
| mxWindow->removeMouseMotionListener(this); |
| |
| Reference<lang::XComponent> xComponent (mxWindow, UNO_QUERY); |
| mxWindow = NULL; |
| if (xComponent.is()) |
| xComponent->dispose(); |
| } |
| |
| mpBitmaps.reset(); |
| } |
| |
| |
| |
| |
| void PresenterScrollBar::SetVisible (const bool bIsVisible) |
| { |
| if (mxWindow.is()) |
| mxWindow->setVisible(bIsVisible); |
| } |
| |
| |
| |
| |
| void PresenterScrollBar::SetPosSize (const css::geometry::RealRectangle2D& rBox) |
| { |
| if (mxWindow.is()) |
| { |
| mxWindow->setPosSize( |
| sal_Int32(floor(rBox.X1)), |
| sal_Int32(ceil(rBox.Y1)), |
| sal_Int32(ceil(rBox.X2-rBox.X1)), |
| sal_Int32(floor(rBox.Y2-rBox.Y1)), |
| awt::PosSize::POSSIZE); |
| UpdateBorders(); |
| } |
| } |
| |
| |
| |
| |
| void PresenterScrollBar::SetThumbPosition ( |
| double nPosition, |
| const bool bAsynchronousUpdate) |
| { |
| SetThumbPosition(nPosition, bAsynchronousUpdate, true, true); |
| } |
| |
| |
| |
| |
| void PresenterScrollBar::SetThumbPosition ( |
| double nPosition, |
| const bool bAsynchronousUpdate, |
| const bool bValidate, |
| const bool bNotify) |
| { |
| if (bValidate) |
| nPosition = ValidateThumbPosition(nPosition); |
| |
| if (nPosition != mnThumbPosition && ! mbIsNotificationActive) |
| { |
| mnThumbPosition = nPosition; |
| |
| UpdateBorders(); |
| Repaint(GetRectangle(Total), bAsynchronousUpdate); |
| if (bNotify) |
| NotifyThumbPositionChange(); |
| } |
| } |
| |
| |
| |
| |
| double PresenterScrollBar::GetThumbPosition (void) const |
| { |
| return mnThumbPosition; |
| } |
| |
| |
| |
| |
| void PresenterScrollBar::SetTotalSize (const double nTotalSize) |
| { |
| if (mnTotalSize != nTotalSize) |
| { |
| mnTotalSize = nTotalSize + 1; |
| UpdateBorders(); |
| Repaint(GetRectangle(Total), false); |
| } |
| } |
| |
| |
| |
| |
| double PresenterScrollBar::GetTotalSize (void) const |
| { |
| return mnTotalSize; |
| } |
| |
| |
| |
| |
| void PresenterScrollBar::SetThumbSize (const double nThumbSize) |
| { |
| OSL_ASSERT(nThumbSize>=0); |
| if (mnThumbSize != nThumbSize) |
| { |
| mnThumbSize = nThumbSize; |
| UpdateBorders(); |
| Repaint(GetRectangle(Total), false); |
| } |
| } |
| |
| |
| |
| |
| double PresenterScrollBar::GetThumbSize (void) const |
| { |
| return mnThumbSize; |
| } |
| |
| |
| |
| |
| void PresenterScrollBar::SetLineHeight (const double nLineHeight) |
| { |
| mnLineHeight = nLineHeight; |
| } |
| |
| |
| |
| |
| double PresenterScrollBar::GetLineHeight (void) const |
| { |
| return mnLineHeight; |
| } |
| |
| |
| |
| |
| void PresenterScrollBar::SetCanvas (const Reference<css::rendering::XCanvas>& rxCanvas) |
| { |
| if (mxCanvas != rxCanvas) |
| { |
| mxCanvas = rxCanvas; |
| if (mxCanvas.is()) |
| { |
| if (mpBitmaps.get()==NULL) |
| { |
| if (mpSharedBitmaps.expired()) |
| { |
| try |
| { |
| mpBitmaps.reset(new PresenterBitmapContainer( |
| OUString::createFromAscii("PresenterScreenSettings/ScrollBar/Bitmaps"), |
| ::boost::shared_ptr<PresenterBitmapContainer>(), |
| mxComponentContext, |
| mxCanvas)); |
| mpSharedBitmaps = mpBitmaps; |
| } |
| catch(Exception&) |
| { |
| OSL_ASSERT(false); |
| } |
| } |
| else |
| mpBitmaps = ::boost::shared_ptr<PresenterBitmapContainer>(mpSharedBitmaps); |
| UpdateBitmaps(); |
| UpdateBorders(); |
| } |
| |
| Repaint(GetRectangle(Total), false); |
| } |
| } |
| } |
| |
| |
| |
| |
| void PresenterScrollBar::SetBackground (const SharedBitmapDescriptor& rpBackgroundBitmap) |
| { |
| mpBackgroundBitmap = rpBackgroundBitmap; |
| } |
| |
| |
| |
| void PresenterScrollBar::CheckValues (void) |
| { |
| mnThumbPosition = ValidateThumbPosition(mnThumbPosition); |
| } |
| |
| |
| |
| |
| double PresenterScrollBar::ValidateThumbPosition (double nPosition) |
| { |
| if (nPosition + mnThumbSize > mnTotalSize) |
| nPosition = mnTotalSize - mnThumbSize; |
| if (nPosition < 0) |
| nPosition = 0; |
| return nPosition; |
| } |
| |
| |
| |
| |
| void PresenterScrollBar::Paint ( |
| const awt::Rectangle& rUpdateBox, |
| const bool bNoClip) |
| { |
| if ( ! mxCanvas.is() || ! mxWindow.is()) |
| { |
| OSL_ASSERT(mxCanvas.is()); |
| OSL_ASSERT(mxWindow.is()); |
| return; |
| } |
| |
| if ( ! bNoClip) |
| { |
| if (PresenterGeometryHelper::AreRectanglesDisjoint (rUpdateBox, mxWindow->getPosSize())) |
| return; |
| } |
| |
| PaintBackground(rUpdateBox); |
| PaintComposite(rUpdateBox, PagerUp, |
| mpPagerStartDescriptor, mpPagerCenterDescriptor, SharedBitmapDescriptor()); |
| PaintComposite(rUpdateBox, PagerDown, |
| SharedBitmapDescriptor(), mpPagerCenterDescriptor, mpPagerEndDescriptor); |
| PaintComposite(rUpdateBox, Thumb, |
| mpThumbStartDescriptor, mpThumbCenterDescriptor, mpThumbEndDescriptor); |
| PaintBitmap(rUpdateBox, PrevButton, mpPrevButtonDescriptor); |
| PaintBitmap(rUpdateBox, NextButton, mpNextButtonDescriptor); |
| |
| Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxCanvas, UNO_QUERY); |
| if (xSpriteCanvas.is()) |
| xSpriteCanvas->updateScreen(sal_False); |
| } |
| |
| |
| |
| |
| |
| |
| //----- XWindowListener ------------------------------------------------------- |
| |
| void SAL_CALL PresenterScrollBar::windowResized (const css::awt::WindowEvent& rEvent) |
| throw (css::uno::RuntimeException) |
| { |
| (void)rEvent; |
| } |
| |
| |
| |
| |
| |
| void SAL_CALL PresenterScrollBar::windowMoved (const css::awt::WindowEvent& rEvent) |
| throw (css::uno::RuntimeException) |
| { |
| (void)rEvent; |
| } |
| |
| |
| |
| |
| void SAL_CALL PresenterScrollBar::windowShown (const css::lang::EventObject& rEvent) |
| throw (css::uno::RuntimeException) |
| { |
| (void)rEvent; |
| } |
| |
| |
| |
| |
| void SAL_CALL PresenterScrollBar::windowHidden (const css::lang::EventObject& rEvent) |
| throw (css::uno::RuntimeException) |
| { |
| (void)rEvent; |
| } |
| |
| |
| |
| |
| //----- XPaintListener -------------------------------------------------------- |
| |
| void SAL_CALL PresenterScrollBar::windowPaint (const css::awt::PaintEvent& rEvent) |
| throw (css::uno::RuntimeException) |
| { |
| if (mxWindow.is()) |
| { |
| awt::Rectangle aRepaintBox (rEvent.UpdateRect); |
| const awt::Rectangle aWindowBox (mxWindow->getPosSize()); |
| aRepaintBox.X += aWindowBox.X; |
| aRepaintBox.Y += aWindowBox.Y; |
| Paint(aRepaintBox); |
| |
| Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxCanvas, UNO_QUERY); |
| if (xSpriteCanvas.is()) |
| xSpriteCanvas->updateScreen(sal_False); |
| } |
| } |
| |
| |
| |
| |
| //----- XMouseListener -------------------------------------------------------- |
| |
| void SAL_CALL PresenterScrollBar::mousePressed (const css::awt::MouseEvent& rEvent) |
| throw(css::uno::RuntimeException) |
| { |
| maDragAnchor.X = rEvent.X; |
| maDragAnchor.Y = rEvent.Y; |
| meButtonDownArea = GetArea(rEvent.X, rEvent.Y); |
| |
| mpMousePressRepeater->Start(meButtonDownArea); |
| } |
| |
| |
| |
| |
| void SAL_CALL PresenterScrollBar::mouseReleased (const css::awt::MouseEvent& rEvent) |
| throw(css::uno::RuntimeException) |
| { |
| (void)rEvent; |
| |
| mpMousePressRepeater->Stop(); |
| |
| if (mxPresenterHelper.is()) |
| mxPresenterHelper->releaseMouse(mxWindow); |
| } |
| |
| |
| |
| |
| void SAL_CALL PresenterScrollBar::mouseEntered (const css::awt::MouseEvent& rEvent) |
| throw(css::uno::RuntimeException) |
| { |
| (void)rEvent; |
| } |
| |
| |
| |
| |
| void SAL_CALL PresenterScrollBar::mouseExited (const css::awt::MouseEvent& rEvent) |
| throw(css::uno::RuntimeException) |
| { |
| (void)rEvent; |
| if (meMouseMoveArea != None) |
| { |
| const Area eOldMouseMoveArea (meMouseMoveArea); |
| meMouseMoveArea = None; |
| Repaint(GetRectangle(eOldMouseMoveArea), true); |
| } |
| meButtonDownArea = None; |
| meMouseMoveArea = None; |
| |
| mpMousePressRepeater->Stop(); |
| } |
| |
| |
| |
| |
| |
| //----- XMouseMotionListener -------------------------------------------------- |
| |
| void SAL_CALL PresenterScrollBar::mouseMoved (const css::awt::MouseEvent& rEvent) |
| throw (css::uno::RuntimeException) |
| { |
| const Area eArea (GetArea(rEvent.X, rEvent.Y)); |
| if (eArea != meMouseMoveArea) |
| { |
| const Area eOldMouseMoveArea (meMouseMoveArea); |
| meMouseMoveArea = eArea; |
| if (eOldMouseMoveArea != None) |
| Repaint(GetRectangle(eOldMouseMoveArea), meMouseMoveArea==None); |
| if (meMouseMoveArea != None) |
| Repaint(GetRectangle(meMouseMoveArea), true); |
| } |
| mpMousePressRepeater->SetMouseArea(eArea); |
| } |
| |
| |
| |
| |
| void SAL_CALL PresenterScrollBar::mouseDragged (const css::awt::MouseEvent& rEvent) |
| throw (css::uno::RuntimeException) |
| { |
| if (meButtonDownArea != Thumb) |
| return; |
| |
| mpMousePressRepeater->Stop(); |
| |
| if (mxPresenterHelper.is()) |
| mxPresenterHelper->captureMouse(mxWindow); |
| |
| const double nDragDistance (GetDragDistance(rEvent.X,rEvent.Y)); |
| UpdateDragAnchor(nDragDistance); |
| if (nDragDistance != 0) |
| { |
| SetThumbPosition(mnThumbPosition + nDragDistance, false, true, true); |
| } |
| } |
| |
| |
| |
| |
| //----- lang::XEventListener -------------------------------------------------- |
| |
| void SAL_CALL PresenterScrollBar::disposing (const css::lang::EventObject& rEvent) |
| throw (css::uno::RuntimeException) |
| { |
| if (rEvent.Source == mxWindow) |
| mxWindow = NULL; |
| } |
| |
| |
| |
| |
| //----------------------------------------------------------------------------- |
| |
| geometry::RealRectangle2D PresenterScrollBar::GetRectangle (const Area eArea) const |
| { |
| OSL_ASSERT(eArea>=0 && eArea<__AreaCount__); |
| |
| return maBox[eArea]; |
| } |
| |
| |
| |
| |
| void PresenterScrollBar::Repaint ( |
| const geometry::RealRectangle2D aBox, |
| const bool bAsynchronousUpdate) |
| { |
| if (mpPaintManager.get() != NULL) |
| mpPaintManager->Invalidate( |
| mxWindow, |
| PresenterGeometryHelper::ConvertRectangle(aBox), |
| bAsynchronousUpdate); |
| } |
| |
| |
| |
| |
| void PresenterScrollBar::PaintBackground( |
| const css::awt::Rectangle& rUpdateBox) |
| { |
| if (mpBackgroundBitmap.get() == NULL) |
| return; |
| |
| const awt::Rectangle aWindowBox (mxWindow->getPosSize()); |
| mpCanvasHelper->Paint( |
| mpBackgroundBitmap, |
| mxCanvas, |
| rUpdateBox, |
| aWindowBox, |
| awt::Rectangle()); |
| } |
| |
| |
| |
| |
| void PresenterScrollBar::PaintBitmap( |
| const css::awt::Rectangle& rUpdateBox, |
| const Area eArea, |
| const SharedBitmapDescriptor& rpBitmaps) |
| { |
| const geometry::RealRectangle2D aLocalBox (GetRectangle(eArea)); |
| const awt::Rectangle aWindowBox (mxWindow->getPosSize()); |
| geometry::RealRectangle2D aBox (aLocalBox); |
| aBox.X1 += aWindowBox.X; |
| aBox.Y1 += aWindowBox.Y; |
| aBox.X2 += aWindowBox.X; |
| aBox.Y2 += aWindowBox.Y; |
| |
| Reference<rendering::XBitmap> xBitmap (GetBitmap(eArea,rpBitmaps)); |
| |
| if (xBitmap.is()) |
| { |
| Reference<rendering::XPolyPolygon2D> xClipPolygon ( |
| PresenterGeometryHelper::CreatePolygon( |
| PresenterGeometryHelper::Intersection(rUpdateBox, |
| PresenterGeometryHelper::ConvertRectangle(aBox)), |
| mxCanvas->getDevice())); |
| |
| const rendering::ViewState aViewState ( |
| geometry::AffineMatrix2D(1,0,0, 0,1,0), |
| xClipPolygon); |
| |
| const geometry::IntegerSize2D aBitmapSize (xBitmap->getSize()); |
| rendering::RenderState aRenderState ( |
| geometry::AffineMatrix2D( |
| 1,0,aBox.X1 + (aBox.X2-aBox.X1 - aBitmapSize.Width)/2, |
| 0,1,aBox.Y1 + (aBox.Y2-aBox.Y1 - aBitmapSize.Height)/2), |
| NULL, |
| Sequence<double>(4), |
| rendering::CompositeOperation::SOURCE); |
| |
| mxCanvas->drawBitmap( |
| xBitmap, |
| aViewState, |
| aRenderState); |
| } |
| } |
| |
| |
| |
| |
| void PresenterScrollBar::NotifyThumbPositionChange (void) |
| { |
| if ( ! mbIsNotificationActive) |
| { |
| mbIsNotificationActive = true; |
| |
| try |
| { |
| maThumbMotionListener(mnThumbPosition); |
| } |
| catch (Exception&) |
| { |
| } |
| |
| mbIsNotificationActive = false; |
| } |
| } |
| |
| |
| |
| |
| PresenterScrollBar::Area PresenterScrollBar::GetArea (const double nX, const double nY) const |
| { |
| const geometry::RealPoint2D aPoint(nX, nY); |
| |
| if (PresenterGeometryHelper::IsInside(GetRectangle(Pager), aPoint)) |
| { |
| if (PresenterGeometryHelper::IsInside(GetRectangle(Thumb), aPoint)) |
| return Thumb; |
| else if (PresenterGeometryHelper::IsInside(GetRectangle(PagerUp), aPoint)) |
| return PagerUp; |
| else if (PresenterGeometryHelper::IsInside(GetRectangle(PagerDown), aPoint)) |
| return PagerDown; |
| } |
| else if (PresenterGeometryHelper::IsInside(GetRectangle(PrevButton), aPoint)) |
| return PrevButton; |
| else if (PresenterGeometryHelper::IsInside(GetRectangle(NextButton), aPoint)) |
| return NextButton; |
| |
| return None; |
| } |
| |
| |
| |
| |
| void PresenterScrollBar::UpdateWidthOrHeight ( |
| sal_Int32& rSize, |
| const SharedBitmapDescriptor& rpDescriptor) |
| { |
| if (rpDescriptor.get() != NULL) |
| { |
| Reference<rendering::XBitmap> xBitmap (rpDescriptor->GetNormalBitmap()); |
| if (xBitmap.is()) |
| { |
| const geometry::IntegerSize2D aBitmapSize (xBitmap->getSize()); |
| const sal_Int32 nBitmapSize = (sal_Int32)GetMinor(aBitmapSize.Width, aBitmapSize.Height); |
| if (nBitmapSize > rSize) |
| rSize = nBitmapSize; |
| } |
| } |
| } |
| |
| |
| |
| |
| css::uno::Reference<css::rendering::XBitmap> PresenterScrollBar::GetBitmap ( |
| const Area eArea, |
| const SharedBitmapDescriptor& rpBitmaps) const |
| { |
| if (rpBitmaps.get() == NULL) |
| return NULL; |
| else |
| return rpBitmaps->GetBitmap(GetBitmapMode(eArea)); |
| } |
| |
| |
| |
| |
| PresenterBitmapContainer::BitmapDescriptor::Mode PresenterScrollBar::GetBitmapMode ( |
| const Area eArea) const |
| { |
| if (IsDisabled(eArea)) |
| return PresenterBitmapContainer::BitmapDescriptor::Disabled; |
| else if (eArea == meMouseMoveArea) |
| return PresenterBitmapContainer::BitmapDescriptor::MouseOver; |
| else |
| return PresenterBitmapContainer::BitmapDescriptor::Normal; |
| } |
| |
| |
| |
| |
| bool PresenterScrollBar::IsDisabled (const Area eArea) const |
| { |
| OSL_ASSERT(eArea>=0 && eArea<__AreaCount__); |
| |
| return ! maEnabledState[eArea]; |
| } |
| |
| |
| |
| |
| //===== PresenterVerticalScrollBar ============================================ |
| |
| PresenterVerticalScrollBar::PresenterVerticalScrollBar ( |
| const Reference<XComponentContext>& rxComponentContext, |
| const Reference<awt::XWindow>& rxParentWindow, |
| const ::boost::shared_ptr<PresenterPaintManager>& rpPaintManager, |
| const ::boost::function<void(double)>& rThumbMotionListener) |
| : PresenterScrollBar(rxComponentContext, rxParentWindow, rpPaintManager, rThumbMotionListener), |
| mnScrollBarWidth(0) |
| { |
| } |
| |
| |
| |
| |
| PresenterVerticalScrollBar::~PresenterVerticalScrollBar (void) |
| { |
| } |
| |
| |
| |
| |
| double PresenterVerticalScrollBar::GetDragDistance (const sal_Int32 nX, const sal_Int32 nY) const |
| { |
| (void)nX; |
| const double nDistance (nY - maDragAnchor.Y); |
| if (nDistance == 0) |
| return 0; |
| else |
| { |
| const awt::Rectangle aWindowBox (mxWindow->getPosSize()); |
| const double nBarWidth (aWindowBox.Width); |
| const double nPagerHeight (aWindowBox.Height - 2*nBarWidth); |
| const double nDragDistance (mnTotalSize / nPagerHeight * nDistance); |
| if (nDragDistance + mnThumbPosition < 0) |
| return -mnThumbPosition; |
| else if (mnThumbPosition + nDragDistance > mnTotalSize-mnThumbSize) |
| return mnTotalSize-mnThumbSize-mnThumbPosition; |
| else |
| return nDragDistance; |
| } |
| } |
| |
| |
| |
| |
| void PresenterVerticalScrollBar::UpdateDragAnchor (const double nDragDistance) |
| { |
| const awt::Rectangle aWindowBox (mxWindow->getPosSize()); |
| const double nBarWidth (aWindowBox.Width); |
| const double nPagerHeight (aWindowBox.Height - 2*nBarWidth); |
| maDragAnchor.Y += nDragDistance * nPagerHeight / mnTotalSize; |
| } |
| |
| |
| |
| |
| sal_Int32 PresenterVerticalScrollBar::GetSize (void) const |
| { |
| return mnScrollBarWidth; |
| } |
| |
| |
| |
| |
| geometry::RealPoint2D PresenterVerticalScrollBar::GetPoint ( |
| const double nMajor, const double nMinor) const |
| { |
| return geometry::RealPoint2D(nMinor, nMajor); |
| } |
| |
| |
| |
| |
| double PresenterVerticalScrollBar::GetMajor (const double nX, const double nY) const |
| { |
| (void)nX; |
| return nY; |
| } |
| |
| |
| |
| |
| double PresenterVerticalScrollBar::GetMinor (const double nX, const double nY) const |
| { |
| (void)nY; |
| return nX; |
| } |
| |
| |
| |
| |
| void PresenterVerticalScrollBar::UpdateBorders (void) |
| { |
| const awt::Rectangle aWindowBox (mxWindow->getPosSize()); |
| double nBottom = aWindowBox.Height; |
| |
| if (mpNextButtonDescriptor.get() != NULL) |
| { |
| Reference<rendering::XBitmap> xBitmap (mpNextButtonDescriptor->GetNormalBitmap()); |
| if (xBitmap.is()) |
| { |
| geometry::IntegerSize2D aSize (xBitmap->getSize()); |
| maBox[NextButton] = geometry::RealRectangle2D( |
| 0, nBottom - aSize.Height, aWindowBox.Width, nBottom); |
| nBottom -= aSize.Height + gnScrollBarGap; |
| } |
| } |
| if (mpPrevButtonDescriptor.get() != NULL) |
| { |
| Reference<rendering::XBitmap> xBitmap (mpPrevButtonDescriptor->GetNormalBitmap()); |
| if (xBitmap.is()) |
| { |
| geometry::IntegerSize2D aSize (xBitmap->getSize()); |
| maBox[PrevButton] = geometry::RealRectangle2D( |
| 0, nBottom - aSize.Height, aWindowBox.Width, nBottom); |
| nBottom -= aSize.Height + gnScrollBarGap; |
| } |
| } |
| const double nPagerHeight (nBottom); |
| maBox[Pager] = geometry::RealRectangle2D( |
| 0,0, aWindowBox.Width, nBottom); |
| if (mnTotalSize < 1) |
| { |
| maBox[Thumb] = maBox[Pager]; |
| |
| // Set up the enabled/disabled states. |
| maEnabledState[PrevButton] = false; |
| maEnabledState[PagerUp] = false; |
| maEnabledState[NextButton] = false; |
| maEnabledState[PagerDown] = false; |
| maEnabledState[Thumb] = false; |
| } |
| else |
| { |
| const double nThumbSize = ::std::min(mnThumbSize,mnTotalSize); |
| const double nThumbPosition = ::std::min(::std::max(0.0,mnThumbPosition), mnTotalSize - nThumbSize); |
| maBox[Thumb] = geometry::RealRectangle2D( |
| 0, nThumbPosition / mnTotalSize * nPagerHeight, |
| aWindowBox.Width, |
| (nThumbPosition+nThumbSize) / mnTotalSize * nPagerHeight); |
| |
| // Set up the enabled/disabled states. |
| maEnabledState[PrevButton] = nThumbPosition>0; |
| maEnabledState[PagerUp] = nThumbPosition>0; |
| maEnabledState[NextButton] = nThumbPosition+nThumbSize < mnTotalSize; |
| maEnabledState[PagerDown] = nThumbPosition+nThumbSize < mnTotalSize; |
| maEnabledState[Thumb] = nThumbSize < mnTotalSize; |
| } |
| maBox[PagerUp] = geometry::RealRectangle2D( |
| maBox[Pager].X1, maBox[Pager].Y1, maBox[Pager].X2, maBox[Thumb].Y1-1); |
| maBox[PagerDown] = geometry::RealRectangle2D( |
| maBox[Pager].X1, maBox[Thumb].Y2+1, maBox[Pager].X2, maBox[Pager].Y2); |
| maBox[Total] = PresenterGeometryHelper::Union( |
| PresenterGeometryHelper::Union(maBox[PrevButton], maBox[NextButton]), |
| maBox[Pager]); |
| } |
| |
| |
| |
| |
| void PresenterVerticalScrollBar::UpdateBitmaps (void) |
| { |
| if (mpBitmaps.get() != NULL) |
| { |
| mpPrevButtonDescriptor = mpBitmaps->GetBitmap(A2S("Up")); |
| mpNextButtonDescriptor = mpBitmaps->GetBitmap(A2S("Down")); |
| mpPagerStartDescriptor = mpBitmaps->GetBitmap(A2S("PagerTop")); |
| mpPagerCenterDescriptor = mpBitmaps->GetBitmap(A2S("PagerVertical")); |
| mpPagerEndDescriptor = mpBitmaps->GetBitmap(A2S("PagerBottom")); |
| mpThumbStartDescriptor = mpBitmaps->GetBitmap(A2S("ThumbTop")); |
| mpThumbCenterDescriptor = mpBitmaps->GetBitmap(A2S("ThumbVertical")); |
| mpThumbEndDescriptor = mpBitmaps->GetBitmap(A2S("ThumbBottom")); |
| |
| mnScrollBarWidth = 0; |
| UpdateWidthOrHeight(mnScrollBarWidth, mpPrevButtonDescriptor); |
| UpdateWidthOrHeight(mnScrollBarWidth, mpNextButtonDescriptor); |
| UpdateWidthOrHeight(mnScrollBarWidth, mpPagerStartDescriptor); |
| UpdateWidthOrHeight(mnScrollBarWidth, mpPagerCenterDescriptor); |
| UpdateWidthOrHeight(mnScrollBarWidth, mpPagerEndDescriptor); |
| UpdateWidthOrHeight(mnScrollBarWidth, mpThumbStartDescriptor); |
| UpdateWidthOrHeight(mnScrollBarWidth, mpThumbCenterDescriptor); |
| UpdateWidthOrHeight(mnScrollBarWidth, mpThumbEndDescriptor); |
| if (mnScrollBarWidth == 0) |
| mnScrollBarWidth = 20; |
| } |
| } |
| |
| |
| |
| |
| void PresenterVerticalScrollBar::PaintComposite( |
| const css::awt::Rectangle& rUpdateBox, |
| const Area eArea, |
| const SharedBitmapDescriptor& rpStartBitmaps, |
| const SharedBitmapDescriptor& rpCenterBitmaps, |
| const SharedBitmapDescriptor& rpEndBitmaps) |
| { |
| const awt::Rectangle aWindowBox (mxWindow->getPosSize()); |
| geometry::RealRectangle2D aBox (GetRectangle(eArea)); |
| aBox.X1 += aWindowBox.X; |
| aBox.Y1 += aWindowBox.Y; |
| aBox.X2 += aWindowBox.X; |
| aBox.Y2 += aWindowBox.Y; |
| |
| // Get bitmaps and sizes. |
| |
| PresenterUIPainter::PaintVerticalBitmapComposite( |
| mxCanvas, |
| rUpdateBox, |
| (eArea == Thumb |
| ? PresenterGeometryHelper::ConvertRectangleWithConstantSize(aBox) |
| : PresenterGeometryHelper::ConvertRectangle(aBox)), |
| GetBitmap(eArea, rpStartBitmaps), |
| GetBitmap(eArea, rpCenterBitmaps), |
| GetBitmap(eArea, rpEndBitmaps)); |
| } |
| |
| |
| |
| |
| //===== PresenterHorizontalScrollBar ============================================ |
| |
| PresenterHorizontalScrollBar::PresenterHorizontalScrollBar ( |
| const Reference<XComponentContext>& rxComponentContext, |
| const Reference<awt::XWindow>& rxParentWindow, |
| const ::boost::shared_ptr<PresenterPaintManager>& rpPaintManager, |
| const ::boost::function<void(double)>& rThumbMotionListener) |
| : PresenterScrollBar(rxComponentContext, rxParentWindow, rpPaintManager, rThumbMotionListener), |
| mnScrollBarHeight(0) |
| { |
| } |
| |
| |
| |
| |
| PresenterHorizontalScrollBar::~PresenterHorizontalScrollBar (void) |
| { |
| } |
| |
| |
| |
| |
| double PresenterHorizontalScrollBar::GetDragDistance (const sal_Int32 nX, const sal_Int32 nY) const |
| { |
| (void)nY; |
| const double nDistance (nX - maDragAnchor.X); |
| if (nDistance == 0) |
| return 0; |
| else |
| { |
| const awt::Rectangle aWindowBox (mxWindow->getPosSize()); |
| const double nBarHeight (aWindowBox.Height); |
| const double nPagerWidth (aWindowBox.Width - 2*nBarHeight); |
| const double nDragDistance (mnTotalSize / nPagerWidth * nDistance); |
| if (nDragDistance + mnThumbPosition < 0) |
| return -mnThumbPosition; |
| else if (mnThumbPosition + nDragDistance > mnTotalSize-mnThumbSize) |
| return mnTotalSize-mnThumbSize-mnThumbPosition; |
| else |
| return nDragDistance; |
| } |
| } |
| |
| |
| |
| |
| void PresenterHorizontalScrollBar::UpdateDragAnchor (const double nDragDistance) |
| { |
| const awt::Rectangle aWindowBox (mxWindow->getPosSize()); |
| const double nBarHeight (aWindowBox.Height); |
| const double nPagerWidth (aWindowBox.Width - 2*nBarHeight); |
| maDragAnchor.X += nDragDistance * nPagerWidth / mnTotalSize; |
| } |
| |
| |
| |
| |
| sal_Int32 PresenterHorizontalScrollBar::GetSize (void) const |
| { |
| return mnScrollBarHeight; |
| } |
| |
| |
| |
| |
| |
| geometry::RealPoint2D PresenterHorizontalScrollBar::GetPoint ( |
| const double nMajor, const double nMinor) const |
| { |
| return geometry::RealPoint2D(nMajor, nMinor); |
| } |
| |
| |
| |
| |
| double PresenterHorizontalScrollBar::GetMajor (const double nX, const double nY) const |
| { |
| (void)nY; |
| return nX; |
| } |
| |
| |
| |
| |
| double PresenterHorizontalScrollBar::GetMinor (const double nX, const double nY) const |
| { |
| (void)nX; |
| return nY; |
| } |
| |
| |
| |
| |
| void PresenterHorizontalScrollBar::UpdateBorders (void) |
| { |
| const awt::Rectangle aWindowBox (mxWindow->getPosSize()); |
| double nRight = aWindowBox.Width; |
| const double nGap (2); |
| |
| if (mpNextButtonDescriptor.get() != NULL) |
| { |
| Reference<rendering::XBitmap> xBitmap (mpNextButtonDescriptor->GetNormalBitmap()); |
| if (xBitmap.is()) |
| { |
| geometry::IntegerSize2D aSize (xBitmap->getSize()); |
| maBox[NextButton] = geometry::RealRectangle2D( |
| nRight - aSize.Width,0, nRight, aWindowBox.Height); |
| nRight -= aSize.Width + nGap; |
| } |
| } |
| if (mpPrevButtonDescriptor.get() != NULL) |
| { |
| Reference<rendering::XBitmap> xBitmap (mpPrevButtonDescriptor->GetNormalBitmap()); |
| if (xBitmap.is()) |
| { |
| geometry::IntegerSize2D aSize (xBitmap->getSize()); |
| maBox[PrevButton] = geometry::RealRectangle2D( |
| nRight - aSize.Width,0, nRight, aWindowBox.Height); |
| nRight -= aSize.Width + nGap; |
| } |
| } |
| |
| const double nPagerWidth (nRight); |
| maBox[Pager] = geometry::RealRectangle2D( |
| 0,0, nRight, aWindowBox.Height); |
| if (mnTotalSize == 0) |
| { |
| maBox[Thumb] = maBox[Pager]; |
| |
| // Set up the enabled/disabled states. |
| maEnabledState[PrevButton] = false; |
| maEnabledState[PagerUp] = false; |
| maEnabledState[NextButton] = false; |
| maEnabledState[PagerDown] = false; |
| maEnabledState[Thumb] = false; |
| } |
| else |
| { |
| const double nThumbSize = ::std::min(mnThumbSize,mnTotalSize); |
| const double nThumbPosition = ::std::min(::std::max(0.0,mnThumbPosition), mnTotalSize - nThumbSize); |
| maBox[Thumb] = geometry::RealRectangle2D( |
| (nThumbPosition) / mnTotalSize * nPagerWidth, 0, |
| (nThumbPosition+nThumbSize) / mnTotalSize * nPagerWidth, aWindowBox.Height); |
| |
| // Set up the enabled/disabled states. |
| maEnabledState[PrevButton] = nThumbPosition>0; |
| maEnabledState[PagerUp] = nThumbPosition>0; |
| maEnabledState[NextButton] = nThumbPosition+nThumbSize < mnTotalSize; |
| maEnabledState[PagerDown] = nThumbPosition+nThumbSize < mnTotalSize; |
| maEnabledState[Thumb] = nThumbSize < mnTotalSize; |
| } |
| maBox[PagerUp] = geometry::RealRectangle2D( |
| maBox[Pager].X1, maBox[Pager].Y1, maBox[Thumb].X1-1, maBox[Pager].Y2); |
| maBox[PagerDown] = geometry::RealRectangle2D( |
| maBox[Thumb].X2+1, maBox[Pager].Y1, maBox[Pager].X2, maBox[Pager].Y2); |
| maBox[Total] = PresenterGeometryHelper::Union( |
| PresenterGeometryHelper::Union(maBox[PrevButton], maBox[NextButton]), |
| maBox[Pager]); |
| } |
| |
| |
| |
| |
| void PresenterHorizontalScrollBar::UpdateBitmaps (void) |
| { |
| if (mpBitmaps.get() != NULL) |
| { |
| mpPrevButtonDescriptor = mpBitmaps->GetBitmap(A2S("Left")); |
| mpNextButtonDescriptor = mpBitmaps->GetBitmap(A2S("Right")); |
| mpPagerStartDescriptor = mpBitmaps->GetBitmap(A2S("PagerLeft")); |
| mpPagerCenterDescriptor = mpBitmaps->GetBitmap(A2S("PagerHorizontal")); |
| mpPagerEndDescriptor = mpBitmaps->GetBitmap(A2S("PagerRight")); |
| mpThumbStartDescriptor = mpBitmaps->GetBitmap(A2S("ThumbLeft")); |
| mpThumbCenterDescriptor = mpBitmaps->GetBitmap(A2S("ThumbHorizontal")); |
| mpThumbEndDescriptor = mpBitmaps->GetBitmap(A2S("ThumbRight")); |
| |
| mnScrollBarHeight = 0; |
| UpdateWidthOrHeight(mnScrollBarHeight, mpPrevButtonDescriptor); |
| UpdateWidthOrHeight(mnScrollBarHeight, mpNextButtonDescriptor); |
| UpdateWidthOrHeight(mnScrollBarHeight, mpPagerStartDescriptor); |
| UpdateWidthOrHeight(mnScrollBarHeight, mpPagerCenterDescriptor); |
| UpdateWidthOrHeight(mnScrollBarHeight, mpPagerEndDescriptor); |
| UpdateWidthOrHeight(mnScrollBarHeight, mpThumbStartDescriptor); |
| UpdateWidthOrHeight(mnScrollBarHeight, mpThumbCenterDescriptor); |
| UpdateWidthOrHeight(mnScrollBarHeight, mpThumbEndDescriptor); |
| if (mnScrollBarHeight == 0) |
| mnScrollBarHeight = 20; |
| } |
| } |
| |
| |
| |
| void PresenterHorizontalScrollBar::PaintComposite( |
| const css::awt::Rectangle& rUpdateBox, |
| const Area eArea, |
| const SharedBitmapDescriptor& rpStartBitmaps, |
| const SharedBitmapDescriptor& rpCenterBitmaps, |
| const SharedBitmapDescriptor& rpEndBitmaps) |
| { |
| const awt::Rectangle aWindowBox (mxWindow->getPosSize()); |
| geometry::RealRectangle2D aBox (GetRectangle(eArea)); |
| aBox.X1 += aWindowBox.X; |
| aBox.Y1 += aWindowBox.Y; |
| aBox.X2 += aWindowBox.X; |
| aBox.Y2 += aWindowBox.Y; |
| |
| PresenterUIPainter::PaintHorizontalBitmapComposite( |
| mxCanvas, |
| rUpdateBox, |
| PresenterGeometryHelper::ConvertRectangle(aBox), |
| GetBitmap(eArea, rpStartBitmaps), |
| GetBitmap(eArea, rpCenterBitmaps), |
| GetBitmap(eArea, rpEndBitmaps)); |
| } |
| |
| |
| |
| |
| //===== PresenterScrollBar::MousePressRepeater ================================ |
| |
| PresenterScrollBar::MousePressRepeater::MousePressRepeater ( |
| const ::rtl::Reference<PresenterScrollBar>& rpScrollBar) |
| : mnMousePressRepeaterTaskId(PresenterTimer::NotAValidTaskId), |
| mpScrollBar(rpScrollBar), |
| meMouseArea(PresenterScrollBar::None) |
| { |
| } |
| |
| |
| |
| |
| void PresenterScrollBar::MousePressRepeater::Dispose (void) |
| { |
| Stop(); |
| mpScrollBar = NULL; |
| } |
| |
| |
| |
| |
| void PresenterScrollBar::MousePressRepeater::Start (const PresenterScrollBar::Area& reArea) |
| { |
| meMouseArea = reArea; |
| |
| if (mnMousePressRepeaterTaskId == PresenterTimer::NotAValidTaskId) |
| { |
| // Execute key press operation at least this one time. |
| Execute(); |
| |
| // Schedule repeated executions. |
| mnMousePressRepeaterTaskId = PresenterTimer::ScheduleRepeatedTask ( |
| ::boost::bind(&PresenterScrollBar::MousePressRepeater::Callback, shared_from_this(), _1), |
| 500000000, |
| 250000000); |
| } |
| else |
| { |
| // There is already an active repeating task. |
| } |
| } |
| |
| |
| |
| |
| void PresenterScrollBar::MousePressRepeater::Stop (void) |
| { |
| if (mnMousePressRepeaterTaskId != PresenterTimer::NotAValidTaskId) |
| { |
| const sal_Int32 nTaskId (mnMousePressRepeaterTaskId); |
| mnMousePressRepeaterTaskId = PresenterTimer::NotAValidTaskId; |
| PresenterTimer::CancelTask(nTaskId); |
| } |
| } |
| |
| |
| |
| |
| void PresenterScrollBar::MousePressRepeater::SetMouseArea(const PresenterScrollBar::Area& reArea) |
| { |
| if (meMouseArea != reArea) |
| { |
| if (mnMousePressRepeaterTaskId != PresenterTimer::NotAValidTaskId) |
| { |
| Stop(); |
| } |
| } |
| } |
| |
| |
| |
| |
| void PresenterScrollBar::MousePressRepeater::Callback (const TimeValue& rCurrentTime) |
| { |
| (void)rCurrentTime; |
| |
| if (mpScrollBar.get() == NULL) |
| { |
| Stop(); |
| return; |
| } |
| |
| Execute(); |
| } |
| |
| |
| |
| |
| void PresenterScrollBar::MousePressRepeater::Execute (void) |
| { |
| const double nThumbPosition (mpScrollBar->GetThumbPosition()); |
| switch (meMouseArea) |
| { |
| case PrevButton: |
| mpScrollBar->SetThumbPosition(nThumbPosition - mpScrollBar->GetLineHeight(), true); |
| break; |
| |
| case NextButton: |
| mpScrollBar->SetThumbPosition(nThumbPosition + mpScrollBar->GetLineHeight(), true); |
| break; |
| |
| case PagerUp: |
| mpScrollBar->SetThumbPosition(nThumbPosition - mpScrollBar->GetThumbSize()*0.8, true); |
| break; |
| |
| case PagerDown: |
| mpScrollBar->SetThumbPosition(nThumbPosition + mpScrollBar->GetThumbSize()*0.8, true); |
| break; |
| |
| default: |
| break; |
| } |
| } |
| |
| |
| |
| } } // end of namespace ::sdext::presenter |