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"
42 #include "res_bmp.hrc"
43 #include <basegfx/polygon/b2dpolygon.hxx>
44 #include <basegfx/polygon/b2dpolygontools.hxx>
46 #include "CustomAnimationEffect.hxx"
48 using namespace ::com::sun::star::uno
;
52 TYPEINIT1( FuConstructBezierPolygon
, FuConstruct
);
54 FuConstructBezierPolygon::FuConstructBezierPolygon (
60 : FuConstruct(pViewSh
, pWin
, pView
, pDoc
, rReq
),
61 nEditMode(SID_BEZIER_MOVE
)
65 rtl::Reference
<FuPoor
> FuConstructBezierPolygon::Create( ViewShell
* pViewSh
, ::sd::Window
* pWin
, ::sd::View
* pView
, SdDrawDocument
* pDoc
, SfxRequest
& rReq
, bool bPermanent
)
67 FuConstructBezierPolygon
* pFunc
;
68 rtl::Reference
<FuPoor
> xFunc( pFunc
= new FuConstructBezierPolygon( pViewSh
, pWin
, pView
, pDoc
, rReq
) );
69 xFunc
->DoExecute(rReq
);
70 pFunc
->SetPermanent(bPermanent
);
74 void FuConstructBezierPolygon::DoExecute( SfxRequest
& rReq
)
76 FuConstruct::DoExecute( rReq
);
78 const SfxItemSet
* pArgs
= rReq
.GetArgs();
81 const SfxPoolItem
* pPoolItem
= NULL
;
82 if( SfxItemState::SET
== pArgs
->GetItemState( SID_ADD_MOTION_PATH
, true, &pPoolItem
) )
83 maTargets
= static_cast<const SfxUnoAnyItem
*>( pPoolItem
)->GetValue();
87 bool FuConstructBezierPolygon::MouseButtonDown(const MouseEvent
& rMEvt
)
89 bool bReturn
= FuConstruct::MouseButtonDown(rMEvt
);
92 SdrHitKind eHit
= mpView
->PickAnything(rMEvt
, SdrMouseEventKind::BUTTONDOWN
, aVEvt
);
94 if (eHit
== SDRHIT_HANDLE
|| rMEvt
.IsMod1())
96 mpView
->SetEditMode(SDREDITMODE_EDIT
);
100 mpView
->SetEditMode(SDREDITMODE_CREATE
);
103 if (aVEvt
.eEvent
== SDREVENT_BEGTEXTEDIT
)
105 // here, we do not allow text input
106 aVEvt
.eEvent
= SDREVENT_BEGDRAGOBJ
;
107 mpView
->EnableExtendedMouseEventDispatcher(false);
111 mpView
->EnableExtendedMouseEventDispatcher(true);
114 if (eHit
== SDRHIT_MARKEDOBJECT
&& nEditMode
== SID_BEZIER_INSERT
)
117 mpView
->BegInsObjPoint(aMDPos
, rMEvt
.IsMod1());
121 mpView
->MouseButtonDown(rMEvt
, mpWindow
);
123 SdrObject
* pObj
= mpView
->GetCreateObj();
127 SfxItemSet
aAttr(mpDoc
->GetPool());
128 SetStyleSheet(aAttr
, pObj
);
129 pObj
->SetMergedItemSet(aAttr
);
136 bool FuConstructBezierPolygon::MouseMove(const MouseEvent
& rMEvt
)
138 return FuConstruct::MouseMove(rMEvt
);
141 bool FuConstructBezierPolygon::MouseButtonUp(const MouseEvent
& rMEvt
)
143 bool bReturn
= false;
144 bool bCreated
= false;
147 mpView
->PickAnything(rMEvt
, SdrMouseEventKind::BUTTONUP
, aVEvt
);
149 const size_t nCount
= mpView
->GetSdrPageView()->GetObjList()->GetObjCount();
151 if (mpView
->IsInsObjPoint())
153 mpView
->EndInsObjPoint(SDRCREATE_FORCEEND
);
157 mpView
->MouseButtonUp(rMEvt
, mpWindow
);
160 if (aVEvt
.eEvent
== SDREVENT_ENDCREATE
)
164 if (nCount
+1 == mpView
->GetSdrPageView()->GetObjList()->GetObjCount())
169 // trick to suppress FuDraw::DoubleClick
174 bReturn
= FuConstruct::MouseButtonUp(rMEvt
) || bReturn
;
176 bool bDeleted
= false;
177 if( bCreated
&& maTargets
.hasValue() )
179 SdrPathObj
* pPathObj
= dynamic_cast< SdrPathObj
* >( mpView
->GetSdrPageView()->GetObjList()->GetObj( nCount
) );
180 SdPage
* pPage
= dynamic_cast< SdPage
* >( pPathObj
? pPathObj
->GetPage() : 0 );
183 boost::shared_ptr
< sd::MainSequence
> pMainSequence( pPage
->getMainSequence() );
184 if( pMainSequence
.get() )
186 Sequence
< Any
> aTargets
;
187 maTargets
>>= aTargets
;
189 sal_Int32 nTCount
= aTargets
.getLength();
192 const Any
* pTarget
= aTargets
.getConstArray();
193 double fDuration
= 0.0;
194 *pTarget
++ >>= fDuration
;
198 CustomAnimationEffectPtr
pCreated( pMainSequence
->append( *pPathObj
, *pTarget
++, fDuration
) );
202 pCreated
->setNodeType( ::com::sun::star::presentation::EffectNodeType::WITH_PREVIOUS
);
207 mpView
->DeleteMarked();
211 if ((!bPermanent
&& bCreated
) || bDeleted
)
213 mpViewShell
->GetViewFrame()->GetDispatcher()->Execute(SID_OBJECT_SELECT
, SfxCallMode::ASYNCHRON
);
220 * Process keyboard input
221 * @returns sal_True if a KeyEvent is being processed, sal_False otherwise
223 bool FuConstructBezierPolygon::KeyInput(const KeyEvent
& rKEvt
)
225 return FuConstruct::KeyInput(rKEvt
);
228 void FuConstructBezierPolygon::Activate()
230 mpView
->EnableExtendedMouseEventDispatcher(true);
236 case SID_DRAW_POLYGON_NOFILL
:
237 case SID_DRAW_XPOLYGON_NOFILL
:
243 case SID_DRAW_POLYGON
:
244 case SID_DRAW_XPOLYGON
:
250 case SID_DRAW_BEZIER_NOFILL
:
252 eKind
= OBJ_PATHLINE
;
256 case SID_DRAW_BEZIER_FILL
:
258 eKind
= OBJ_PATHFILL
;
262 case SID_DRAW_FREELINE_NOFILL
:
264 eKind
= OBJ_FREELINE
;
268 case SID_DRAW_FREELINE
:
270 eKind
= OBJ_FREEFILL
;
276 eKind
= OBJ_PATHLINE
;
281 mpView
->SetCurrentObj((sal_uInt16
)eKind
);
283 FuConstruct::Activate();
286 void FuConstructBezierPolygon::Deactivate()
288 mpView
->EnableExtendedMouseEventDispatcher(false);
290 FuConstruct::Deactivate();
293 void FuConstructBezierPolygon::SelectionHasChanged()
295 FuDraw::SelectionHasChanged();
297 mpViewShell
->GetViewShellBase().GetToolBarManager()->SelectionHasChanged(
303 * Set current bezier edit mode
305 void FuConstructBezierPolygon::SetEditMode(sal_uInt16 nMode
)
310 SfxBindings
& rBindings
= mpViewShell
->GetViewFrame()->GetBindings();
311 rBindings
.Invalidate(SID_BEZIER_MOVE
);
312 rBindings
.Invalidate(SID_BEZIER_INSERT
);
315 SdrObject
* FuConstructBezierPolygon::CreateDefaultObject(const sal_uInt16 nID
, const Rectangle
& rRectangle
)
317 // case SID_DRAW_POLYGON:
318 // case SID_DRAW_POLYGON_NOFILL:
319 // case SID_DRAW_XPOLYGON:
320 // case SID_DRAW_XPOLYGON_NOFILL:
321 // case SID_DRAW_FREELINE:
322 // case SID_DRAW_FREELINE_NOFILL:
323 // case SID_DRAW_BEZIER_FILL: // BASIC
324 // case SID_DRAW_BEZIER_NOFILL: // BASIC
326 SdrObject
* pObj
= SdrObjFactory::MakeNewObject(
327 mpView
->GetCurrentObjInventor(), mpView
->GetCurrentObjIdentifier(),
332 if(pObj
->ISA(SdrPathObj
))
334 basegfx::B2DPolyPolygon aPoly
;
338 case SID_DRAW_BEZIER_FILL
:
340 const sal_Int32
nWdt(rRectangle
.GetWidth() / 2);
341 const sal_Int32
nHgt(rRectangle
.GetHeight() / 2);
342 const basegfx::B2DPolygon
aInnerPoly(basegfx::tools::createPolygonFromEllipse(basegfx::B2DPoint(rRectangle
.Center().X(), rRectangle
.Center().Y()), nWdt
, nHgt
));
344 aPoly
.append(aInnerPoly
);
347 case SID_DRAW_BEZIER_NOFILL
:
349 basegfx::B2DPolygon aInnerPoly
;
351 aInnerPoly
.append(basegfx::B2DPoint(rRectangle
.Left(), rRectangle
.Bottom()));
353 const basegfx::B2DPoint
aCenterBottom(rRectangle
.Center().X(), rRectangle
.Bottom());
354 aInnerPoly
.appendBezierSegment(
357 basegfx::B2DPoint(rRectangle
.Center().X(), rRectangle
.Center().Y()));
359 const basegfx::B2DPoint
aCenterTop(rRectangle
.Center().X(), rRectangle
.Top());
360 aInnerPoly
.appendBezierSegment(
363 basegfx::B2DPoint(rRectangle
.Right(), rRectangle
.Top()));
365 aPoly
.append(aInnerPoly
);
368 case SID_DRAW_FREELINE
:
369 case SID_DRAW_FREELINE_NOFILL
:
371 basegfx::B2DPolygon aInnerPoly
;
373 aInnerPoly
.append(basegfx::B2DPoint(rRectangle
.Left(), rRectangle
.Bottom()));
375 aInnerPoly
.appendBezierSegment(
376 basegfx::B2DPoint(rRectangle
.Left(), rRectangle
.Top()),
377 basegfx::B2DPoint(rRectangle
.Center().X(), rRectangle
.Top()),
378 basegfx::B2DPoint(rRectangle
.Center().X(), rRectangle
.Center().Y()));
380 aInnerPoly
.appendBezierSegment(
381 basegfx::B2DPoint(rRectangle
.Center().X(), rRectangle
.Bottom()),
382 basegfx::B2DPoint(rRectangle
.Right(), rRectangle
.Bottom()),
383 basegfx::B2DPoint(rRectangle
.Right(), rRectangle
.Top()));
385 if(SID_DRAW_FREELINE
== nID
)
387 aInnerPoly
.append(basegfx::B2DPoint(rRectangle
.Right(), rRectangle
.Bottom()));
391 aInnerPoly
.setClosed(true);
394 aPoly
.append(aInnerPoly
);
397 case SID_DRAW_XPOLYGON
:
398 case SID_DRAW_XPOLYGON_NOFILL
:
400 basegfx::B2DPolygon aInnerPoly
;
402 aInnerPoly
.append(basegfx::B2DPoint(rRectangle
.Left(), rRectangle
.Bottom()));
403 aInnerPoly
.append(basegfx::B2DPoint(rRectangle
.Left(), rRectangle
.Top()));
404 aInnerPoly
.append(basegfx::B2DPoint(rRectangle
.Center().X(), rRectangle
.Top()));
405 aInnerPoly
.append(basegfx::B2DPoint(rRectangle
.Center().X(), rRectangle
.Center().Y()));
406 aInnerPoly
.append(basegfx::B2DPoint(rRectangle
.Right(), rRectangle
.Center().Y()));
407 aInnerPoly
.append(basegfx::B2DPoint(rRectangle
.Right(), rRectangle
.Bottom()));
409 if(SID_DRAW_XPOLYGON_NOFILL
== nID
)
411 aInnerPoly
.append(basegfx::B2DPoint(rRectangle
.Center().X(), rRectangle
.Bottom()));
415 aInnerPoly
.setClosed(true);
418 aPoly
.append(aInnerPoly
);
421 case SID_DRAW_POLYGON
:
422 case SID_DRAW_POLYGON_NOFILL
:
424 basegfx::B2DPolygon aInnerPoly
;
425 const sal_Int32
nWdt(rRectangle
.GetWidth());
426 const sal_Int32
nHgt(rRectangle
.GetHeight());
428 aInnerPoly
.append(basegfx::B2DPoint(rRectangle
.Left(), rRectangle
.Bottom()));
429 aInnerPoly
.append(basegfx::B2DPoint(rRectangle
.Left() + (nWdt
* 30) / 100, rRectangle
.Top() + (nHgt
* 70) / 100));
430 aInnerPoly
.append(basegfx::B2DPoint(rRectangle
.Left(), rRectangle
.Top() + (nHgt
* 15) / 100));
431 aInnerPoly
.append(basegfx::B2DPoint(rRectangle
.Left() + (nWdt
* 65) / 100, rRectangle
.Top()));
432 aInnerPoly
.append(basegfx::B2DPoint(rRectangle
.Left() + nWdt
, rRectangle
.Top() + (nHgt
* 30) / 100));
433 aInnerPoly
.append(basegfx::B2DPoint(rRectangle
.Left() + (nWdt
* 80) / 100, rRectangle
.Top() + (nHgt
* 50) / 100));
434 aInnerPoly
.append(basegfx::B2DPoint(rRectangle
.Left() + (nWdt
* 80) / 100, rRectangle
.Top() + (nHgt
* 75) / 100));
435 aInnerPoly
.append(basegfx::B2DPoint(rRectangle
.Bottom(), rRectangle
.Right()));
437 if(SID_DRAW_POLYGON_NOFILL
== nID
)
439 aInnerPoly
.append(basegfx::B2DPoint(rRectangle
.Center().X(), rRectangle
.Bottom()));
443 aInnerPoly
.setClosed(true);
446 aPoly
.append(aInnerPoly
);
451 static_cast<SdrPathObj
*>(pObj
)->SetPathPoly(aPoly
);
455 OSL_FAIL("Object is NO path object");
458 pObj
->SetLogicRect(rRectangle
);
464 } // end of namespace sd
466 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */