1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <com/sun/star/util/XChangesNotifier.hpp>
22 #include <basegfx/matrix/b2dhommatrix.hxx>
23 #include <basegfx/polygon/b2dpolygontools.hxx>
24 #include <basegfx/matrix/b2dhommatrixtools.hxx>
26 #include <sfx2/viewfrm.hxx>
27 #include <sfx2/dispatch.hxx>
29 #include <svx/svdpagv.hxx>
30 #include <svx/sdrpagewindow.hxx>
31 #include <svx/sdrpaintwindow.hxx>
32 #include <svx/svdopath.hxx>
33 #include <svx/xfillit0.hxx>
34 #include <svx/xlineit0.hxx>
35 #include <svx/xlndsit.hxx>
36 #include <svx/xlnclit.hxx>
37 #include <svx/xlnstit.hxx>
38 #include <svx/xlnedit.hxx>
39 #include <svx/xlnstwit.hxx>
40 #include <svx/xlnedwit.hxx>
41 #include <svx/xlnstcit.hxx>
42 #include <svx/xlnedcit.hxx>
43 #include <svx/xlntrit.hxx>
44 #include <svx/svxids.hrc>
45 #include <svx/polypolygoneditor.hxx>
46 #include <svx/svddrgmt.hxx>
48 #include <CustomAnimationPane.hxx>
50 #include "motionpathtag.hxx"
51 #include <ViewShell.hxx>
54 #include <svx/sdr/contact/viewcontact.hxx>
55 #include <svx/sdr/overlay/overlayprimitive2dsequenceobject.hxx>
58 using sdr::PolyPolygonEditor
;
59 using namespace ::com::sun::star
;
60 using namespace ::com::sun::star::uno
;
61 using namespace ::com::sun::star::lang
;
62 using namespace ::com::sun::star::util
;
63 using namespace ::com::sun::star::drawing
;
68 const sal_uInt32 SMART_TAG_HDL_NUM
= SAL_MAX_UINT32
;
69 const int DRGPIX
= 2; // Drag MinMove in Pixel
73 class PathDragMove
: public SdrDragMove
76 basegfx::B2DPolyPolygon maPathPolyPolygon
;
79 virtual void createSdrDragEntries() override
;
82 PathDragMove(SdrDragView
& rNewView
,
83 rtl::Reference
<MotionPathTag
> xTag
,
84 basegfx::B2DPolyPolygon aPathPolyPolygon
)
85 : SdrDragMove(rNewView
),
86 maPathPolyPolygon(std::move(aPathPolyPolygon
)),
87 mxTag(std::move( xTag
))
90 PathDragMove(SdrDragView
& rNewView
,
91 rtl::Reference
<MotionPathTag
> xTag
)
92 : SdrDragMove(rNewView
),
93 mxTag(std::move( xTag
))
96 virtual bool BeginSdrDrag() override
;
97 virtual bool EndSdrDrag(bool bCopy
) override
;
99 rtl::Reference
<MotionPathTag
> mxTag
;
104 void PathDragMove::createSdrDragEntries()
107 SdrDragMove::createSdrDragEntries();
109 if(maPathPolyPolygon
.count())
111 addSdrDragEntry(std::unique_ptr
<SdrDragEntry
>(new SdrDragEntryPolyPolygon(maPathPolyPolygon
)));
115 bool PathDragMove::BeginSdrDrag()
119 SdrPathObj
* pPathObj
= mxTag
->getPathObj();
122 DragStat().SetActionRect(pPathObj
->GetCurrentBoundRect());
129 bool PathDragMove::EndSdrDrag(bool /*bCopy*/)
133 mxTag
->MovePath( DragStat().GetDX(), DragStat().GetDY() );
139 class PathDragResize
: public SdrDragResize
142 basegfx::B2DPolyPolygon maPathPolyPolygon
;
145 virtual void createSdrDragEntries() override
;
148 PathDragResize(SdrDragView
& rNewView
,
149 rtl::Reference
<MotionPathTag
> xTag
,
150 basegfx::B2DPolyPolygon aPathPolyPolygon
)
151 : SdrDragResize(rNewView
),
152 maPathPolyPolygon(std::move(aPathPolyPolygon
)),
153 mxTag(std::move( xTag
))
156 PathDragResize(SdrDragView
& rNewView
,
157 rtl::Reference
<MotionPathTag
> xTag
)
158 : SdrDragResize(rNewView
),
159 mxTag(std::move( xTag
))
162 virtual bool EndSdrDrag(bool bCopy
) override
;
163 rtl::Reference
<MotionPathTag
> mxTag
;
168 void PathDragResize::createSdrDragEntries()
171 SdrDragResize::createSdrDragEntries();
173 if(maPathPolyPolygon
.count())
175 addSdrDragEntry(std::unique_ptr
<SdrDragEntry
>(new SdrDragEntryPolyPolygon(maPathPolyPolygon
)));
179 bool PathDragResize::EndSdrDrag(bool /*bCopy*/)
184 SdrPathObj
* pPathObj
= mxTag
->getPathObj();
187 const Point
aRef( DragStat().GetRef1() );
188 basegfx::B2DHomMatrix
aTrans(basegfx::utils::createTranslateB2DHomMatrix(-aRef
.X(), -aRef
.Y()));
189 aTrans
.scale(double(aXFact
), double(aYFact
));
190 aTrans
.translate(aRef
.X(), aRef
.Y());
191 basegfx::B2DPolyPolygon
aDragPoly(pPathObj
->GetPathPoly());
192 aDragPoly
.transform(aTrans
);
193 pPathObj
->SetPathPoly( aDragPoly
);
201 class PathDragObjOwn
: public SdrDragObjOwn
204 basegfx::B2DPolyPolygon maPathPolyPolygon
;
207 virtual void createSdrDragEntries() override
;
210 PathDragObjOwn(SdrDragView
& rNewView
,
211 basegfx::B2DPolyPolygon aPathPolyPolygon
)
212 : SdrDragObjOwn(rNewView
),
213 maPathPolyPolygon(std::move(aPathPolyPolygon
))
216 explicit PathDragObjOwn(SdrDragView
& rNewView
)
217 : SdrDragObjOwn(rNewView
)
220 virtual bool EndSdrDrag(bool bCopy
) override
;
225 void PathDragObjOwn::createSdrDragEntries()
228 SdrDragObjOwn::createSdrDragEntries();
230 if(maPathPolyPolygon
.count())
232 addSdrDragEntry(std::unique_ptr
<SdrDragEntry
>(new SdrDragEntryPolyPolygon(maPathPolyPolygon
)));
236 bool PathDragObjOwn::EndSdrDrag(bool /*bCopy*/)
240 SdrObject
* pObj
= GetDragObj();
242 if(pObj
&& pObj
->applySpecialDrag(DragStat()))
245 pObj
->BroadcastObjectChange();
256 class SdPathHdl
: public SmartHdl
259 SdPathHdl( const SmartTagReference
& xTag
, SdrPathObj
* mpPathObj
);
261 virtual void CreateB2dIAObject() override
;
262 virtual bool IsFocusHdl() const override
;
265 SdrPathObj
* mpPathObj
;
270 SdPathHdl::SdPathHdl( const SmartTagReference
& xTag
, SdrPathObj
* pPathObj
)
271 : SmartHdl( xTag
, pPathObj
->GetCurrentBoundRect().TopLeft(), SdrHdlKind::SmartTag
)
272 , mpPathObj( pPathObj
)
276 void SdPathHdl::CreateB2dIAObject()
278 // first throw away old one
284 SdrMarkView
* pView
= pHdlList
->GetView();
286 if(!pView
|| pView
->areMarkHandlesHidden())
289 SdrPageView
* pPageView
= pView
->GetSdrPageView();
294 for(sal_uInt32
b(0); b
< pPageView
->PageWindowCount(); b
++)
296 const SdrPageWindow
& rPageWindow
= *pPageView
->GetPageWindow(b
);
298 if(rPageWindow
.GetPaintWindow().OutputToWindow())
300 const rtl::Reference
< sdr::overlay::OverlayManager
>& xManager
= rPageWindow
.GetOverlayManager();
301 if (xManager
.is() && mpPathObj
)
303 const sdr::contact::ViewContact
& rVC
= mpPathObj
->GetViewContact();
304 drawinglayer::primitive2d::Primitive2DContainer aSequence
;
305 rVC
.getViewIndependentPrimitive2DContainer(aSequence
);
306 std::unique_ptr
<sdr::overlay::OverlayObject
> pNew(new sdr::overlay::OverlayPrimitive2DSequenceObject(std::move(aSequence
)));
309 insertNewlyCreatedOverlayObjectForSdrHdl(
311 rPageWindow
.GetObjectContact(),
318 bool SdPathHdl::IsFocusHdl() const
323 MotionPathTag::MotionPathTag( CustomAnimationPane
& rPane
, ::sd::View
& rView
, const CustomAnimationEffectPtr
& pEffect
)
326 , mpEffect( pEffect
)
327 , mxOrigin( pEffect
->getTargetShape() )
328 , msLastPath( pEffect
->getPath() )
329 , mbInUpdatePath( false )
331 mpPathObj
= mpEffect
->createSdrPathObjFromPath(rView
.getSdrModelFromSdrView());
332 mxPolyPoly
= mpPathObj
->GetPathPoly();
334 maOriginPos
= mxOrigin
->getPosition();
336 XDash
aDash( css::drawing::DashStyle_RECT
, 1, 80, 1, 80, 80);
337 OUString
aEmpty( "?" );
338 mpPathObj
->SetMergedItem( XLineDashItem( aEmpty
, aDash
) );
339 mpPathObj
->SetMergedItem( XLineStyleItem( drawing::LineStyle_DASH
) );
340 mpPathObj
->SetMergedItem( XLineColorItem(aEmpty
, COL_GRAY
) );
341 mpPathObj
->SetMergedItem( XFillStyleItem( drawing::FillStyle_NONE
) );
343 ::basegfx::B2DPolygon aStartArrow
;
344 aStartArrow
.append(::basegfx::B2DPoint(20.0, 0.0));
345 aStartArrow
.append(::basegfx::B2DPoint(0.0, 0.0));
346 aStartArrow
.append(::basegfx::B2DPoint(10.0, 30.0));
347 aStartArrow
.setClosed(true);
348 mpPathObj
->SetMergedItem(XLineStartItem(aEmpty
,::basegfx::B2DPolyPolygon(aStartArrow
)));
349 mpPathObj
->SetMergedItem(XLineStartWidthItem(400));
350 mpPathObj
->SetMergedItem(XLineStartCenterItem(true));
352 updatePathAttributes();
354 mpPathObj
->SetMergedItem(XLineTransparenceItem(50));
356 mpMark
.reset(new SdrMark( mpPathObj
.get(), mrView
.GetSdrPageView() ));
358 mpPathObj
->AddListener( *this );
360 Reference
< XChangesNotifier
> xNotifier( mpEffect
->getNode(), UNO_QUERY
);
363 xNotifier
->addChangesListener( this );
367 MotionPathTag::~MotionPathTag()
369 DBG_ASSERT( mpPathObj
== nullptr, "sd::MotionPathTag::~MotionPathTag(), dispose me first!" );
373 void MotionPathTag::updatePathAttributes()
375 ::basegfx::B2DPolygon aCandidate
;
376 if( mxPolyPoly
.count() )
378 aCandidate
= mxPolyPoly
.getB2DPolygon(0);
379 ::basegfx::utils::checkClosed( aCandidate
);
382 if( !aCandidate
.isClosed() )
384 ::basegfx::B2DPolygon aEndArrow
;
385 aEndArrow
.append(::basegfx::B2DPoint(10.0, 0.0));
386 aEndArrow
.append(::basegfx::B2DPoint(0.0, 30.0));
387 aEndArrow
.append(::basegfx::B2DPoint(20.0, 30.0));
388 aEndArrow
.setClosed(true);
389 mpPathObj
->SetMergedItem(XLineEndItem("?",::basegfx::B2DPolyPolygon(aEndArrow
)));
390 mpPathObj
->SetMergedItem(XLineEndWidthItem(400));
391 mpPathObj
->SetMergedItem(XLineEndCenterItem(true));
395 mpPathObj
->SetMergedItem(XLineEndItem());
399 void MotionPathTag::Notify( SfxBroadcaster
& /*rBC*/, const SfxHint
& rHint
)
401 if( !(mpPathObj
&& !mbInUpdatePath
&& rHint
.GetId() == SfxHintId::ThisIsAnSdrHint
&& mpEffect
) )
404 if( mxPolyPoly
!= mpPathObj
->GetPathPoly() )
406 mbInUpdatePath
= true;
407 mxPolyPoly
= mpPathObj
->GetPathPoly();
408 rtl::Reference
< MotionPathTag
> xTag( this );
409 mrPane
.updatePathFromMotionPathTag( xTag
);
410 msLastPath
= mpEffect
->getPath();
411 updatePathAttributes();
412 mbInUpdatePath
= false;
416 void MotionPathTag::MovePath( int nDX
, int nDY
)
420 mpPathObj
->Move( Size( nDX
, nDY
) );
421 mrView
.updateHandles();
425 /** returns true if the MotionPathTag handled the event. */
426 bool MotionPathTag::MouseButtonDown( const MouseEvent
& rMEvt
, SmartHdl
& rHdl
)
433 SmartTagReference
xTag( this );
434 mrView
.getSmartTags().select( xTag
);
440 if( rMEvt
.IsLeft() && (rMEvt
.GetClicks() == 2) )
442 mrView
.GetViewShell()->GetViewFrame()->GetDispatcher()->Execute(SID_BEZIER_EDIT
, SfxCallMode::ASYNCHRON
);
445 else if( rMEvt
.IsLeft() )
447 OutputDevice
* pOut
= mrView
.GetViewShell()->GetActiveWindow()->GetOutDev();
448 Point
aMDPos( pOut
->PixelToLogic( rMEvt
.GetPosPixel() ) );
450 if( !mrView
.IsFrameDragSingles() && mrView
.IsInsObjPointMode() && (rHdl
.GetObjHdlNum() == SMART_TAG_HDL_NUM
) )
452 // insert a point in edit mode
453 const bool bNewObj
= rMEvt
.IsMod1();
457 Point
aPt(aMDPos
); // - pMarkedPV->GetOffset());
460 aPt
= mrView
.GetSnapPos(aPt
,mrView
.GetSdrPageView());
462 bool bClosed0(mpPathObj
->IsClosedObj());
464 sal_uInt32 nInsPointNum
= mpPathObj
->NbcInsPointOld(aPt
, bNewObj
);
466 if(bClosed0
!= mpPathObj
->IsClosedObj())
468 // Obj was closed implicit
470 mpPathObj
->SetChanged();
471 mpPathObj
->BroadcastObjectChange();
474 if(0xffffffff != nInsPointNum
)
476 mrView
.UnmarkAllPoints();
477 mrView
.updateHandles();
479 bool bRet
= mrView
.BegDragObj(aMDPos
, pOut
, mrView
.GetHdl(nInsPointNum
+1), 0, new PathDragObjOwn( mrView
) );
483 const_cast< SdrDragStat
* >( &mrView
.GetDragStat() )->SetMinMoved();
484 mrView
.MovDragObj(aMDPos
);
491 SmartHdl
* pHdl
= &rHdl
;
492 if (!mrView
.IsPointMarked(*pHdl
) || rMEvt
.IsShift())
494 if (!rMEvt
.IsShift())
496 mrView
.UnmarkAllPoints();
497 pHdl
= dynamic_cast< SmartHdl
* >( mrView
.PickHandle(aMDPos
) );
501 if (mrView
.IsPointMarked(*pHdl
) )
503 mrView
.UnmarkPoint(*pHdl
);
508 pHdl
= dynamic_cast< SmartHdl
* >( mrView
.PickHandle(aMDPos
) );
513 mrView
.MarkPoint(*pHdl
);
516 if( pHdl
&& !rMEvt
.IsRight() )
519 const sal_uInt16 nDrgLog
= static_cast<sal_uInt16
>(pOut
->PixelToLogic(Size(DRGPIX
,0)).Width());
521 rtl::Reference
< MotionPathTag
> xTag( this );
522 SdrDragMethod
* pDragMethod
;
524 // #i95646# add DragPoly as geometry to each local SdrDragMethod to be able
525 // to create the needed local SdrDragEntry for it in createSdrDragEntries()
526 basegfx::B2DPolyPolygon
aDragPoly(mpPathObj
->GetPathPoly());
528 if( (pHdl
->GetKind() == SdrHdlKind::Move
) || (pHdl
->GetKind() == SdrHdlKind::SmartTag
) )
530 pDragMethod
= new PathDragMove( mrView
, xTag
, aDragPoly
);
531 pHdl
->SetPos( aMDPos
);
533 else if( pHdl
->GetKind() == SdrHdlKind::Poly
)
535 pDragMethod
= new PathDragObjOwn( mrView
, aDragPoly
);
539 pDragMethod
= new PathDragResize( mrView
, xTag
, std::move(aDragPoly
) );
542 mrView
.BegDragObj(aMDPos
, nullptr, pHdl
, nDrgLog
, pDragMethod
);
552 /** returns true if the SmartTag consumes this event. */
553 bool MotionPathTag::KeyInput( const KeyEvent
& rKEvt
)
558 sal_uInt16 nCode
= rKEvt
.GetKeyCode().GetCode();
568 return OnMove( rKEvt
);
572 SmartTagReference
xThis( this );
573 mrView
.getSmartTags().deselect();
578 return OnTabHandles( rKEvt
);
581 return OnMarkHandle( rKEvt
);
589 bool MotionPathTag::OnDelete()
591 mrPane
.remove( mpEffect
);
595 bool MotionPathTag::OnTabHandles( const KeyEvent
& rKEvt
)
597 if(rKEvt
.GetKeyCode().IsMod1() || rKEvt
.GetKeyCode().IsMod2())
599 const SdrHdlList
& rHdlList
= mrView
.GetHdlList();
600 bool bForward(!rKEvt
.GetKeyCode().IsShift());
602 const_cast<SdrHdlList
&>(rHdlList
).TravelFocusHdl(bForward
);
604 // guarantee visibility of focused handle
605 SdrHdl
* pHdl
= rHdlList
.GetFocusHdl();
609 Window
* pWindow
= mrView
.GetViewShell()->GetActiveWindow();
612 Point
aHdlPosition(pHdl
->GetPos());
613 ::tools::Rectangle
aVisRect(aHdlPosition
- Point(100, 100), Size(200, 200));
614 mrView
.MakeVisible(aVisRect
, *pWindow
);
624 bool MotionPathTag::OnMarkHandle( const KeyEvent
& rKEvt
)
626 const SdrHdlList
& rHdlList
= mrView
.GetHdlList();
627 SdrHdl
* pHdl
= rHdlList
.GetFocusHdl();
629 if(pHdl
&& pHdl
->GetKind() == SdrHdlKind::Poly
)
631 // rescue ID of point with focus
632 sal_uInt32
nPol(pHdl
->GetPolyNum());
633 sal_uInt32
nPnt(pHdl
->GetPointNum());
635 if(mrView
.IsPointMarked(*pHdl
))
637 if(rKEvt
.GetKeyCode().IsShift())
639 mrView
.UnmarkPoint(*pHdl
);
644 if(!rKEvt
.GetKeyCode().IsShift())
646 mrView
.UnmarkAllPoints();
648 mrView
.MarkPoint(*pHdl
);
651 if(nullptr == rHdlList
.GetFocusHdl())
653 // restore point with focus
654 SdrHdl
* pNewOne
= nullptr;
656 for(size_t a
= 0; !pNewOne
&& a
< rHdlList
.GetHdlCount(); ++a
)
658 SdrHdl
* pAct
= rHdlList
.GetHdl(a
);
660 if(pAct
&& pAct
->GetKind() == SdrHdlKind::Poly
&& pAct
->GetPolyNum() == nPol
&& pAct
->GetPointNum() == nPnt
)
665 const_cast<SdrHdlList
&>(rHdlList
).SetFocusHdl(pNewOne
);
672 bool MotionPathTag::OnMove( const KeyEvent
& rKEvt
)
674 ::tools::Long nX
= 0;
675 ::tools::Long nY
= 0;
677 switch( rKEvt
.GetKeyCode().GetCode() )
679 case KEY_UP
: nY
= -1; break;
680 case KEY_DOWN
: nY
= 1; break;
681 case KEY_LEFT
: nX
= -1; break;
682 case KEY_RIGHT
: nX
= 1; break;
686 if(rKEvt
.GetKeyCode().IsMod2())
688 OutputDevice
* pOut
= mrView
.GetViewShell()->GetActiveWindow()->GetOutDev();
689 Size aLogicSizeOnePixel
= pOut
? pOut
->PixelToLogic(Size(1,1)) : Size(100, 100);
690 nX
*= aLogicSizeOnePixel
.Width();
691 nY
*= aLogicSizeOnePixel
.Height();
695 // old, fixed move distance
702 // in point edit mode move the handle with the focus
703 const SdrHdlList
& rHdlList
= mrView
.GetHdlList();
704 SdrHdl
* pHdl
= rHdlList
.GetFocusHdl();
708 // now move the Handle (nX, nY)
709 Point
aStartPoint(pHdl
->GetPos());
710 Point
aEndPoint(pHdl
->GetPos() + Point(nX
, nY
));
713 rtl::Reference
< MotionPathTag
> xTag( this );
714 SdrDragMethod
* pDragMethod
= nullptr;
715 if( (pHdl
->GetKind() == SdrHdlKind::Move
) || (pHdl
->GetKind() == SdrHdlKind::SmartTag
) )
717 pDragMethod
= new PathDragMove( mrView
, xTag
);
719 else if( pHdl
->GetKind() == SdrHdlKind::Poly
)
721 pDragMethod
= new PathDragObjOwn( mrView
);
723 else if( pHdl
->GetKind() != SdrHdlKind::BezierWeight
)
725 pDragMethod
= new PathDragResize( mrView
, xTag
);
727 mrView
.BegDragObj(aStartPoint
, nullptr, pHdl
, 0, pDragMethod
);
729 if(mrView
.IsDragObj())
731 bool bWasNoSnap
= mrView
.GetDragStat().IsNoSnap();
732 bool bWasSnapEnabled
= mrView
.IsSnapEnabled();
734 // switch snapping off
736 const_cast<SdrDragStat
&>(mrView
.GetDragStat()).SetNoSnap();
738 mrView
.SetSnapEnabled(false);
740 mrView
.MovAction(aEndPoint
);
745 const_cast<SdrDragStat
&>(mrView
.GetDragStat()).SetNoSnap(bWasNoSnap
);
747 mrView
.SetSnapEnabled(bWasSnapEnabled
);
760 sal_Int32
MotionPathTag::GetMarkablePointCount() const
762 if( mpPathObj
&& isSelected() )
764 return mpPathObj
->GetPointCount();
772 sal_Int32
MotionPathTag::GetMarkedPointCount() const
776 const SdrUShortCont
& rPts
= mpMark
->GetMarkedPoints();
785 bool MotionPathTag::MarkPoint(SdrHdl
& rHdl
, bool bUnmark
)
788 if( mpPathObj
&& mrView
.IsPointMarkable( rHdl
) && (rHdl
.GetKind() != SdrHdlKind::SmartTag
) )
790 SmartHdl
* pSmartHdl
= dynamic_cast< SmartHdl
* >( &rHdl
);
791 if( pSmartHdl
&& pSmartHdl
->getTag().get() == this )
793 if (mrView
.MarkPointHelper(&rHdl
,mpMark
.get(),bUnmark
))
795 mrView
.MarkListHasChanged();
803 bool MotionPathTag::MarkPoints(const ::tools::Rectangle
* pRect
, bool bUnmark
)
807 if( mpPathObj
&& isSelected() )
809 size_t nHdlNum
= mrView
.GetHdlList().GetHdlCount();
813 while( --nHdlNum
> 0 )
815 SmartHdl
* pHdl
= dynamic_cast< SmartHdl
* >( mrView
.GetHdl( nHdlNum
) );
817 if( pHdl
&& (pHdl
->getTag().get() == this) && mrView
.IsPointMarkable(*pHdl
) && pHdl
->IsSelected() == bUnmark
)
819 Point
aPos(pHdl
->GetPos());
820 if( pRect
==nullptr || pRect
->Contains(aPos
))
822 if( mrView
.MarkPointHelper(pHdl
,mpMark
.get(),bUnmark
) )
829 mrView
.MarkListHasChanged();
835 bool MotionPathTag::getContext( SdrViewContext
& rContext
)
837 if( mpPathObj
&& isSelected() && !mrView
.IsFrameDragSingles() )
839 rContext
= SdrViewContext::PointEdit
;
848 void MotionPathTag::CheckPossibilities()
850 if( !(mpPathObj
&& isSelected()) )
853 mrView
.SetMoveAllowed( true );
854 mrView
.SetMoveProtected( false );
855 mrView
.SetResizeFreeAllowed( true );
856 mrView
.SetResizePropAllowed( true );
857 mrView
.SetResizeProtected( false );
859 if( !mrView
.IsFrameDragSingles() )
861 bool b1stSmooth(true);
864 bool bSmoothFuz(false);
865 bool bSegmFuz(false);
866 basegfx::B2VectorContinuity eSmooth
= basegfx::B2VectorContinuity::NONE
;
868 mrView
.CheckPolyPossibilitiesHelper( mpMark
.get(), b1stSmooth
, b1stSegm
, bCurve
, bSmoothFuz
, bSegmFuz
, eSmooth
);
872 void MotionPathTag::addCustomHandles( SdrHdlList
& rHandlerList
)
877 css::awt::Point aPos
;
879 aPos
= mxOrigin
->getPosition();
880 if( (aPos
.X
!= maOriginPos
.X
) || (aPos
.Y
!= maOriginPos
.Y
) )
882 const basegfx::B2DHomMatrix
aTransform(basegfx::utils::createTranslateB2DHomMatrix(
883 aPos
.X
- maOriginPos
.X
, aPos
.Y
- maOriginPos
.Y
));
884 mxPolyPoly
.transform( aTransform
);
885 mpPathObj
->SetPathPoly( mxPolyPoly
);
889 SmartTagReference
xThis( this );
890 std::unique_ptr
<SdPathHdl
> pHdl(new SdPathHdl( xThis
, mpPathObj
.get() ));
891 pHdl
->SetObjHdlNum( SMART_TAG_HDL_NUM
);
892 pHdl
->SetPageView( mrView
.GetSdrPageView() );
893 pHdl
->SetObj(mpPathObj
.get());
894 rHandlerList
.AddHdl( std::move(pHdl
) );
899 mrView
.GetSdrPageView()->SetHasMarkedObj(true);
901 if( !mrView
.IsFrameDragSingles() )
903 SdrHdlList
aTemp( rHandlerList
.GetView() );
904 mpPathObj
->AddToHdlList( aTemp
);
905 const SdrUShortCont
& rMrkPnts
= mpMark
->GetMarkedPoints();
907 for( size_t nHandle
= 0; nHandle
< aTemp
.GetHdlCount(); ++nHandle
)
909 SdrHdl
* pTempHdl
= aTemp
.GetHdl( nHandle
);
911 SmartHdl
* pSmartHdl
= new SmartHdl( xThis
, mpPathObj
.get(), pTempHdl
->GetPos(), pTempHdl
->GetKind() );
912 pSmartHdl
->SetObjHdlNum( static_cast<sal_uInt32
>(nHandle
) );
913 pSmartHdl
->SetPolyNum( pTempHdl
->GetPolyNum() );
914 pSmartHdl
->SetPointNum( pTempHdl
->GetPointNum() );
915 pSmartHdl
->SetPlusHdl( pTempHdl
->IsPlusHdl() );
916 pSmartHdl
->SetSourceHdlNum( pTempHdl
->GetSourceHdlNum() );
917 pSmartHdl
->SetPageView( mrView
.GetSdrPageView() );
919 rHandlerList
.AddHdl( std::unique_ptr
<SmartHdl
>(pSmartHdl
) );
921 const bool bSelected
= rMrkPnts
.find( sal_uInt16(nHandle
) ) != rMrkPnts
.end();
922 pSmartHdl
->SetSelected(bSelected
);
924 if( mrView
.IsPlusHandlesAlwaysVisible() || bSelected
)
926 SdrHdlList
plusList(nullptr);
927 mpPathObj
->AddToPlusHdlList(plusList
, *pSmartHdl
);
928 sal_uInt32 nPlusHdlCnt
=plusList
.GetHdlCount();
929 for (sal_uInt32 nPlusNum
=0; nPlusNum
<nPlusHdlCnt
; nPlusNum
++)
931 SdrHdl
* pPlusHdl
= plusList
.GetHdl(nPlusNum
);
932 pPlusHdl
->SetObj(mpPathObj
.get());
933 pPlusHdl
->SetPageView(mrView
.GetSdrPageView());
934 pPlusHdl
->SetPlusHdl(true);
936 plusList
.MoveTo(rHandlerList
);
942 ::tools::Rectangle
aRect(mpPathObj
->GetCurrentBoundRect());
946 size_t nCount
= rHandlerList
.GetHdlCount();
948 bool bWdt0
=aRect
.Left()==aRect
.Right();
949 bool bHgt0
=aRect
.Top()==aRect
.Bottom();
952 rHandlerList
.AddHdl(std::make_unique
<SmartHdl
>( xThis
, mpPathObj
.get(), aRect
.TopLeft(),SdrHdlKind::UpperLeft
));
954 else if (bWdt0
|| bHgt0
)
956 rHandlerList
.AddHdl(std::make_unique
<SmartHdl
>( xThis
, mpPathObj
.get(), aRect
.TopLeft() ,SdrHdlKind::UpperLeft
));
957 rHandlerList
.AddHdl(std::make_unique
<SmartHdl
>( xThis
, mpPathObj
.get(), aRect
.BottomRight(),SdrHdlKind::LowerRight
));
959 else // !bWdt0 && !bHgt0
961 rHandlerList
.AddHdl(std::make_unique
<SmartHdl
>( xThis
, mpPathObj
.get(), aRect
.TopLeft() ,SdrHdlKind::UpperLeft
));
962 rHandlerList
.AddHdl(std::make_unique
<SmartHdl
>( xThis
, mpPathObj
.get(), aRect
.TopCenter() ,SdrHdlKind::Upper
));
963 rHandlerList
.AddHdl(std::make_unique
<SmartHdl
>( xThis
, mpPathObj
.get(), aRect
.TopRight() ,SdrHdlKind::UpperRight
));
964 rHandlerList
.AddHdl(std::make_unique
<SmartHdl
>( xThis
, mpPathObj
.get(), aRect
.LeftCenter() ,SdrHdlKind::Left
));
965 rHandlerList
.AddHdl(std::make_unique
<SmartHdl
>( xThis
, mpPathObj
.get(), aRect
.RightCenter() ,SdrHdlKind::Right
));
966 rHandlerList
.AddHdl(std::make_unique
<SmartHdl
>( xThis
, mpPathObj
.get(), aRect
.BottomLeft() ,SdrHdlKind::LowerLeft
));
967 rHandlerList
.AddHdl(std::make_unique
<SmartHdl
>( xThis
, mpPathObj
.get(), aRect
.BottomCenter(),SdrHdlKind::Lower
));
968 rHandlerList
.AddHdl(std::make_unique
<SmartHdl
>( xThis
, mpPathObj
.get(), aRect
.BottomRight() ,SdrHdlKind::LowerRight
));
971 while( nCount
< rHandlerList
.GetHdlCount() )
973 rHandlerList
.GetHdl(nCount
++)->SetPageView( mrView
.GetSdrPageView() );
979 void MotionPathTag::disposing()
981 Reference
< XChangesNotifier
> xNotifier( mpEffect
->getNode(), UNO_QUERY
);
984 xNotifier
->removeChangesListener( this );
990 mrView
.updateHandles();
995 SmartTag::disposing();
998 void MotionPathTag::deselect()
1000 SmartTag::deselect();
1004 SdrUShortCont
& rPts
= mpMark
->GetMarkedPoints();
1011 void MotionPathTag::selectionChanged()
1013 if( mrView
.GetViewShell() && mrView
.GetViewShell()->GetViewFrame() )
1015 SfxBindings
& rBindings
= mrView
.GetViewShell()->GetViewFrame()->GetBindings();
1016 rBindings
.InvalidateAll(true);
1020 // IPolyPolygonEditorController
1022 void MotionPathTag::DeleteMarkedPoints()
1024 if( !(mpPathObj
&& IsDeleteMarkedPointsPossible()) )
1029 SdrUShortCont
& rPts
= mpMark
->GetMarkedPoints();
1030 PolyPolygonEditor
aEditor( mpPathObj
->GetPathPoly());
1031 if (aEditor
.DeletePoints(rPts
))
1033 if( aEditor
.GetPolyPolygon().count() )
1035 mpPathObj
->SetPathPoly( aEditor
.GetPolyPolygon() );
1038 mrView
.UnmarkAllPoints();
1039 mrView
.MarkListHasChanged();
1040 mrView
.updateHandles();
1044 bool MotionPathTag::IsDeleteMarkedPointsPossible() const
1046 return mpPathObj
&& isSelected() && (GetMarkedPointCount() != 0);
1049 void MotionPathTag::RipUpAtMarkedPoints()
1051 // not supported for motion path
1054 bool MotionPathTag::IsRipUpAtMarkedPointsPossible() const
1056 // not supported for motion path
1060 bool MotionPathTag::IsSetMarkedSegmentsKindPossible() const
1063 return mrView
.IsSetMarkedSegmentsKindPossible();
1068 SdrPathSegmentKind
MotionPathTag::GetMarkedSegmentsKind() const
1071 return mrView
.GetMarkedSegmentsKind();
1073 return SdrPathSegmentKind::Line
;
1076 void MotionPathTag::SetMarkedSegmentsKind(SdrPathSegmentKind eKind
)
1078 if(mpPathObj
&& isSelected() && (GetMarkedPointCount() != 0))
1080 SdrUShortCont
& rPts
= mpMark
->GetMarkedPoints();
1081 PolyPolygonEditor
aEditor( mpPathObj
->GetPathPoly() );
1082 if (aEditor
.SetSegmentsKind(eKind
, rPts
))
1084 mpPathObj
->SetPathPoly(aEditor
.GetPolyPolygon());
1085 mrView
.MarkListHasChanged();
1086 mrView
.updateHandles();
1091 bool MotionPathTag::IsSetMarkedPointsSmoothPossible() const
1094 return mrView
.IsSetMarkedPointsSmoothPossible();
1099 SdrPathSmoothKind
MotionPathTag::GetMarkedPointsSmooth() const
1102 return mrView
.GetMarkedPointsSmooth();
1104 return SdrPathSmoothKind::Angular
;
1107 void MotionPathTag::SetMarkedPointsSmooth(SdrPathSmoothKind eKind
)
1109 basegfx::B2VectorContinuity eFlags
;
1111 if(SdrPathSmoothKind::Angular
== eKind
)
1113 eFlags
= basegfx::B2VectorContinuity::NONE
;
1115 else if(SdrPathSmoothKind::Asymmetric
== eKind
)
1117 eFlags
= basegfx::B2VectorContinuity::C1
;
1119 else if(SdrPathSmoothKind::Symmetric
== eKind
)
1121 eFlags
= basegfx::B2VectorContinuity::C2
;
1128 if(mpPathObj
&& mpMark
&& isSelected() && (GetMarkedPointCount() != 0))
1130 SdrUShortCont
& rPts
= mpMark
->GetMarkedPoints();
1131 PolyPolygonEditor
aEditor( mpPathObj
->GetPathPoly());
1132 if (aEditor
.SetPointsSmooth(eFlags
, rPts
))
1134 mpPathObj
->SetPathPoly(aEditor
.GetPolyPolygon());
1135 mrView
.MarkListHasChanged();
1136 mrView
.updateHandles();
1141 bool MotionPathTag::IsOpenCloseMarkedObjectsPossible() const
1143 // not supported for motion path
1147 SdrObjClosedKind
MotionPathTag::GetMarkedObjectsClosedState() const
1149 // not supported for motion path
1150 return SdrObjClosedKind::Open
;
1154 void SAL_CALL
MotionPathTag::changesOccurred( const ChangesEvent
& /*Event*/ )
1156 if( mpPathObj
&& !mbInUpdatePath
&& (mpEffect
->getPath() != msLastPath
) )
1158 mbInUpdatePath
=true;
1159 msLastPath
= mpEffect
->getPath();
1160 mpEffect
->updateSdrPathObjFromPath( *mpPathObj
);
1161 mbInUpdatePath
= false;
1162 updatePathAttributes();
1163 mrView
.updateHandles();
1167 void SAL_CALL
MotionPathTag::disposing( const EventObject
& /*Source*/ )
1173 Any SAL_CALL
MotionPathTag::queryInterface( const css::uno::Type
& aType
)
1175 if( aType
== cppu::UnoType
<XChangesListener
>::get() )
1176 return Any( Reference
< XChangesListener
>( this ) );
1177 if( aType
== cppu::UnoType
<XEventListener
>::get() )
1178 return Any( Reference
< XEventListener
>( this ) );
1179 if( aType
== cppu::UnoType
<XInterface
>::get() )
1180 return Any( Reference
< XInterface
>( this ) );
1185 void SAL_CALL
MotionPathTag::acquire() noexcept
1187 SimpleReferenceComponent::acquire();
1190 void SAL_CALL
MotionPathTag::release( ) noexcept
1192 SimpleReferenceComponent::release();
1195 } // end of namespace sd
1197 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */