bump product version to 5.0.4.1
[LibreOffice.git] / svx / source / engine3d / dragmt3d.cxx
blob7e090c3fc941529a58b0b9e3a53f3ebb928a00f2
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 .
21 #include <dragmt3d.hxx>
22 #include <o3tl/numeric.hxx>
23 #include <svx/svdpagv.hxx>
24 #include <svx/dialmgr.hxx>
25 #include <svx/svddrgmt.hxx>
26 #include <svx/svdtrans.hxx>
27 #include <svx/obj3d.hxx>
28 #include <svx/polysc3d.hxx>
29 #include <svx/e3dundo.hxx>
30 #include <svx/dialogs.hrc>
31 #include <svx/sdr/overlay/overlaypolypolygon.hxx>
32 #include <svx/sdr/overlay/overlaymanager.hxx>
33 #include <basegfx/polygon/b2dpolypolygontools.hxx>
34 #include <svx/sdr/contact/viewcontactofe3dscene.hxx>
35 #include <drawinglayer/geometry/viewinformation3d.hxx>
36 #include <svx/e3dsceneupdater.hxx>
38 TYPEINIT1(E3dDragMethod, SdrDragMethod);
40 E3dDragMethod::E3dDragMethod (
41 SdrDragView &_rView,
42 const SdrMarkList& rMark,
43 E3dDragConstraint eConstr,
44 bool bFull)
45 : SdrDragMethod(_rView),
46 meConstraint(eConstr),
47 mbMoveFull(bFull),
48 mbMovedAtAll(false)
50 // Create a unit for all the 3D objects present in the selection
51 const size_t nCnt(rMark.GetMarkCount());
53 if(mbMoveFull)
55 // for non-visible 3D objects fallback to wireframe interaction
56 for(size_t nObjs = 0; nObjs < nCnt; ++nObjs)
58 E3dObject* pE3dObj = dynamic_cast< E3dObject* >(rMark.GetMark(nObjs)->GetMarkedSdrObj());
60 if(pE3dObj)
62 if(!pE3dObj->HasFillStyle() && !pE3dObj->HasLineStyle())
64 mbMoveFull = false;
65 break;
71 for(size_t nObjs = 0; nObjs < nCnt; ++nObjs)
73 E3dObject* pE3dObj = dynamic_cast< E3dObject* >(rMark.GetMark(nObjs)->GetMarkedSdrObj());
75 if(pE3dObj)
77 // fill new interaction unit
78 E3dDragMethodUnit aNewUnit;
79 aNewUnit.mp3DObj = pE3dObj;
81 // get transformations
82 aNewUnit.maInitTransform = aNewUnit.maTransform = pE3dObj->GetTransform();
84 if(pE3dObj->GetParentObj())
86 // get transform between object and world, normally scene transform
87 aNewUnit.maInvDisplayTransform = aNewUnit.maDisplayTransform = pE3dObj->GetParentObj()->GetFullTransform();
88 aNewUnit.maInvDisplayTransform.invert();
91 if(!mbMoveFull)
93 // create wireframe visualisation for parent coordinate system
94 aNewUnit.maWireframePoly.clear();
95 aNewUnit.maWireframePoly = pE3dObj->CreateWireframe();
96 aNewUnit.maWireframePoly.transform(aNewUnit.maTransform);
99 // Determine FullBound
100 maFullBound.Union(pE3dObj->GetSnapRect());
102 // Insert Unit
103 maGrp.push_back(aNewUnit);
108 void E3dDragMethod::TakeSdrDragComment(OUString& /*rStr*/) const
112 // Create the wireframe model for all actions
114 bool E3dDragMethod::BeginSdrDrag()
116 if(E3DDRAG_CONSTR_Z == meConstraint)
118 const sal_uInt32 nCnt(maGrp.size());
119 DragStat().Ref1() = maFullBound.Center();
121 for(sal_uInt32 nOb(0); nOb < nCnt; nOb++)
123 E3dDragMethodUnit& rCandidate = maGrp[nOb];
124 rCandidate.mnStartAngle = GetAngle(DragStat().GetStart() - DragStat().GetRef1());
125 rCandidate.mnLastAngle = 0;
128 else
130 maLastPos = DragStat().GetStart();
133 if(!mbMoveFull)
135 Show();
138 return true;
141 bool E3dDragMethod::EndSdrDrag(bool /*bCopy*/)
143 const sal_uInt32 nCnt(maGrp.size());
145 if(!mbMoveFull)
147 // Hide wireframe
148 Hide();
151 // Apply all transformations and create undo's
152 if(mbMovedAtAll)
154 const bool bUndo = getSdrDragView().IsUndoEnabled();
155 if( bUndo )
156 getSdrDragView().BegUndo(SVX_RESSTR(RID_SVX_3D_UNDO_ROTATE));
157 sal_uInt32 nOb(0);
159 for(nOb=0;nOb<nCnt;nOb++)
161 E3dDragMethodUnit& rCandidate = maGrp[nOb];
162 E3DModifySceneSnapRectUpdater aUpdater(rCandidate.mp3DObj);
163 rCandidate.mp3DObj->SetTransform(rCandidate.maTransform);
164 if( bUndo )
166 getSdrDragView().AddUndo(new E3dRotateUndoAction(rCandidate.mp3DObj->GetModel(),
167 rCandidate.mp3DObj, rCandidate.maInitTransform,
168 rCandidate.maTransform));
171 if( bUndo )
172 getSdrDragView().EndUndo();
175 return true;
178 void E3dDragMethod::CancelSdrDrag()
180 if(mbMoveFull)
182 if(mbMovedAtAll)
184 const sal_uInt32 nCnt(maGrp.size());
186 for(sal_uInt32 nOb(0); nOb < nCnt; nOb++)
188 // Restore transformation
189 E3dDragMethodUnit& rCandidate = maGrp[nOb];
190 E3DModifySceneSnapRectUpdater aUpdater(rCandidate.mp3DObj);
191 rCandidate.mp3DObj->SetTransform(rCandidate.maInitTransform);
195 else
197 // Hide WireFrame
198 Hide();
202 // Common MoveSdrDrag()
204 void E3dDragMethod::MoveSdrDrag(const Point& /*rPnt*/)
206 mbMovedAtAll = true;
209 // Draw the wire frame model
211 // for migration from XOR to overlay
212 void E3dDragMethod::CreateOverlayGeometry(sdr::overlay::OverlayManager& rOverlayManager)
214 const sal_uInt32 nCnt(maGrp.size());
215 basegfx::B2DPolyPolygon aResult;
217 for(sal_uInt32 nOb(0); nOb < nCnt; nOb++)
219 E3dDragMethodUnit& rCandidate = maGrp[nOb];
220 SdrPageView* pPV = getSdrDragView().GetSdrPageView();
222 if(pPV && pPV->HasMarkedObjPageView())
224 const basegfx::B3DPolyPolygon aCandidate(rCandidate.maWireframePoly);
225 const sal_uInt32 nPlyCnt(aCandidate.count());
227 if(nPlyCnt)
229 const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(rCandidate.mp3DObj->GetScene()->GetViewContact());
230 const drawinglayer::geometry::ViewInformation3D aViewInfo3D(rVCScene.getViewInformation3D());
231 const basegfx::B3DHomMatrix aWorldToView(aViewInfo3D.getDeviceToView() * aViewInfo3D.getProjection() * aViewInfo3D.getOrientation());
232 const basegfx::B3DHomMatrix aTransform(aWorldToView * rCandidate.maDisplayTransform);
234 // transform to relative scene coordinates
235 basegfx::B2DPolyPolygon aPolyPolygon(basegfx::tools::createB2DPolyPolygonFromB3DPolyPolygon(aCandidate, aTransform));
237 // transform to 2D view coordinates
238 aPolyPolygon.transform(rVCScene.getObjectTransformation());
240 aResult.append(aPolyPolygon);
245 if(aResult.count())
247 sdr::overlay::OverlayPolyPolygonStripedAndFilled* pNew = new sdr::overlay::OverlayPolyPolygonStripedAndFilled(
248 aResult);
249 rOverlayManager.add(*pNew);
250 addToOverlayObjectList(*pNew);
254 TYPEINIT1(E3dDragRotate, E3dDragMethod);
256 E3dDragRotate::E3dDragRotate(SdrDragView &_rView,
257 const SdrMarkList& rMark,
258 E3dDragConstraint eConstr,
259 bool bFull)
260 : E3dDragMethod(_rView, rMark, eConstr, bFull)
262 // Get center of all selected objects in eye coordinates
263 const sal_uInt32 nCnt(maGrp.size());
265 if(nCnt)
267 const E3dScene *pScene = maGrp[0].mp3DObj->GetScene();
269 if(pScene)
271 const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(pScene->GetViewContact());
272 const drawinglayer::geometry::ViewInformation3D aViewInfo3D(rVCScene.getViewInformation3D());
274 for(sal_uInt32 nOb(0); nOb < nCnt; nOb++)
276 E3dDragMethodUnit& rCandidate = maGrp[nOb];
277 basegfx::B3DPoint aObjCenter = rCandidate.mp3DObj->GetBoundVolume().getCenter();
278 const basegfx::B3DHomMatrix aTransform(aViewInfo3D.getOrientation() * rCandidate.maDisplayTransform * rCandidate.maInitTransform);
280 aObjCenter = aTransform * aObjCenter;
281 maGlobalCenter += aObjCenter;
284 // Divide by the number
285 if(nCnt > 1)
287 maGlobalCenter /= (double)nCnt;
290 // get rotate center and transform to 3D eye coordinates
291 basegfx::B2DPoint aRotCenter2D(Ref1().X(), Ref1().Y());
293 // from world to relative scene using inverse getObjectTransformation()
294 basegfx::B2DHomMatrix aInverseObjectTransform(rVCScene.getObjectTransformation());
295 aInverseObjectTransform.invert();
296 aRotCenter2D = aInverseObjectTransform * aRotCenter2D;
298 // from 3D view to 3D eye
299 basegfx::B3DPoint aRotCenter3D(aRotCenter2D.getX(), aRotCenter2D.getY(), 0.0);
300 basegfx::B3DHomMatrix aInverseViewToEye(aViewInfo3D.getDeviceToView() * aViewInfo3D.getProjection());
301 aInverseViewToEye.invert();
302 aRotCenter3D = aInverseViewToEye * aRotCenter3D;
304 // Use X,Y of the RotCenter and depth of the common object centre
305 // as rotation point in the space
306 maGlobalCenter.setX(aRotCenter3D.getX());
307 maGlobalCenter.setY(aRotCenter3D.getY());
313 //The object is moved, determine the angle
315 void E3dDragRotate::MoveSdrDrag(const Point& rPnt)
317 // call parent
318 E3dDragMethod::MoveSdrDrag(rPnt);
320 if(DragStat().CheckMinMoved(rPnt))
322 // Get modifier
323 sal_uInt16 nModifier = 0;
324 if(getSdrDragView().ISA(E3dView))
326 const MouseEvent& rLastMouse = static_cast<E3dView&>(getSdrDragView()).GetMouseEvent();
327 nModifier = rLastMouse.GetModifier();
330 // Rotate all objects
331 const sal_uInt32 nCnt(maGrp.size());
333 for(sal_uInt32 nOb(0); nOb < nCnt; nOb++)
335 // Determine rotation angle
336 double fWAngle, fHAngle;
337 E3dDragMethodUnit& rCandidate = maGrp[nOb];
339 if(E3DDRAG_CONSTR_Z == meConstraint)
341 fWAngle = NormAngle360(GetAngle(rPnt - DragStat().GetRef1()) -
342 rCandidate.mnStartAngle) - rCandidate.mnLastAngle;
343 rCandidate.mnLastAngle = (long)fWAngle + rCandidate.mnLastAngle;
344 fWAngle /= 100.0;
345 fHAngle = 0.0;
347 else
349 if ((maFullBound.GetWidth() == 0) || (maFullBound.GetHeight() == 0))
350 throw o3tl::divide_by_zero();
351 fWAngle = 90.0 * (double)(rPnt.X() - maLastPos.X())
352 / (double)maFullBound.GetWidth();
353 fHAngle = 90.0 * (double)(rPnt.Y() - maLastPos.Y())
354 / (double)maFullBound.GetHeight();
356 long nSnap = 0;
358 if(!getSdrDragView().IsRotateAllowed(false))
359 nSnap = 90;
361 if(nSnap != 0)
363 fWAngle = (double)(((long) fWAngle + nSnap/2) / nSnap * nSnap);
364 fHAngle = (double)(((long) fHAngle + nSnap/2) / nSnap * nSnap);
367 // to radians
368 fWAngle *= F_PI180;
369 fHAngle *= F_PI180;
371 // Determine transformation
372 basegfx::B3DHomMatrix aRotMat;
373 if(E3DDRAG_CONSTR_Y & meConstraint)
375 if(nModifier & KEY_MOD2)
376 aRotMat.rotate(0.0, 0.0, fWAngle);
377 else
378 aRotMat.rotate(0.0, fWAngle, 0.0);
380 else if(E3DDRAG_CONSTR_Z & meConstraint)
382 if(nModifier & KEY_MOD2)
383 aRotMat.rotate(0.0, fWAngle, 0.0);
384 else
385 aRotMat.rotate(0.0, 0.0, fWAngle);
387 if(E3DDRAG_CONSTR_X & meConstraint)
389 aRotMat.rotate(fHAngle, 0.0, 0.0);
392 // Transformation in eye coordinates, there rotate then and back
393 const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(rCandidate.mp3DObj->GetScene()->GetViewContact());
394 const drawinglayer::geometry::ViewInformation3D aViewInfo3D(rVCScene.getViewInformation3D());
395 basegfx::B3DHomMatrix aInverseOrientation(aViewInfo3D.getOrientation());
396 aInverseOrientation.invert();
398 basegfx::B3DHomMatrix aTransMat(rCandidate.maDisplayTransform);
399 aTransMat *= aViewInfo3D.getOrientation();
400 aTransMat.translate(-maGlobalCenter.getX(), -maGlobalCenter.getY(), -maGlobalCenter.getZ());
401 aTransMat *= aRotMat;
402 aTransMat.translate(maGlobalCenter.getX(), maGlobalCenter.getY(), maGlobalCenter.getZ());
403 aTransMat *= aInverseOrientation;
404 aTransMat *= rCandidate.maInvDisplayTransform;
406 // ...and apply
407 rCandidate.maTransform *= aTransMat;
409 if(mbMoveFull)
411 E3DModifySceneSnapRectUpdater aUpdater(rCandidate.mp3DObj);
412 rCandidate.mp3DObj->SetTransform(rCandidate.maTransform);
414 else
416 Hide();
417 rCandidate.maWireframePoly.transform(aTransMat);
418 Show();
421 maLastPos = rPnt;
422 DragStat().NextMove(rPnt);
426 Pointer E3dDragRotate::GetSdrDragPointer() const
428 return Pointer(PointerStyle::Rotate);
431 // E3dDragMove. This drag method is only required for translations inside
432 // 3D scenes. If a 3D-scene itself moved, then this drag method will drag
433 // not be used.
435 TYPEINIT1(E3dDragMove, E3dDragMethod);
437 E3dDragMove::E3dDragMove(SdrDragView &_rView,
438 const SdrMarkList& rMark,
439 SdrHdlKind eDrgHdl,
440 E3dDragConstraint eConstr,
441 bool bFull)
442 : E3dDragMethod(_rView, rMark, eConstr, bFull),
443 meWhatDragHdl(eDrgHdl)
445 switch(meWhatDragHdl)
447 case HDL_LEFT:
448 maScaleFixPos = maFullBound.RightCenter();
449 break;
450 case HDL_RIGHT:
451 maScaleFixPos = maFullBound.LeftCenter();
452 break;
453 case HDL_UPPER:
454 maScaleFixPos = maFullBound.BottomCenter();
455 break;
456 case HDL_LOWER:
457 maScaleFixPos = maFullBound.TopCenter();
458 break;
459 case HDL_UPLFT:
460 maScaleFixPos = maFullBound.BottomRight();
461 break;
462 case HDL_UPRGT:
463 maScaleFixPos = maFullBound.BottomLeft();
464 break;
465 case HDL_LWLFT:
466 maScaleFixPos = maFullBound.TopRight();
467 break;
468 case HDL_LWRGT:
469 maScaleFixPos = maFullBound.TopLeft();
470 break;
471 default:
472 // Moving the object, HDL_MOVE
473 break;
476 // Override when IsResizeAtCenter()
477 if(getSdrDragView().IsResizeAtCenter())
479 meWhatDragHdl = HDL_USER;
480 maScaleFixPos = maFullBound.Center();
484 // The object is moved, determine the translations
486 void E3dDragMove::MoveSdrDrag(const Point& rPnt)
488 // call parent
489 E3dDragMethod::MoveSdrDrag(rPnt);
491 if(DragStat().CheckMinMoved(rPnt))
493 if(HDL_MOVE == meWhatDragHdl)
495 // Translation
496 // Determine the motion vector
497 const sal_uInt32 nCnt(maGrp.size());
499 // Get modifier
500 sal_uInt16 nModifier(0);
502 if(getSdrDragView().ISA(E3dView))
504 const MouseEvent& rLastMouse = static_cast<E3dView&>(getSdrDragView()).GetMouseEvent();
505 nModifier = rLastMouse.GetModifier();
508 for(sal_uInt32 nOb(0); nOb < nCnt; nOb++)
510 E3dDragMethodUnit& rCandidate = maGrp[nOb];
511 const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(rCandidate.mp3DObj->GetScene()->GetViewContact());
512 const drawinglayer::geometry::ViewInformation3D aViewInfo3D(rVCScene.getViewInformation3D());
514 // move coor from 2d world to 3d Eye
515 basegfx::B2DPoint aGlobalMoveHead2D((double)(rPnt.X() - maLastPos.X()), (double)(rPnt.Y() - maLastPos.Y()));
516 basegfx::B2DPoint aGlobalMoveTail2D(0.0, 0.0);
517 basegfx::B2DHomMatrix aInverseSceneTransform(rVCScene.getObjectTransformation());
519 aInverseSceneTransform.invert();
520 aGlobalMoveHead2D = aInverseSceneTransform * aGlobalMoveHead2D;
521 aGlobalMoveTail2D = aInverseSceneTransform * aGlobalMoveTail2D;
523 basegfx::B3DPoint aMoveHead3D(aGlobalMoveHead2D.getX(), aGlobalMoveHead2D.getY(), 0.5);
524 basegfx::B3DPoint aMoveTail3D(aGlobalMoveTail2D.getX(), aGlobalMoveTail2D.getY(), 0.5);
525 basegfx::B3DHomMatrix aInverseViewToEye(aViewInfo3D.getDeviceToView() * aViewInfo3D.getProjection());
526 aInverseViewToEye.invert();
528 aMoveHead3D = aInverseViewToEye * aMoveHead3D;
529 aMoveTail3D = aInverseViewToEye * aMoveTail3D;
531 // eventually switch movement from XY to XZ plane
532 if(nModifier & KEY_MOD2)
534 double fZwi = aMoveHead3D.getY();
535 aMoveHead3D.setY(aMoveHead3D.getZ());
536 aMoveHead3D.setZ(fZwi);
538 fZwi = aMoveTail3D.getY();
539 aMoveTail3D.setY(aMoveTail3D.getZ());
540 aMoveTail3D.setZ(fZwi);
543 // Motion vector from eye coordinates to parent coordinates
544 basegfx::B3DHomMatrix aInverseOrientation(aViewInfo3D.getOrientation());
545 aInverseOrientation.invert();
546 basegfx::B3DHomMatrix aCompleteTrans(rCandidate.maInvDisplayTransform * aInverseOrientation);
548 aMoveHead3D = aCompleteTrans * aMoveHead3D;
549 aMoveTail3D = aCompleteTrans* aMoveTail3D;
551 // build transformation
552 basegfx::B3DHomMatrix aTransMat;
553 basegfx::B3DPoint aTranslate(aMoveHead3D - aMoveTail3D);
554 aTransMat.translate(aTranslate.getX(), aTranslate.getY(), aTranslate.getZ());
556 // ...and apply
557 rCandidate.maTransform *= aTransMat;
559 if(mbMoveFull)
561 E3DModifySceneSnapRectUpdater aUpdater(rCandidate.mp3DObj);
562 rCandidate.mp3DObj->SetTransform(rCandidate.maTransform);
564 else
566 Hide();
567 rCandidate.maWireframePoly.transform(aTransMat);
568 Show();
572 else
574 // Scaling
575 // Determine scaling vector
576 Point aStartPos = DragStat().GetStart();
577 const sal_uInt32 nCnt(maGrp.size());
579 for(sal_uInt32 nOb(0); nOb < nCnt; nOb++)
581 E3dDragMethodUnit& rCandidate = maGrp[nOb];
582 const basegfx::B3DPoint aObjectCenter(rCandidate.mp3DObj->GetBoundVolume().getCenter());
584 // transform from 2D world view to 3D eye
585 const sdr::contact::ViewContactOfE3dScene& rVCScene = static_cast< sdr::contact::ViewContactOfE3dScene& >(rCandidate.mp3DObj->GetScene()->GetViewContact());
586 const drawinglayer::geometry::ViewInformation3D aViewInfo3D(rVCScene.getViewInformation3D());
588 basegfx::B2DPoint aGlobalScaleStart2D((double)(aStartPos.X()), (double)(aStartPos.Y()));
589 basegfx::B2DPoint aGlobalScaleNext2D((double)(rPnt.X()), (double)(rPnt.Y()));
590 basegfx::B2DPoint aGlobalScaleFixPos2D((double)(maScaleFixPos.X()), (double)(maScaleFixPos.Y()));
591 basegfx::B2DHomMatrix aInverseSceneTransform(rVCScene.getObjectTransformation());
593 aInverseSceneTransform.invert();
594 aGlobalScaleStart2D = aInverseSceneTransform * aGlobalScaleStart2D;
595 aGlobalScaleNext2D = aInverseSceneTransform * aGlobalScaleNext2D;
596 aGlobalScaleFixPos2D = aInverseSceneTransform * aGlobalScaleFixPos2D;
598 basegfx::B3DPoint aGlobalScaleStart3D(aGlobalScaleStart2D.getX(), aGlobalScaleStart2D.getY(), aObjectCenter.getZ());
599 basegfx::B3DPoint aGlobalScaleNext3D(aGlobalScaleNext2D.getX(), aGlobalScaleNext2D.getY(), aObjectCenter.getZ());
600 basegfx::B3DPoint aGlobalScaleFixPos3D(aGlobalScaleFixPos2D.getX(), aGlobalScaleFixPos2D.getY(), aObjectCenter.getZ());
601 basegfx::B3DHomMatrix aInverseViewToEye(aViewInfo3D.getDeviceToView() * aViewInfo3D.getProjection());
603 aInverseViewToEye.invert();
604 basegfx::B3DPoint aScStart(aInverseViewToEye * aGlobalScaleStart3D);
605 basegfx::B3DPoint aScNext(aInverseViewToEye * aGlobalScaleNext3D);
606 basegfx::B3DPoint aScFixPos(aInverseViewToEye * aGlobalScaleFixPos3D);
608 // constraints?
609 switch(meWhatDragHdl)
611 case HDL_LEFT:
612 case HDL_RIGHT:
613 // to constrain on X -> Y equal
614 aScNext.setY(aScFixPos.getY());
615 break;
616 case HDL_UPPER:
617 case HDL_LOWER:
618 // constrain to auf Y -> X equal
619 aScNext.setX(aScFixPos.getX());
620 break;
621 default:
622 break;
625 // get scale vector in eye coordinates
626 basegfx::B3DPoint aScaleVec(aScStart - aScFixPos);
627 aScaleVec.setZ(1.0);
629 if(aScaleVec.getX() != 0.0)
631 aScaleVec.setX((aScNext.getX() - aScFixPos.getX()) / aScaleVec.getX());
633 else
635 aScaleVec.setX(1.0);
638 if(aScaleVec.getY() != 0.0)
640 aScaleVec.setY((aScNext.getY() - aScFixPos.getY()) / aScaleVec.getY());
642 else
644 aScaleVec.setY(1.0);
647 // SHIFT-key used?
648 if(getSdrDragView().IsOrtho())
650 if(fabs(aScaleVec.getX()) > fabs(aScaleVec.getY()))
652 // X is biggest
653 aScaleVec.setY(aScaleVec.getX());
655 else
657 // Y is biggest
658 aScaleVec.setX(aScaleVec.getY());
662 // build transformation
663 basegfx::B3DHomMatrix aInverseOrientation(aViewInfo3D.getOrientation());
664 aInverseOrientation.invert();
666 basegfx::B3DHomMatrix aNewTrans = rCandidate.maInitTransform;
667 aNewTrans *= rCandidate.maDisplayTransform;
668 aNewTrans *= aViewInfo3D.getOrientation();
669 aNewTrans.translate(-aScFixPos.getX(), -aScFixPos.getY(), -aScFixPos.getZ());
670 aNewTrans.scale(aScaleVec.getX(), aScaleVec.getY(), aScaleVec.getZ());
671 aNewTrans.translate(aScFixPos.getX(), aScFixPos.getY(), aScFixPos.getZ());
672 aNewTrans *= aInverseOrientation;
673 aNewTrans *= rCandidate.maInvDisplayTransform;
675 // ...and apply
676 rCandidate.maTransform = aNewTrans;
678 if(mbMoveFull)
680 E3DModifySceneSnapRectUpdater aUpdater(rCandidate.mp3DObj);
681 rCandidate.mp3DObj->SetTransform(rCandidate.maTransform);
683 else
685 Hide();
686 rCandidate.maWireframePoly.clear();
687 rCandidate.maWireframePoly = rCandidate.mp3DObj->CreateWireframe();
688 rCandidate.maWireframePoly.transform(rCandidate.maTransform);
689 Show();
693 maLastPos = rPnt;
694 DragStat().NextMove(rPnt);
698 Pointer E3dDragMove::GetSdrDragPointer() const
700 return Pointer(PointerStyle::Move);
703 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */