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/presentation/EffectNodeType.hpp>
22 #include <fuconbez.hxx>
23 #include <svl/aeitem.hxx>
24 #include <svx/svdopath.hxx>
25 #include <svl/intitem.hxx>
26 #include <sfx2/dispatch.hxx>
27 #include <svx/svdobj.hxx>
28 #include <sfx2/bindings.hxx>
29 #include <sfx2/request.hxx>
30 #include <sfx2/viewfrm.hxx>
32 #include <svx/svxids.hrc>
33 #include <svx/svdpagv.hxx>
36 #include <ViewShell.hxx>
37 #include <ViewShellBase.hxx>
40 #include <ToolBarManager.hxx>
41 #include <drawdoc.hxx>
43 #include <basegfx/polygon/b2dpolygon.hxx>
44 #include <basegfx/polygon/b2dpolygontools.hxx>
46 #include <CustomAnimationEffect.hxx>
48 using namespace ::com::sun::star::uno
;
53 FuConstructBezierPolygon::FuConstructBezierPolygon (
59 : FuConstruct(pViewSh
, pWin
, pView
, pDoc
, rReq
),
60 nEditMode(SID_BEZIER_MOVE
)
64 rtl::Reference
<FuPoor
> FuConstructBezierPolygon::Create( ViewShell
* pViewSh
, ::sd::Window
* pWin
, ::sd::View
* pView
, SdDrawDocument
* pDoc
, SfxRequest
& rReq
, bool bPermanent
)
66 FuConstructBezierPolygon
* pFunc
;
67 rtl::Reference
<FuPoor
> xFunc( pFunc
= new FuConstructBezierPolygon( pViewSh
, pWin
, pView
, pDoc
, rReq
) );
68 xFunc
->DoExecute(rReq
);
69 pFunc
->SetPermanent(bPermanent
);
73 void FuConstructBezierPolygon::DoExecute( SfxRequest
& rReq
)
75 FuConstruct::DoExecute( rReq
);
77 const SfxItemSet
* pArgs
= rReq
.GetArgs();
80 const SfxPoolItem
* pPoolItem
= nullptr;
81 if( SfxItemState::SET
== pArgs
->GetItemState( SID_ADD_MOTION_PATH
, true, &pPoolItem
) )
82 maTargets
= static_cast<const SfxUnoAnyItem
*>( pPoolItem
)->GetValue();
86 bool FuConstructBezierPolygon::MouseButtonDown(const MouseEvent
& rMEvt
)
88 bool bReturn
= FuConstruct::MouseButtonDown(rMEvt
);
91 SdrHitKind eHit
= mpView
->PickAnything(rMEvt
, SdrMouseEventKind::BUTTONDOWN
, aVEvt
);
93 if (eHit
== SdrHitKind::Handle
|| rMEvt
.IsMod1())
95 mpView
->SetEditMode(SdrViewEditMode::Edit
);
99 mpView
->SetEditMode(SdrViewEditMode::Create
);
102 if (aVEvt
.eEvent
== SdrEventKind::BeginTextEdit
)
104 // here, we do not allow text input
105 aVEvt
.eEvent
= SdrEventKind::BeginDragObj
;
106 mpView
->EnableExtendedMouseEventDispatcher(false);
110 mpView
->EnableExtendedMouseEventDispatcher(true);
113 if (eHit
== SdrHitKind::MarkedObject
&& nEditMode
== SID_BEZIER_INSERT
)
116 mpView
->BegInsObjPoint(aMDPos
, rMEvt
.IsMod1());
120 mpView
->MouseButtonDown(rMEvt
, mpWindow
);
122 SdrObject
* pObj
= mpView
->GetCreateObj();
126 SfxItemSet
aAttr(mpDoc
->GetPool());
127 SetStyleSheet(aAttr
, pObj
);
128 pObj
->SetMergedItemSet(aAttr
);
135 bool FuConstructBezierPolygon::MouseButtonUp(const MouseEvent
& rMEvt
)
137 bool bReturn
= false;
138 bool bCreated
= false;
141 mpView
->PickAnything(rMEvt
, SdrMouseEventKind::BUTTONUP
, aVEvt
);
143 const size_t nCount
= mpView
->GetSdrPageView()->GetObjList()->GetObjCount();
145 if (mpView
->IsInsObjPoint())
147 mpView
->EndInsObjPoint(SdrCreateCmd::ForceEnd
);
151 mpView
->MouseButtonUp(rMEvt
, mpWindow
);
154 if (aVEvt
.eEvent
== SdrEventKind::EndCreate
)
158 if (nCount
+1 == mpView
->GetSdrPageView()->GetObjList()->GetObjCount())
163 // trick to suppress FuDraw::DoubleClick
168 bReturn
= FuConstruct::MouseButtonUp(rMEvt
) || bReturn
;
170 bool bDeleted
= false;
171 if( bCreated
&& maTargets
.hasValue() )
173 SdrPathObj
* pPathObj
= dynamic_cast< SdrPathObj
* >( mpView
->GetSdrPageView()->GetObjList()->GetObj( nCount
) );
174 SdPage
* pPage
= dynamic_cast< SdPage
* >( pPathObj
? pPathObj
->GetPage() : nullptr );
177 std::shared_ptr
< sd::MainSequence
> pMainSequence( pPage
->getMainSequence() );
178 if( pMainSequence
.get() )
180 Sequence
< Any
> aTargets
;
181 maTargets
>>= aTargets
;
183 sal_Int32 nTCount
= aTargets
.getLength();
186 const Any
* pTarget
= aTargets
.getConstArray();
187 double fDuration
= 0.0;
188 *pTarget
++ >>= fDuration
;
192 CustomAnimationEffectPtr
pCreated( pMainSequence
->append( *pPathObj
, *pTarget
++, fDuration
) );
196 pCreated
->setNodeType( css::presentation::EffectNodeType::WITH_PREVIOUS
);
201 mpView
->DeleteMarked();
205 if ((!bPermanent
&& bCreated
) || bDeleted
)
207 mpViewShell
->GetViewFrame()->GetDispatcher()->Execute(SID_OBJECT_SELECT
, SfxCallMode::ASYNCHRON
);
213 void FuConstructBezierPolygon::Activate()
215 mpView
->EnableExtendedMouseEventDispatcher(true);
221 case SID_DRAW_POLYGON_NOFILL
:
222 case SID_DRAW_XPOLYGON_NOFILL
:
228 case SID_DRAW_POLYGON
:
229 case SID_DRAW_XPOLYGON
:
235 case SID_DRAW_BEZIER_NOFILL
:
237 eKind
= OBJ_PATHLINE
;
241 case SID_DRAW_BEZIER_FILL
:
243 eKind
= OBJ_PATHFILL
;
247 case SID_DRAW_FREELINE_NOFILL
:
249 eKind
= OBJ_FREELINE
;
253 case SID_DRAW_FREELINE
:
255 eKind
= OBJ_FREEFILL
;
261 eKind
= OBJ_PATHLINE
;
266 mpView
->SetCurrentObj(static_cast<sal_uInt16
>(eKind
));
268 FuConstruct::Activate();
271 void FuConstructBezierPolygon::Deactivate()
273 mpView
->EnableExtendedMouseEventDispatcher(false);
275 FuConstruct::Deactivate();
278 void FuConstructBezierPolygon::SelectionHasChanged()
280 FuDraw::SelectionHasChanged();
282 mpViewShell
->GetViewShellBase().GetToolBarManager()->SelectionHasChanged(
288 * Set current bezier edit mode
290 void FuConstructBezierPolygon::SetEditMode(sal_uInt16 nMode
)
295 SfxBindings
& rBindings
= mpViewShell
->GetViewFrame()->GetBindings();
296 rBindings
.Invalidate(SID_BEZIER_MOVE
);
297 rBindings
.Invalidate(SID_BEZIER_INSERT
);
300 SdrObject
* FuConstructBezierPolygon::CreateDefaultObject(const sal_uInt16 nID
, const ::tools::Rectangle
& rRectangle
)
302 // case SID_DRAW_POLYGON:
303 // case SID_DRAW_POLYGON_NOFILL:
304 // case SID_DRAW_XPOLYGON:
305 // case SID_DRAW_XPOLYGON_NOFILL:
306 // case SID_DRAW_FREELINE:
307 // case SID_DRAW_FREELINE_NOFILL:
308 // case SID_DRAW_BEZIER_FILL: // BASIC
309 // case SID_DRAW_BEZIER_NOFILL: // BASIC
311 SdrObject
* pObj
= SdrObjFactory::MakeNewObject(
312 mpView
->getSdrModelFromSdrView(),
313 mpView
->GetCurrentObjInventor(),
314 mpView
->GetCurrentObjIdentifier());
318 if( dynamic_cast< const SdrPathObj
*>( pObj
) != nullptr)
320 basegfx::B2DPolyPolygon aPoly
;
324 case SID_DRAW_BEZIER_FILL
:
326 const sal_Int32
nWdt(rRectangle
.GetWidth() / 2);
327 const sal_Int32
nHgt(rRectangle
.GetHeight() / 2);
328 const basegfx::B2DPolygon
aInnerPoly(basegfx::utils::createPolygonFromEllipse(basegfx::B2DPoint(rRectangle
.Center().X(), rRectangle
.Center().Y()), nWdt
, nHgt
));
330 aPoly
.append(aInnerPoly
);
333 case SID_DRAW_BEZIER_NOFILL
:
335 basegfx::B2DPolygon aInnerPoly
;
337 aInnerPoly
.append(basegfx::B2DPoint(rRectangle
.Left(), rRectangle
.Bottom()));
339 const basegfx::B2DPoint
aCenterBottom(rRectangle
.Center().X(), rRectangle
.Bottom());
340 aInnerPoly
.appendBezierSegment(
343 basegfx::B2DPoint(rRectangle
.Center().X(), rRectangle
.Center().Y()));
345 const basegfx::B2DPoint
aCenterTop(rRectangle
.Center().X(), rRectangle
.Top());
346 aInnerPoly
.appendBezierSegment(
349 basegfx::B2DPoint(rRectangle
.Right(), rRectangle
.Top()));
351 aPoly
.append(aInnerPoly
);
354 case SID_DRAW_FREELINE
:
355 case SID_DRAW_FREELINE_NOFILL
:
357 basegfx::B2DPolygon aInnerPoly
;
359 aInnerPoly
.append(basegfx::B2DPoint(rRectangle
.Left(), rRectangle
.Bottom()));
361 aInnerPoly
.appendBezierSegment(
362 basegfx::B2DPoint(rRectangle
.Left(), rRectangle
.Top()),
363 basegfx::B2DPoint(rRectangle
.Center().X(), rRectangle
.Top()),
364 basegfx::B2DPoint(rRectangle
.Center().X(), rRectangle
.Center().Y()));
366 aInnerPoly
.appendBezierSegment(
367 basegfx::B2DPoint(rRectangle
.Center().X(), rRectangle
.Bottom()),
368 basegfx::B2DPoint(rRectangle
.Right(), rRectangle
.Bottom()),
369 basegfx::B2DPoint(rRectangle
.Right(), rRectangle
.Top()));
371 if(SID_DRAW_FREELINE
== nID
)
373 aInnerPoly
.append(basegfx::B2DPoint(rRectangle
.Right(), rRectangle
.Bottom()));
377 aInnerPoly
.setClosed(true);
380 aPoly
.append(aInnerPoly
);
383 case SID_DRAW_XPOLYGON
:
384 case SID_DRAW_XPOLYGON_NOFILL
:
386 basegfx::B2DPolygon aInnerPoly
;
388 aInnerPoly
.append(basegfx::B2DPoint(rRectangle
.Left(), rRectangle
.Bottom()));
389 aInnerPoly
.append(basegfx::B2DPoint(rRectangle
.Left(), rRectangle
.Top()));
390 aInnerPoly
.append(basegfx::B2DPoint(rRectangle
.Center().X(), rRectangle
.Top()));
391 aInnerPoly
.append(basegfx::B2DPoint(rRectangle
.Center().X(), rRectangle
.Center().Y()));
392 aInnerPoly
.append(basegfx::B2DPoint(rRectangle
.Right(), rRectangle
.Center().Y()));
393 aInnerPoly
.append(basegfx::B2DPoint(rRectangle
.Right(), rRectangle
.Bottom()));
395 if(SID_DRAW_XPOLYGON_NOFILL
== nID
)
397 aInnerPoly
.append(basegfx::B2DPoint(rRectangle
.Center().X(), rRectangle
.Bottom()));
401 aInnerPoly
.setClosed(true);
404 aPoly
.append(aInnerPoly
);
407 case SID_DRAW_POLYGON
:
408 case SID_DRAW_POLYGON_NOFILL
:
410 basegfx::B2DPolygon aInnerPoly
;
411 const sal_Int32
nWdt(rRectangle
.GetWidth());
412 const sal_Int32
nHgt(rRectangle
.GetHeight());
414 aInnerPoly
.append(basegfx::B2DPoint(rRectangle
.Left(), rRectangle
.Bottom()));
415 aInnerPoly
.append(basegfx::B2DPoint(rRectangle
.Left() + (nWdt
* 30) / 100, rRectangle
.Top() + (nHgt
* 70) / 100));
416 aInnerPoly
.append(basegfx::B2DPoint(rRectangle
.Left(), rRectangle
.Top() + (nHgt
* 15) / 100));
417 aInnerPoly
.append(basegfx::B2DPoint(rRectangle
.Left() + (nWdt
* 65) / 100, rRectangle
.Top()));
418 aInnerPoly
.append(basegfx::B2DPoint(rRectangle
.Left() + nWdt
, rRectangle
.Top() + (nHgt
* 30) / 100));
419 aInnerPoly
.append(basegfx::B2DPoint(rRectangle
.Left() + (nWdt
* 80) / 100, rRectangle
.Top() + (nHgt
* 50) / 100));
420 aInnerPoly
.append(basegfx::B2DPoint(rRectangle
.Left() + (nWdt
* 80) / 100, rRectangle
.Top() + (nHgt
* 75) / 100));
421 aInnerPoly
.append(basegfx::B2DPoint(rRectangle
.Bottom(), rRectangle
.Right()));
423 if(SID_DRAW_POLYGON_NOFILL
== nID
)
425 aInnerPoly
.append(basegfx::B2DPoint(rRectangle
.Center().X(), rRectangle
.Bottom()));
429 aInnerPoly
.setClosed(true);
432 aPoly
.append(aInnerPoly
);
437 static_cast<SdrPathObj
*>(pObj
)->SetPathPoly(aPoly
);
441 OSL_FAIL("Object is NO path object");
444 pObj
->SetLogicRect(rRectangle
);
450 } // end of namespace sd
452 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */