summaryrefslogtreecommitdiff
path: root/sd/source/ui/slidesorter/view/SlsViewOverlay.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sd/source/ui/slidesorter/view/SlsViewOverlay.cxx')
-rw-r--r--sd/source/ui/slidesorter/view/SlsViewOverlay.cxx606
1 files changed, 606 insertions, 0 deletions
diff --git a/sd/source/ui/slidesorter/view/SlsViewOverlay.cxx b/sd/source/ui/slidesorter/view/SlsViewOverlay.cxx
new file mode 100644
index 000000000000..32576240036c
--- /dev/null
+++ b/sd/source/ui/slidesorter/view/SlsViewOverlay.cxx
@@ -0,0 +1,606 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org 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 version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+#include "precompiled_sd.hxx"
+
+#include "view/SlsViewOverlay.hxx"
+
+#include "SlideSorter.hxx"
+#include "model/SlideSorterModel.hxx"
+#include "model/SlsPageDescriptor.hxx"
+#include "model/SlsPageEnumeration.hxx"
+#include "view/SlideSorterView.hxx"
+#include "SlideSorterViewShell.hxx"
+#include "view/SlsLayouter.hxx"
+#include "view/SlsPageObject.hxx"
+#include "view/SlsPageObjectViewObjectContact.hxx"
+#include "ViewShell.hxx"
+#include "ViewShellBase.hxx"
+#include "UpdateLockManager.hxx"
+
+#include "Window.hxx"
+#include "sdpage.hxx"
+
+#include <basegfx/range/b2drectangle.hxx>
+#include <basegfx/range/b2drange.hxx>
+#include <basegfx/range/b2irange.hxx>
+#include <basegfx/matrix/b2dhommatrix.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <basegfx/polygon/b2dpolypolygontools.hxx>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
+
+#include <svx/sdr/overlay/overlaymanager.hxx>
+#include <svx/svdpagv.hxx>
+#include <svx/sdrpagewindow.hxx>
+#include <vcl/svapp.hxx>
+
+#include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
+#include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
+
+using namespace ::sdr::overlay;
+
+namespace {
+ const static sal_Int32 gnSubstitutionStripeLength (3);
+}
+
+namespace sd { namespace slidesorter { namespace view {
+
+//===== ViewOverlay =========================================================
+
+ViewOverlay::ViewOverlay (SlideSorter& rSlideSorter)
+ : mrSlideSorter(rSlideSorter),
+ maSelectionRectangleOverlay(*this),
+ maMouseOverIndicatorOverlay(*this),
+ maInsertionIndicatorOverlay(*this),
+ maSubstitutionOverlay(*this)
+{
+}
+
+
+
+
+ViewOverlay::~ViewOverlay (void)
+{
+}
+
+
+
+
+SelectionRectangleOverlay& ViewOverlay::GetSelectionRectangleOverlay (void)
+{
+ return maSelectionRectangleOverlay;
+}
+
+
+
+
+MouseOverIndicatorOverlay& ViewOverlay::GetMouseOverIndicatorOverlay (void)
+{
+ return maMouseOverIndicatorOverlay;
+}
+
+
+
+
+InsertionIndicatorOverlay& ViewOverlay::GetInsertionIndicatorOverlay (void)
+{
+ return maInsertionIndicatorOverlay;
+}
+
+
+
+
+SubstitutionOverlay& ViewOverlay::GetSubstitutionOverlay (void)
+{
+ return maSubstitutionOverlay;
+}
+
+
+
+
+SlideSorter& ViewOverlay::GetSlideSorter (void) const
+{
+ return mrSlideSorter;
+}
+
+
+
+
+OverlayManager* ViewOverlay::GetOverlayManager (void) const
+{
+ OverlayManager* pOverlayManager = NULL;
+
+ SlideSorterView& rView (mrSlideSorter.GetView());
+ SdrPageView* pPageView = rView.GetSdrPageView();
+ if (pPageView != NULL && pPageView->PageWindowCount()>0)
+ {
+ SdrPageWindow* pPageWindow = pPageView->GetPageWindow(0);
+ if (pPageWindow != NULL)
+ pOverlayManager = pPageWindow->GetOverlayManager();
+ }
+
+ return pOverlayManager;
+}
+
+
+
+
+//===== OverlayBase =========================================================
+
+OverlayBase::OverlayBase (ViewOverlay& rViewOverlay)
+ : OverlayObject(Color(0,0,0)),
+ mrViewOverlay(rViewOverlay)
+{
+ setVisible(false);
+}
+
+
+
+
+OverlayBase::~OverlayBase (void)
+{
+ OSL_ENSURE(!getOverlayManager(), "Please call RemoveRegistration() in the derived class; it's too late to call it in the base class since virtual methods will be missing when called in the destructor.");
+}
+
+
+
+
+void OverlayBase::EnsureRegistration (void)
+{
+ if (getOverlayManager() == NULL)
+ {
+ OverlayManager* pOverlayManager = mrViewOverlay.GetOverlayManager();
+ if (pOverlayManager != NULL)
+ pOverlayManager->add(*this);
+ }
+}
+
+
+
+
+void OverlayBase::RemoveRegistration()
+{
+ OverlayManager* pOverlayManager = getOverlayManager();
+ if (pOverlayManager != NULL)
+ pOverlayManager->remove(*this);
+}
+
+
+
+
+//===== SubstitutionOverlay =================================================
+
+SubstitutionOverlay::SubstitutionOverlay (ViewOverlay& rViewOverlay)
+ : OverlayBase(rViewOverlay),
+ maPosition(0,0),
+ maShapes()
+{
+}
+
+
+
+
+SubstitutionOverlay::~SubstitutionOverlay (void)
+{
+ RemoveRegistration();
+}
+
+
+
+
+void SubstitutionOverlay::Create (
+ model::PageEnumeration& rSelection,
+ const Point& rPosition)
+{
+ EnsureRegistration();
+
+ maPosition = rPosition;
+
+ maShapes.clear();
+ while (rSelection.HasMoreElements())
+ {
+ const Rectangle aBox (rSelection.GetNextElement()->GetPageObject()->GetCurrentBoundRect());
+ basegfx::B2DRectangle aB2DBox(
+ aBox.Left(),
+ aBox.Top(),
+ aBox.Right(),
+ aBox.Bottom());
+ maShapes.append(basegfx::tools::createPolygonFromRect(aB2DBox), 4);
+ }
+
+ setVisible(maShapes.count() > 0);
+ // The selection indicator may have been visible already so call
+ // objectChange() to enforce an update.
+ objectChange();
+}
+
+
+
+
+void SubstitutionOverlay::Clear (void)
+{
+ maShapes.clear();
+ setVisible(false);
+}
+
+
+
+
+void SubstitutionOverlay::Move (const Point& rOffset)
+{
+ const basegfx::B2DHomMatrix aTranslation(basegfx::tools::createTranslateB2DHomMatrix(rOffset.X(), rOffset.Y()));
+
+ maShapes.transform(aTranslation);
+ maPosition += rOffset;
+
+ objectChange();
+}
+
+
+
+
+void SubstitutionOverlay::SetPosition (const Point& rPosition)
+{
+ Move(rPosition - GetPosition());
+}
+
+
+
+
+Point SubstitutionOverlay::GetPosition (void) const
+{
+ return maPosition;
+}
+
+
+
+
+drawinglayer::primitive2d::Primitive2DSequence SubstitutionOverlay::createOverlayObjectPrimitive2DSequence()
+{
+ drawinglayer::primitive2d::Primitive2DSequence aRetval;
+ const sal_uInt32 nCount(maShapes.count());
+
+ if(nCount && getOverlayManager())
+ {
+ aRetval.realloc(nCount);
+ const basegfx::BColor aRGBColorA(getOverlayManager()->getStripeColorA().getBColor());
+ const basegfx::BColor aRGBColorB(getOverlayManager()->getStripeColorB().getBColor());
+
+ for(sal_uInt32 a(0); a < nCount; a++)
+ {
+ aRetval[a] = drawinglayer::primitive2d::Primitive2DReference(
+ new drawinglayer::primitive2d::PolygonMarkerPrimitive2D(
+ maShapes.getB2DPolygon(a),
+ aRGBColorA,
+ aRGBColorB,
+ gnSubstitutionStripeLength));
+ }
+ }
+
+ return aRetval;
+}
+
+void SubstitutionOverlay::stripeDefinitionHasChanged()
+{
+ // react on OverlayManager's stripe definition change
+ objectChange();
+}
+
+
+//===== SelectionRectangleOverlay ===========================================
+
+SelectionRectangleOverlay::SelectionRectangleOverlay (ViewOverlay& rViewOverlay)
+ : OverlayBase (rViewOverlay),
+ maAnchor(0,0),
+ maSecondCorner(0,0)
+{
+}
+
+
+
+SelectionRectangleOverlay::~SelectionRectangleOverlay()
+{
+ RemoveRegistration();
+}
+
+
+
+
+Rectangle SelectionRectangleOverlay::GetSelectionRectangle (void)
+{
+ return Rectangle(maAnchor, maSecondCorner);
+}
+
+
+
+
+void SelectionRectangleOverlay::Start (const Point& rAnchor)
+{
+ EnsureRegistration();
+ setVisible(false);
+ maAnchor = rAnchor;
+}
+
+
+
+
+void SelectionRectangleOverlay::Update (const Point& rSecondCorner)
+{
+ maSecondCorner = rSecondCorner;
+ setVisible(true);
+ // The selection rectangle may have been visible already so call
+ // objectChange() to enforce an update.
+ objectChange();
+}
+
+
+
+
+drawinglayer::primitive2d::Primitive2DSequence SelectionRectangleOverlay::createOverlayObjectPrimitive2DSequence()
+{
+ drawinglayer::primitive2d::Primitive2DSequence aRetval;
+ const basegfx::B2DRange aRange(maAnchor.X(), maAnchor.Y(), maSecondCorner.X(), maSecondCorner.Y());
+ const basegfx::B2DPolygon aPolygon(basegfx::tools::createPolygonFromRect(aRange));
+
+ if(aPolygon.count())
+ {
+ const basegfx::BColor aRGBColorA(getOverlayManager()->getStripeColorA().getBColor());
+ const basegfx::BColor aRGBColorB(getOverlayManager()->getStripeColorB().getBColor());
+ const drawinglayer::primitive2d::Primitive2DReference xReference(
+ new drawinglayer::primitive2d::PolygonMarkerPrimitive2D(
+ aPolygon,
+ aRGBColorA,
+ aRGBColorB,
+ gnSubstitutionStripeLength));
+
+ aRetval = drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1);
+ }
+
+ return aRetval;
+}
+
+void SelectionRectangleOverlay::stripeDefinitionHasChanged()
+{
+ // react on OverlayManager's stripe definition change
+ objectChange();
+}
+
+
+
+
+//===== InsertionIndicatorOverlay ===========================================
+
+InsertionIndicatorOverlay::InsertionIndicatorOverlay (ViewOverlay& rViewOverlay)
+ : OverlayBase (rViewOverlay),
+ mnInsertionIndex(-1),
+ maBoundingBox()
+{
+}
+
+
+
+
+InsertionIndicatorOverlay::~InsertionIndicatorOverlay()
+{
+ RemoveRegistration();
+}
+
+
+
+
+void InsertionIndicatorOverlay::SetPositionAndSize (const Rectangle& aNewBoundingBox)
+{
+ EnsureRegistration();
+ maBoundingBox = aNewBoundingBox;
+ setVisible( ! maBoundingBox.IsEmpty());
+ // The insertion indicator may have been visible already so call
+ // objectChange() to enforce an update.
+ objectChange();
+}
+
+
+
+
+void InsertionIndicatorOverlay::SetPosition (const Point& rPoint)
+{
+ static const bool bAllowHorizontalInsertMarker = true;
+ Layouter& rLayouter (mrViewOverlay.GetSlideSorter().GetView().GetLayouter());
+ USHORT nPageCount
+ = (USHORT)mrViewOverlay.GetSlideSorter().GetModel().GetPageCount();
+
+ sal_Int32 nInsertionIndex = rLayouter.GetInsertionIndex (rPoint,
+ bAllowHorizontalInsertMarker);
+ if (nInsertionIndex >= nPageCount)
+ nInsertionIndex = nPageCount-1;
+ sal_Int32 nDrawIndex = nInsertionIndex;
+
+ bool bVertical = false;
+ bool bLeftOrTop = false;
+ if (nInsertionIndex >= 0)
+ {
+ // Now that we know where to insert, we still have to determine
+ // where to draw the marker. There are two decisions to make:
+ // 1. Draw a vertical or a horizontal insert marker.
+ // The horizontal one may only be chosen when there is only one
+ // column.
+ // 2. The vertical (standard) insert marker may be painted left to
+ // the insert page or right of the previous one. When both pages
+ // are in the same row this makes no difference. Otherwise the
+ // posiotions are at the left and right ends of two rows.
+
+ Point aPageCenter (rLayouter.GetPageObjectBox (
+ nInsertionIndex).Center());
+
+ if (bAllowHorizontalInsertMarker
+ && rLayouter.GetColumnCount() == 1)
+ {
+ bVertical = false;
+ bLeftOrTop = (rPoint.Y() <= aPageCenter.Y());
+ }
+ else
+ {
+ bVertical = true;
+ bLeftOrTop = (rPoint.X() <= aPageCenter.X());
+ }
+
+ // Add one when the mark was painted below or to the right of the
+ // page object.
+ if ( ! bLeftOrTop)
+ nInsertionIndex += 1;
+ }
+
+ mnInsertionIndex = nInsertionIndex;
+
+ Rectangle aBox;
+ if (mnInsertionIndex >= 0)
+ aBox = rLayouter.GetInsertionMarkerBox (
+ nDrawIndex,
+ bVertical,
+ bLeftOrTop);
+ SetPositionAndSize (aBox);
+}
+
+
+
+
+sal_Int32 InsertionIndicatorOverlay::GetInsertionPageIndex (void) const
+{
+ return mnInsertionIndex;
+}
+
+
+
+
+drawinglayer::primitive2d::Primitive2DSequence InsertionIndicatorOverlay::createOverlayObjectPrimitive2DSequence()
+{
+ drawinglayer::primitive2d::Primitive2DSequence aRetval(2);
+ const basegfx::B2DRange aRange(maBoundingBox.Left(), maBoundingBox.Top(), maBoundingBox.Right(), maBoundingBox.Bottom());
+ const basegfx::B2DPolygon aPolygon(basegfx::tools::createPolygonFromRect(aRange));
+ const basegfx::BColor aRGBColor(Application::GetDefaultDevice()->GetSettings().GetStyleSettings().GetFontColor().getBColor());
+
+ aRetval[0] = drawinglayer::primitive2d::Primitive2DReference(
+ new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D(
+ basegfx::B2DPolyPolygon(aPolygon),
+ aRGBColor));
+ aRetval[1] = drawinglayer::primitive2d::Primitive2DReference(
+ new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(
+ aPolygon,
+ aRGBColor));
+
+ return aRetval;
+}
+
+
+
+
+//===== MouseOverIndicatorOverlay ===========================================
+
+MouseOverIndicatorOverlay::MouseOverIndicatorOverlay (ViewOverlay& rViewOverlay)
+ : OverlayBase (rViewOverlay),
+ mpPageUnderMouse()
+{
+}
+
+
+
+
+MouseOverIndicatorOverlay::~MouseOverIndicatorOverlay (void)
+{
+ RemoveRegistration();
+}
+
+
+
+
+void MouseOverIndicatorOverlay::SetSlideUnderMouse (
+ const model::SharedPageDescriptor& rpDescriptor)
+{
+ ViewShellBase* pBase = mrViewOverlay.GetSlideSorter().GetViewShellBase();
+ if (pBase==NULL || ! pBase->GetUpdateLockManager()->IsLocked())
+ {
+ model::SharedPageDescriptor pDescriptor;
+ if ( ! mpPageUnderMouse.expired())
+ {
+ try
+ {
+ pDescriptor = model::SharedPageDescriptor(mpPageUnderMouse);
+ }
+ catch (::boost::bad_weak_ptr)
+ {
+ }
+ }
+
+ if (pDescriptor != rpDescriptor)
+ {
+ // Switch to the new (possibly empty) descriptor.
+ mpPageUnderMouse = rpDescriptor;
+
+ EnsureRegistration();
+
+ // Show the indicator when a valid page descriptor is given.
+ setVisible( ! mpPageUnderMouse.expired());
+ // The mouse over indicator may have been visible already so call
+ // objectChange() to enforce an update.
+ objectChange();
+ }
+ }
+}
+
+
+
+
+drawinglayer::primitive2d::Primitive2DSequence MouseOverIndicatorOverlay::createOverlayObjectPrimitive2DSequence()
+{
+ view::PageObjectViewObjectContact* pContact = GetViewObjectContact();
+
+ if(pContact)
+ {
+ return pContact->createMouseOverEffectPrimitive2DSequence();
+ }
+
+ return drawinglayer::primitive2d::Primitive2DSequence();
+}
+
+
+
+
+view::PageObjectViewObjectContact* MouseOverIndicatorOverlay::GetViewObjectContact (void) const
+{
+ if ( ! mpPageUnderMouse.expired())
+ {
+ model::SharedPageDescriptor pDescriptor (mpPageUnderMouse);
+ return pDescriptor->GetViewObjectContact();
+ }
+ return NULL;
+}
+
+
+
+
+} } } // end of namespace ::sd::slidesorter::view
+