Update ooo320-m1
[ooovba.git] / sd / source / ui / slidesorter / view / SlsViewOverlay.cxx
blobd41b5947e6544de04462ec9e6fa3ca6d761377b9
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: SlsViewOverlay.cxx,v $
10 * $Revision: 1.16 $
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"
48 #include "Window.hxx"
49 #include "sdpage.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;
68 namespace {
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)
160 setVisible(false);
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),
193 maPosition(0,0),
194 maShapes()
201 SubstitutionOverlay::~SubstitutionOverlay (void)
208 void SubstitutionOverlay::Create (
209 model::PageEnumeration& rSelection,
210 const Point& rPosition)
212 EnsureRegistration();
214 maPosition = rPosition;
216 maShapes.clear();
217 while (rSelection.HasMoreElements())
219 const Rectangle aBox (rSelection.GetNextElement()->GetPageObject()->GetCurrentBoundRect());
220 basegfx::B2DRectangle aB2DBox(
221 aBox.Left(),
222 aBox.Top(),
223 aBox.Right(),
224 aBox.Bottom());
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.
231 objectChange();
237 void SubstitutionOverlay::Clear (void)
239 maShapes.clear();
240 setVisible(false);
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;
254 objectChange();
260 void SubstitutionOverlay::SetPosition (const Point& rPosition)
262 Move(rPosition - GetPosition());
268 Point SubstitutionOverlay::GetPosition (void) const
270 return maPosition;
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),
292 aRGBColorA,
293 aRGBColorB,
294 gnSubstitutionStripeLength));
298 return aRetval;
301 void SubstitutionOverlay::stripeDefinitionHasChanged()
303 // react on OverlayManager's stripe definition change
304 objectChange();
308 //===== SelectionRectangleOverlay ===========================================
310 SelectionRectangleOverlay::SelectionRectangleOverlay (ViewOverlay& rViewOverlay)
311 : OverlayBase (rViewOverlay),
312 maAnchor(0,0),
313 maSecondCorner(0,0)
320 Rectangle SelectionRectangleOverlay::GetSelectionRectangle (void)
322 return Rectangle(maAnchor, maSecondCorner);
328 void SelectionRectangleOverlay::Start (const Point& rAnchor)
330 EnsureRegistration();
331 setVisible(false);
332 maAnchor = rAnchor;
338 void SelectionRectangleOverlay::Update (const Point& rSecondCorner)
340 maSecondCorner = rSecondCorner;
341 setVisible(true);
342 // The selection rectangle may have been visible already so call
343 // objectChange() to enforce an update.
344 objectChange();
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));
356 if(aPolygon.count())
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(
362 aPolygon,
363 aRGBColorA,
364 aRGBColorB,
365 gnSubstitutionStripeLength));
367 aRetval = drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1);
370 return aRetval;
373 void SelectionRectangleOverlay::stripeDefinitionHasChanged()
375 // react on OverlayManager's stripe definition change
376 objectChange();
382 //===== InsertionIndicatorOverlay ===========================================
384 InsertionIndicatorOverlay::InsertionIndicatorOverlay (ViewOverlay& rViewOverlay)
385 : OverlayBase (rViewOverlay),
386 mnInsertionIndex(-1),
387 maBoundingBox()
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.
401 objectChange();
407 void InsertionIndicatorOverlay::SetPosition (const Point& rPoint)
409 static const bool bAllowHorizontalInsertMarker = true;
410 Layouter& rLayouter (mrViewOverlay.GetSlideSorter().GetView().GetLayouter());
411 USHORT nPageCount
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
428 // column.
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)
440 bVertical = false;
441 bLeftOrTop = (rPoint.Y() <= aPageCenter.Y());
443 else
445 bVertical = true;
446 bLeftOrTop = (rPoint.X() <= aPageCenter.X());
449 // Add one when the mark was painted below or to the right of the
450 // page object.
451 if ( ! bLeftOrTop)
452 nInsertionIndex += 1;
455 mnInsertionIndex = nInsertionIndex;
457 Rectangle aBox;
458 if (mnInsertionIndex >= 0)
459 aBox = rLayouter.GetInsertionMarkerBox (
460 nDrawIndex,
461 bVertical,
462 bLeftOrTop);
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),
487 aRGBColor));
488 aRetval[1] = drawinglayer::primitive2d::Primitive2DReference(
489 new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(
490 aPolygon,
491 aRGBColor));
493 return aRetval;
499 //===== MouseOverIndicatorOverlay ===========================================
501 MouseOverIndicatorOverlay::MouseOverIndicatorOverlay (ViewOverlay& rViewOverlay)
502 : OverlayBase (rViewOverlay),
503 mpPageUnderMouse()
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.
546 objectChange();
554 drawinglayer::primitive2d::Primitive2DSequence MouseOverIndicatorOverlay::createOverlayObjectPrimitive2DSequence()
556 view::PageObjectViewObjectContact* pContact = GetViewObjectContact();
558 if(pContact)
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();
576 return NULL;
582 } } } // end of namespace ::sd::slidesorter::view