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: SlsViewOverlay.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 #include "precompiled_sd.hxx"
33 #include "view/SlsViewOverlay.hxx"
35 #include "SlideSorter.hxx"
36 #include "model/SlideSorterModel.hxx"
37 #include "model/SlsPageDescriptor.hxx"
38 #include "model/SlsPageEnumeration.hxx"
39 #include "view/SlideSorterView.hxx"
40 #include "SlideSorterViewShell.hxx"
41 #include "view/SlsLayouter.hxx"
42 #include "view/SlsPageObject.hxx"
43 #include "view/SlsPageObjectViewObjectContact.hxx"
44 #include "ViewShell.hxx"
45 #include "ViewShellBase.hxx"
46 #include "UpdateLockManager.hxx"
51 #include <basegfx/range/b2drectangle.hxx>
52 #include <basegfx/range/b2drange.hxx>
53 #include <basegfx/range/b2irange.hxx>
54 #include <basegfx/matrix/b2dhommatrix.hxx>
55 #include <basegfx/polygon/b2dpolygon.hxx>
56 #include <basegfx/polygon/b2dpolygontools.hxx>
57 #include <basegfx/polygon/b2dpolypolygontools.hxx>
58 #include <svx/sdr/overlay/overlaymanager.hxx>
59 #include <svx/svdpagv.hxx>
60 #include <svx/sdrpagewindow.hxx>
61 #include <vcl/svapp.hxx>
63 #include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
64 #include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
66 using namespace ::sdr::overlay
;
69 const static sal_Int32
gnSubstitutionStripeLength (3);
72 namespace sd
{ namespace slidesorter
{ namespace view
{
74 //===== ViewOverlay =========================================================
76 ViewOverlay::ViewOverlay (SlideSorter
& rSlideSorter
)
77 : mrSlideSorter(rSlideSorter
),
78 maSelectionRectangleOverlay(*this),
79 maMouseOverIndicatorOverlay(*this),
80 maInsertionIndicatorOverlay(*this),
81 maSubstitutionOverlay(*this)
88 ViewOverlay::~ViewOverlay (void)
95 SelectionRectangleOverlay
& ViewOverlay::GetSelectionRectangleOverlay (void)
97 return maSelectionRectangleOverlay
;
103 MouseOverIndicatorOverlay
& ViewOverlay::GetMouseOverIndicatorOverlay (void)
105 return maMouseOverIndicatorOverlay
;
111 InsertionIndicatorOverlay
& ViewOverlay::GetInsertionIndicatorOverlay (void)
113 return maInsertionIndicatorOverlay
;
119 SubstitutionOverlay
& ViewOverlay::GetSubstitutionOverlay (void)
121 return maSubstitutionOverlay
;
127 SlideSorter
& ViewOverlay::GetSlideSorter (void) const
129 return mrSlideSorter
;
135 OverlayManager
* ViewOverlay::GetOverlayManager (void) const
137 OverlayManager
* pOverlayManager
= NULL
;
139 SlideSorterView
& rView (mrSlideSorter
.GetView());
140 SdrPageView
* pPageView
= rView
.GetSdrPageView();
141 if (pPageView
!= NULL
&& pPageView
->PageWindowCount()>0)
143 SdrPageWindow
* pPageWindow
= pPageView
->GetPageWindow(0);
144 if (pPageWindow
!= NULL
)
145 pOverlayManager
= pPageWindow
->GetOverlayManager();
148 return pOverlayManager
;
154 //===== OverlayBase =========================================================
156 OverlayBase::OverlayBase (ViewOverlay
& rViewOverlay
)
157 : OverlayObject(Color(0,0,0)),
158 mrViewOverlay(rViewOverlay
)
166 OverlayBase::~OverlayBase (void)
168 OverlayManager
* pOverlayManager
= getOverlayManager();
169 if (pOverlayManager
!= NULL
)
170 pOverlayManager
->remove(*this);
176 void OverlayBase::EnsureRegistration (void)
178 if (getOverlayManager() == NULL
)
180 OverlayManager
* pOverlayManager
= mrViewOverlay
.GetOverlayManager();
181 if (pOverlayManager
!= NULL
)
182 pOverlayManager
->add(*this);
189 //===== SubstitutionOverlay =================================================
191 SubstitutionOverlay::SubstitutionOverlay (ViewOverlay
& rViewOverlay
)
192 : OverlayBase(rViewOverlay
),
201 SubstitutionOverlay::~SubstitutionOverlay (void)
208 void SubstitutionOverlay::Create (
209 model::PageEnumeration
& rSelection
,
210 const Point
& rPosition
)
212 EnsureRegistration();
214 maPosition
= rPosition
;
217 while (rSelection
.HasMoreElements())
219 const Rectangle
aBox (rSelection
.GetNextElement()->GetPageObject()->GetCurrentBoundRect());
220 basegfx::B2DRectangle
aB2DBox(
225 maShapes
.append(basegfx::tools::createPolygonFromRect(aB2DBox
), 4);
228 setVisible(maShapes
.count() > 0);
229 // The selection indicator may have been visible already so call
230 // objectChange() to enforce an update.
237 void SubstitutionOverlay::Clear (void)
246 void SubstitutionOverlay::Move (const Point
& rOffset
)
248 basegfx::B2DHomMatrix aTranslation
;
249 aTranslation
.translate(rOffset
.X(), rOffset
.Y());
251 maShapes
.transform(aTranslation
);
252 maPosition
+= rOffset
;
260 void SubstitutionOverlay::SetPosition (const Point
& rPosition
)
262 Move(rPosition
- GetPosition());
268 Point
SubstitutionOverlay::GetPosition (void) const
276 drawinglayer::primitive2d::Primitive2DSequence
SubstitutionOverlay::createOverlayObjectPrimitive2DSequence()
278 drawinglayer::primitive2d::Primitive2DSequence aRetval
;
279 const sal_uInt32
nCount(maShapes
.count());
281 if(nCount
&& getOverlayManager())
283 aRetval
.realloc(nCount
);
284 const basegfx::BColor
aRGBColorA(getOverlayManager()->getStripeColorA().getBColor());
285 const basegfx::BColor
aRGBColorB(getOverlayManager()->getStripeColorB().getBColor());
287 for(sal_uInt32
a(0); a
< nCount
; a
++)
289 aRetval
[a
] = drawinglayer::primitive2d::Primitive2DReference(
290 new drawinglayer::primitive2d::PolygonMarkerPrimitive2D(
291 maShapes
.getB2DPolygon(a
),
294 gnSubstitutionStripeLength
));
301 void SubstitutionOverlay::stripeDefinitionHasChanged()
303 // react on OverlayManager's stripe definition change
308 //===== SelectionRectangleOverlay ===========================================
310 SelectionRectangleOverlay::SelectionRectangleOverlay (ViewOverlay
& rViewOverlay
)
311 : OverlayBase (rViewOverlay
),
320 Rectangle
SelectionRectangleOverlay::GetSelectionRectangle (void)
322 return Rectangle(maAnchor
, maSecondCorner
);
328 void SelectionRectangleOverlay::Start (const Point
& rAnchor
)
330 EnsureRegistration();
338 void SelectionRectangleOverlay::Update (const Point
& rSecondCorner
)
340 maSecondCorner
= rSecondCorner
;
342 // The selection rectangle may have been visible already so call
343 // objectChange() to enforce an update.
350 drawinglayer::primitive2d::Primitive2DSequence
SelectionRectangleOverlay::createOverlayObjectPrimitive2DSequence()
352 drawinglayer::primitive2d::Primitive2DSequence aRetval
;
353 const basegfx::B2DRange
aRange(maAnchor
.X(), maAnchor
.Y(), maSecondCorner
.X(), maSecondCorner
.Y());
354 const basegfx::B2DPolygon
aPolygon(basegfx::tools::createPolygonFromRect(aRange
));
358 const basegfx::BColor
aRGBColorA(getOverlayManager()->getStripeColorA().getBColor());
359 const basegfx::BColor
aRGBColorB(getOverlayManager()->getStripeColorB().getBColor());
360 const drawinglayer::primitive2d::Primitive2DReference
xReference(
361 new drawinglayer::primitive2d::PolygonMarkerPrimitive2D(
365 gnSubstitutionStripeLength
));
367 aRetval
= drawinglayer::primitive2d::Primitive2DSequence(&xReference
, 1);
373 void SelectionRectangleOverlay::stripeDefinitionHasChanged()
375 // react on OverlayManager's stripe definition change
382 //===== InsertionIndicatorOverlay ===========================================
384 InsertionIndicatorOverlay::InsertionIndicatorOverlay (ViewOverlay
& rViewOverlay
)
385 : OverlayBase (rViewOverlay
),
386 mnInsertionIndex(-1),
394 void InsertionIndicatorOverlay::SetPositionAndSize (const Rectangle
& aNewBoundingBox
)
396 EnsureRegistration();
397 maBoundingBox
= aNewBoundingBox
;
398 setVisible( ! maBoundingBox
.IsEmpty());
399 // The insertion indicator may have been visible already so call
400 // objectChange() to enforce an update.
407 void InsertionIndicatorOverlay::SetPosition (const Point
& rPoint
)
409 static const bool bAllowHorizontalInsertMarker
= true;
410 Layouter
& rLayouter (mrViewOverlay
.GetSlideSorter().GetView().GetLayouter());
412 = (USHORT
)mrViewOverlay
.GetSlideSorter().GetModel().GetPageCount();
414 sal_Int32 nInsertionIndex
= rLayouter
.GetInsertionIndex (rPoint
,
415 bAllowHorizontalInsertMarker
);
416 if (nInsertionIndex
>= nPageCount
)
417 nInsertionIndex
= nPageCount
-1;
418 sal_Int32 nDrawIndex
= nInsertionIndex
;
420 bool bVertical
= false;
421 bool bLeftOrTop
= false;
422 if (nInsertionIndex
>= 0)
424 // Now that we know where to insert, we still have to determine
425 // where to draw the marker. There are two decisions to make:
426 // 1. Draw a vertical or a horizontal insert marker.
427 // The horizontal one may only be chosen when there is only one
429 // 2. The vertical (standard) insert marker may be painted left to
430 // the insert page or right of the previous one. When both pages
431 // are in the same row this makes no difference. Otherwise the
432 // posiotions are at the left and right ends of two rows.
434 Point
aPageCenter (rLayouter
.GetPageObjectBox (
435 nInsertionIndex
).Center());
437 if (bAllowHorizontalInsertMarker
438 && rLayouter
.GetColumnCount() == 1)
441 bLeftOrTop
= (rPoint
.Y() <= aPageCenter
.Y());
446 bLeftOrTop
= (rPoint
.X() <= aPageCenter
.X());
449 // Add one when the mark was painted below or to the right of the
452 nInsertionIndex
+= 1;
455 mnInsertionIndex
= nInsertionIndex
;
458 if (mnInsertionIndex
>= 0)
459 aBox
= rLayouter
.GetInsertionMarkerBox (
463 SetPositionAndSize (aBox
);
469 sal_Int32
InsertionIndicatorOverlay::GetInsertionPageIndex (void) const
471 return mnInsertionIndex
;
477 drawinglayer::primitive2d::Primitive2DSequence
InsertionIndicatorOverlay::createOverlayObjectPrimitive2DSequence()
479 drawinglayer::primitive2d::Primitive2DSequence
aRetval(2);
480 const basegfx::B2DRange
aRange(maBoundingBox
.Left(), maBoundingBox
.Top(), maBoundingBox
.Right(), maBoundingBox
.Bottom());
481 const basegfx::B2DPolygon
aPolygon(basegfx::tools::createPolygonFromRect(aRange
));
482 const basegfx::BColor
aRGBColor(Application::GetDefaultDevice()->GetSettings().GetStyleSettings().GetFontColor().getBColor());
484 aRetval
[0] = drawinglayer::primitive2d::Primitive2DReference(
485 new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D(
486 basegfx::B2DPolyPolygon(aPolygon
),
488 aRetval
[1] = drawinglayer::primitive2d::Primitive2DReference(
489 new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(
499 //===== MouseOverIndicatorOverlay ===========================================
501 MouseOverIndicatorOverlay::MouseOverIndicatorOverlay (ViewOverlay
& rViewOverlay
)
502 : OverlayBase (rViewOverlay
),
510 MouseOverIndicatorOverlay::~MouseOverIndicatorOverlay (void)
517 void MouseOverIndicatorOverlay::SetSlideUnderMouse (
518 const model::SharedPageDescriptor
& rpDescriptor
)
520 ViewShellBase
* pBase
= mrViewOverlay
.GetSlideSorter().GetViewShellBase();
521 if (pBase
==NULL
|| ! pBase
->GetUpdateLockManager()->IsLocked())
523 model::SharedPageDescriptor pDescriptor
;
524 if ( ! mpPageUnderMouse
.expired())
528 pDescriptor
= model::SharedPageDescriptor(mpPageUnderMouse
);
530 catch (::boost::bad_weak_ptr
)
535 if (pDescriptor
!= rpDescriptor
)
537 // Switch to the new (possibly empty) descriptor.
538 mpPageUnderMouse
= rpDescriptor
;
540 EnsureRegistration();
542 // Show the indicator when a valid page descriptor is given.
543 setVisible( ! mpPageUnderMouse
.expired());
544 // The mouse over indicator may have been visible already so call
545 // objectChange() to enforce an update.
554 drawinglayer::primitive2d::Primitive2DSequence
MouseOverIndicatorOverlay::createOverlayObjectPrimitive2DSequence()
556 view::PageObjectViewObjectContact
* pContact
= GetViewObjectContact();
560 return pContact
->createMouseOverEffectPrimitive2DSequence();
563 return drawinglayer::primitive2d::Primitive2DSequence();
569 view::PageObjectViewObjectContact
* MouseOverIndicatorOverlay::GetViewObjectContact (void) const
571 if ( ! mpPageUnderMouse
.expired())
573 model::SharedPageDescriptor
pDescriptor (mpPageUnderMouse
);
574 return pDescriptor
->GetViewObjectContact();
582 } } } // end of namespace ::sd::slidesorter::view