bump product version to 6.3.0.0.beta1
[LibreOffice.git] / sd / source / ui / func / fuconbez.cxx
blobb95d2c2bb7042c57ae4e409a1d71fc1aa8bdc9de
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 <svx/svdopath.hxx>
24 #include <svl/intitem.hxx>
25 #include <sfx2/dispatch.hxx>
26 #include <svx/svdobj.hxx>
27 #include <sfx2/bindings.hxx>
28 #include <sfx2/request.hxx>
29 #include <sfx2/viewfrm.hxx>
31 #include <svx/svxids.hrc>
32 #include <svx/svdpagv.hxx>
33 #include <svx/xlnclit.hxx>
34 #include <svx/xlntrit.hxx>
35 #include <svx/xlnwtit.hxx>
37 #include <app.hrc>
38 #include <ViewShell.hxx>
39 #include <ViewShellBase.hxx>
40 #include <View.hxx>
41 #include <Window.hxx>
42 #include <ToolBarManager.hxx>
43 #include <drawdoc.hxx>
44 #include <sdpage.hxx>
46 #include <basegfx/polygon/b2dpolygon.hxx>
47 #include <basegfx/polygon/b2dpolygontools.hxx>
49 #include <CustomAnimationEffect.hxx>
51 using namespace ::com::sun::star::uno;
53 namespace sd {
55 /*//Extra attributes coming from parameters
56 sal_uInt16 mnTransparence; // Default: 0
57 OUString msColor; // Default: ""
58 sal_uInt16 mnWidth; // Default: 0
59 OUString msShapeName; // Default: ""*/
60 FuConstructBezierPolygon::FuConstructBezierPolygon (
61 ViewShell* pViewSh,
62 ::sd::Window* pWin,
63 ::sd::View* pView,
64 SdDrawDocument* pDoc,
65 SfxRequest& rReq)
66 : FuConstruct(pViewSh, pWin, pView, pDoc, rReq),
67 nEditMode(SID_BEZIER_MOVE),
68 mnTransparence(0),
69 mnWidth(0)
73 namespace{
75 /// Checks to see if the request has a parameter of IsSticky:bool=true
76 /// It means that the selected command/button will stay selected after use
77 bool isSticky(SfxRequest& rReq)
79 const SfxItemSet *pArgs = rReq.GetArgs ();
80 if (pArgs)
82 const SfxBoolItem* pIsSticky = rReq.GetArg<SfxBoolItem>(FN_PARAM_4);
83 if (pIsSticky && pIsSticky->GetValue())
84 return true;
87 return false;
92 rtl::Reference<FuPoor> FuConstructBezierPolygon::Create( ViewShell* pViewSh, ::sd::Window* pWin, ::sd::View* pView, SdDrawDocument* pDoc, SfxRequest& rReq, bool bPermanent )
94 FuConstructBezierPolygon* pFunc;
95 rtl::Reference<FuPoor> xFunc( pFunc = new FuConstructBezierPolygon( pViewSh, pWin, pView, pDoc, rReq ) );
96 xFunc->DoExecute(rReq);
97 pFunc->SetPermanent(bPermanent || isSticky(rReq));
98 return xFunc;
101 void FuConstructBezierPolygon::DoExecute( SfxRequest& rReq )
103 FuConstruct::DoExecute( rReq );
105 const SfxItemSet* pArgs = rReq.GetArgs();
107 if( !pArgs )
108 return;
110 const SfxPoolItem* pPoolItem = nullptr;
111 if( SfxItemState::SET == pArgs->GetItemState( SID_ADD_MOTION_PATH, true, &pPoolItem ) )
112 maTargets = static_cast<const SfxUnoAnyItem*>( pPoolItem )->GetValue();
114 if (nSlotId == SID_DRAW_FREELINE_NOFILL)
116 const SfxUInt16Item* pTransparence = rReq.GetArg<SfxUInt16Item>(FN_PARAM_1);
117 const SfxStringItem* pColor = rReq.GetArg<SfxStringItem>(FN_PARAM_2);
118 const SfxUInt16Item* pWidth = rReq.GetArg<SfxUInt16Item>(FN_PARAM_3);
119 const SfxStringItem* pShapeName = rReq.GetArg<SfxStringItem>(SID_SHAPE_NAME);
121 if (pTransparence && pTransparence->GetValue() > 0)
123 mnTransparence = pTransparence->GetValue();
125 if (pColor && !pColor->GetValue().isEmpty())
127 msColor = pColor->GetValue();
129 if (pWidth && pWidth->GetValue() > 0)
131 mnWidth = pWidth->GetValue();
133 if (pShapeName && !pShapeName->GetValue().isEmpty())
135 msShapeName = pShapeName->GetValue();
140 bool FuConstructBezierPolygon::MouseButtonDown(const MouseEvent& rMEvt)
142 bool bReturn = FuConstruct::MouseButtonDown(rMEvt);
144 SdrViewEvent aVEvt;
145 SdrHitKind eHit = mpView->PickAnything(rMEvt, SdrMouseEventKind::BUTTONDOWN, aVEvt);
147 if (eHit == SdrHitKind::Handle || rMEvt.IsMod1())
149 mpView->SetEditMode(SdrViewEditMode::Edit);
151 else
153 mpView->SetEditMode(SdrViewEditMode::Create);
156 if (aVEvt.eEvent == SdrEventKind::BeginTextEdit)
158 // here, we do not allow text input
159 aVEvt.eEvent = SdrEventKind::BeginDragObj;
160 mpView->EnableExtendedMouseEventDispatcher(false);
162 else
164 mpView->EnableExtendedMouseEventDispatcher(true);
167 if (eHit == SdrHitKind::MarkedObject && nEditMode == SID_BEZIER_INSERT)
169 // insert glue point
170 mpView->BegInsObjPoint(aMDPos, rMEvt.IsMod1());
172 else
174 mpView->MouseButtonDown(rMEvt, mpWindow);
176 SdrObject* pObj = mpView->GetCreateObj();
178 if (pObj)
180 SfxItemSet aAttr(mpDoc->GetPool());
181 SetStyleSheet(aAttr, pObj);
182 SetAttributes(aAttr, pObj);
183 pObj->SetMergedItemSet(aAttr);
187 return bReturn;
190 bool FuConstructBezierPolygon::MouseButtonUp(const MouseEvent& rMEvt )
192 bool bReturn = false;
193 bool bCreated = false;
195 SdrViewEvent aVEvt;
196 mpView->PickAnything(rMEvt, SdrMouseEventKind::BUTTONUP, aVEvt);
198 const size_t nCount = mpView->GetSdrPageView()->GetObjList()->GetObjCount();
200 if (mpView->IsInsObjPoint())
202 mpView->EndInsObjPoint(SdrCreateCmd::ForceEnd);
204 else
206 mpView->MouseButtonUp(rMEvt, mpWindow);
209 if (aVEvt.eEvent == SdrEventKind::EndCreate)
211 bReturn = true;
213 if (nCount+1 == mpView->GetSdrPageView()->GetObjList()->GetObjCount())
215 bCreated = true;
218 // trick to suppress FuDraw::DoubleClick
219 bMBDown = false;
223 bReturn = FuConstruct::MouseButtonUp(rMEvt) || bReturn;
225 bool bDeleted = false;
226 if( bCreated && maTargets.hasValue() )
228 SdrPathObj* pPathObj = dynamic_cast< SdrPathObj* >( mpView->GetSdrPageView()->GetObjList()->GetObj( nCount ) );
229 SdPage* pPage = dynamic_cast< SdPage* >( pPathObj ? pPathObj->getSdrPageFromSdrObject() : nullptr );
230 if( pPage )
232 std::shared_ptr< sd::MainSequence > pMainSequence( pPage->getMainSequence() );
233 if( pMainSequence.get() )
235 Sequence< Any > aTargets;
236 maTargets >>= aTargets;
238 sal_Int32 nTCount = aTargets.getLength();
239 if( nTCount > 1 )
241 const Any* pTarget = aTargets.getConstArray();
242 double fDuration = 0.0;
243 *pTarget++ >>= fDuration;
244 bool bFirst = true;
245 while( --nTCount )
247 CustomAnimationEffectPtr pCreated( pMainSequence->append( *pPathObj, *pTarget++, fDuration ) );
248 if( bFirst )
249 bFirst = false;
250 else
251 pCreated->setNodeType( css::presentation::EffectNodeType::WITH_PREVIOUS );
256 mpView->DeleteMarked();
257 bDeleted = true;
260 if ((!bPermanent && bCreated) || bDeleted)
262 mpViewShell->GetViewFrame()->GetDispatcher()->Execute(SID_OBJECT_SELECT, SfxCallMode::ASYNCHRON);
265 return bReturn;
268 void FuConstructBezierPolygon::Activate()
270 mpView->EnableExtendedMouseEventDispatcher(true);
272 SdrObjKind eKind;
274 switch (nSlotId)
276 case SID_DRAW_POLYGON_NOFILL:
277 case SID_DRAW_XPOLYGON_NOFILL:
279 eKind = OBJ_PLIN;
281 break;
283 case SID_DRAW_POLYGON:
284 case SID_DRAW_XPOLYGON:
286 eKind = OBJ_POLY;
288 break;
290 case SID_DRAW_BEZIER_NOFILL:
292 eKind = OBJ_PATHLINE;
294 break;
296 case SID_DRAW_BEZIER_FILL:
298 eKind = OBJ_PATHFILL;
300 break;
302 case SID_DRAW_FREELINE_NOFILL:
304 eKind = OBJ_FREELINE;
306 break;
308 case SID_DRAW_FREELINE:
310 eKind = OBJ_FREEFILL;
312 break;
314 default:
316 eKind = OBJ_PATHLINE;
318 break;
321 mpView->SetCurrentObj(static_cast<sal_uInt16>(eKind));
323 FuConstruct::Activate();
326 void FuConstructBezierPolygon::Deactivate()
328 mpView->EnableExtendedMouseEventDispatcher(false);
330 FuConstruct::Deactivate();
333 void FuConstructBezierPolygon::SelectionHasChanged()
335 FuDraw::SelectionHasChanged();
337 mpViewShell->GetViewShellBase().GetToolBarManager()->SelectionHasChanged(
338 *mpViewShell,
339 *mpView);
342 namespace {
343 /// Returns the color based on the color names listed in core/include/tools/color.hxx
344 /// Feel free to extend with more color names from color.hxx
345 Color strToColor(const OUString& sColor)
347 Color aColor = COL_AUTO;
349 if (sColor == "COL_GRAY")
350 aColor = COL_GRAY;
351 else if (sColor == "COL_GRAY3")
352 aColor = COL_GRAY3;
353 else if (sColor == "COL_GRAY7")
354 aColor = COL_GRAY7;
356 return aColor;
360 void FuConstructBezierPolygon::SetAttributes(SfxItemSet& rAttr, SdrObject *pObj)
362 if (nSlotId == SID_DRAW_FREELINE_NOFILL)
364 if (mnTransparence > 0 && mnTransparence <= 100)
365 rAttr.Put(XLineTransparenceItem(mnTransparence));
366 if (!msColor.isEmpty())
367 rAttr.Put(XLineColorItem(OUString(), strToColor(msColor)));
368 if (mnWidth > 0)
369 rAttr.Put(XLineWidthItem(mnWidth));
370 if (!msShapeName.isEmpty())
371 pObj->SetName(msShapeName);
376 * Set current bezier edit mode
378 void FuConstructBezierPolygon::SetEditMode(sal_uInt16 nMode)
380 nEditMode = nMode;
381 ForcePointer();
383 SfxBindings& rBindings = mpViewShell->GetViewFrame()->GetBindings();
384 rBindings.Invalidate(SID_BEZIER_MOVE);
385 rBindings.Invalidate(SID_BEZIER_INSERT);
388 SdrObjectUniquePtr FuConstructBezierPolygon::CreateDefaultObject(const sal_uInt16 nID, const ::tools::Rectangle& rRectangle)
390 // case SID_DRAW_POLYGON:
391 // case SID_DRAW_POLYGON_NOFILL:
392 // case SID_DRAW_XPOLYGON:
393 // case SID_DRAW_XPOLYGON_NOFILL:
394 // case SID_DRAW_FREELINE:
395 // case SID_DRAW_FREELINE_NOFILL:
396 // case SID_DRAW_BEZIER_FILL: // BASIC
397 // case SID_DRAW_BEZIER_NOFILL: // BASIC
399 SdrObjectUniquePtr pObj(SdrObjFactory::MakeNewObject(
400 mpView->getSdrModelFromSdrView(),
401 mpView->GetCurrentObjInventor(),
402 mpView->GetCurrentObjIdentifier()));
404 if(pObj)
406 if( auto pPathObj = dynamic_cast< SdrPathObj *>( pObj.get() ) )
408 basegfx::B2DPolyPolygon aPoly;
410 switch(nID)
412 case SID_DRAW_BEZIER_FILL:
414 const sal_Int32 nWdt(rRectangle.GetWidth() / 2);
415 const sal_Int32 nHgt(rRectangle.GetHeight() / 2);
416 const basegfx::B2DPolygon aInnerPoly(basegfx::utils::createPolygonFromEllipse(basegfx::B2DPoint(rRectangle.Center().X(), rRectangle.Center().Y()), nWdt, nHgt));
418 aPoly.append(aInnerPoly);
419 break;
421 case SID_DRAW_BEZIER_NOFILL:
423 basegfx::B2DPolygon aInnerPoly;
425 aInnerPoly.append(basegfx::B2DPoint(rRectangle.Left(), rRectangle.Bottom()));
427 const basegfx::B2DPoint aCenterBottom(rRectangle.Center().X(), rRectangle.Bottom());
428 aInnerPoly.appendBezierSegment(
429 aCenterBottom,
430 aCenterBottom,
431 basegfx::B2DPoint(rRectangle.Center().X(), rRectangle.Center().Y()));
433 const basegfx::B2DPoint aCenterTop(rRectangle.Center().X(), rRectangle.Top());
434 aInnerPoly.appendBezierSegment(
435 aCenterTop,
436 aCenterTop,
437 basegfx::B2DPoint(rRectangle.Right(), rRectangle.Top()));
439 aPoly.append(aInnerPoly);
440 break;
442 case SID_DRAW_FREELINE:
443 case SID_DRAW_FREELINE_NOFILL:
445 basegfx::B2DPolygon aInnerPoly;
447 aInnerPoly.append(basegfx::B2DPoint(rRectangle.Left(), rRectangle.Bottom()));
449 aInnerPoly.appendBezierSegment(
450 basegfx::B2DPoint(rRectangle.Left(), rRectangle.Top()),
451 basegfx::B2DPoint(rRectangle.Center().X(), rRectangle.Top()),
452 basegfx::B2DPoint(rRectangle.Center().X(), rRectangle.Center().Y()));
454 aInnerPoly.appendBezierSegment(
455 basegfx::B2DPoint(rRectangle.Center().X(), rRectangle.Bottom()),
456 basegfx::B2DPoint(rRectangle.Right(), rRectangle.Bottom()),
457 basegfx::B2DPoint(rRectangle.Right(), rRectangle.Top()));
459 if(SID_DRAW_FREELINE == nID)
461 aInnerPoly.append(basegfx::B2DPoint(rRectangle.Right(), rRectangle.Bottom()));
463 else
465 aInnerPoly.setClosed(true);
468 aPoly.append(aInnerPoly);
469 break;
471 case SID_DRAW_XPOLYGON:
472 case SID_DRAW_XPOLYGON_NOFILL:
474 basegfx::B2DPolygon aInnerPoly;
476 aInnerPoly.append(basegfx::B2DPoint(rRectangle.Left(), rRectangle.Bottom()));
477 aInnerPoly.append(basegfx::B2DPoint(rRectangle.Left(), rRectangle.Top()));
478 aInnerPoly.append(basegfx::B2DPoint(rRectangle.Center().X(), rRectangle.Top()));
479 aInnerPoly.append(basegfx::B2DPoint(rRectangle.Center().X(), rRectangle.Center().Y()));
480 aInnerPoly.append(basegfx::B2DPoint(rRectangle.Right(), rRectangle.Center().Y()));
481 aInnerPoly.append(basegfx::B2DPoint(rRectangle.Right(), rRectangle.Bottom()));
483 if(SID_DRAW_XPOLYGON_NOFILL == nID)
485 aInnerPoly.append(basegfx::B2DPoint(rRectangle.Center().X(), rRectangle.Bottom()));
487 else
489 aInnerPoly.setClosed(true);
492 aPoly.append(aInnerPoly);
493 break;
495 case SID_DRAW_POLYGON:
496 case SID_DRAW_POLYGON_NOFILL:
498 basegfx::B2DPolygon aInnerPoly;
499 const sal_Int32 nWdt(rRectangle.GetWidth());
500 const sal_Int32 nHgt(rRectangle.GetHeight());
502 aInnerPoly.append(basegfx::B2DPoint(rRectangle.Left(), rRectangle.Bottom()));
503 aInnerPoly.append(basegfx::B2DPoint(rRectangle.Left() + (nWdt * 30) / 100, rRectangle.Top() + (nHgt * 70) / 100));
504 aInnerPoly.append(basegfx::B2DPoint(rRectangle.Left(), rRectangle.Top() + (nHgt * 15) / 100));
505 aInnerPoly.append(basegfx::B2DPoint(rRectangle.Left() + (nWdt * 65) / 100, rRectangle.Top()));
506 aInnerPoly.append(basegfx::B2DPoint(rRectangle.Left() + nWdt, rRectangle.Top() + (nHgt * 30) / 100));
507 aInnerPoly.append(basegfx::B2DPoint(rRectangle.Left() + (nWdt * 80) / 100, rRectangle.Top() + (nHgt * 50) / 100));
508 aInnerPoly.append(basegfx::B2DPoint(rRectangle.Left() + (nWdt * 80) / 100, rRectangle.Top() + (nHgt * 75) / 100));
509 aInnerPoly.append(basegfx::B2DPoint(rRectangle.Bottom(), rRectangle.Right()));
511 if(SID_DRAW_POLYGON_NOFILL == nID)
513 aInnerPoly.append(basegfx::B2DPoint(rRectangle.Center().X(), rRectangle.Bottom()));
515 else
517 aInnerPoly.setClosed(true);
520 aPoly.append(aInnerPoly);
521 break;
525 pPathObj->SetPathPoly(aPoly);
527 else
529 OSL_FAIL("Object is NO path object");
532 pObj->SetLogicRect(rRectangle);
535 return pObj;
538 } // end of namespace sd
540 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */