merge the formfield patch from ooo-build
[ooovba.git] / sd / source / ui / func / fucon3d.cxx
blobafecd4b42d0479185e23f9a015353bcfb213a232
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: fucon3d.cxx,v $
10 * $Revision: 1.23.8.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sd.hxx"
34 #include "fucon3d.hxx"
35 #include <vcl/waitobj.hxx>
37 #include <svx/svxids.hrc>
38 #include <svtools/aeitem.hxx>
39 #include <sfx2/app.hxx>
40 #include <sfx2/dispatch.hxx>
41 #include <sfx2/viewfrm.hxx>
42 #include <tools/poly.hxx>
44 #include <math.h>
45 #include <svx/globl3d.hxx>
46 #include <svx/scene3d.hxx>
47 #include <svx/sphere3d.hxx>
48 #include <svx/cube3d.hxx>
49 #include <svx/lathe3d.hxx>
50 #include <svx/camera3d.hxx>
52 #include "app.hrc"
53 #include "res_bmp.hrc"
54 #include "View.hxx"
55 #include "Window.hxx"
56 #include "ViewShell.hxx"
57 #include "drawdoc.hxx"
58 #include "ViewShellBase.hxx"
59 #include "ToolBarManager.hxx"
60 #include <svx/svx3ditems.hxx>
62 // #97016#
63 #include <svx/polysc3d.hxx>
64 #include <basegfx/polygon/b2dpolygontools.hxx>
66 namespace sd {
68 TYPEINIT1( FuConstruct3dObject, FuConstruct );
70 /*************************************************************************
72 |* Konstruktor
74 \************************************************************************/
76 FuConstruct3dObject::FuConstruct3dObject (
77 ViewShell* pViewSh,
78 ::sd::Window* pWin,
79 ::sd::View* pView,
80 SdDrawDocument* pDoc,
81 SfxRequest& rReq)
82 : FuConstruct(pViewSh, pWin, pView, pDoc, rReq)
86 FunctionReference FuConstruct3dObject::Create( ViewShell* pViewSh, ::sd::Window* pWin, ::sd::View* pView, SdDrawDocument* pDoc, SfxRequest& rReq, bool bPermanent )
88 FuConstruct3dObject* pFunc;
89 FunctionReference xFunc( pFunc = new FuConstruct3dObject( pViewSh, pWin, pView, pDoc, rReq ) );
90 xFunc->DoExecute(rReq);
91 pFunc->SetPermanent(bPermanent);
92 return xFunc;
95 void FuConstruct3dObject::DoExecute( SfxRequest& rReq )
97 FuConstruct::DoExecute( rReq );
98 mpViewShell->GetViewShellBase().GetToolBarManager()->SetToolBar(
99 ToolBarManager::TBG_FUNCTION,
100 ToolBarManager::msDrawingObjectToolBar);
103 /*************************************************************************
105 |* MouseButtonDown-event
107 \************************************************************************/
109 // #97016#
110 E3dCompoundObject* FuConstruct3dObject::ImpCreateBasic3DShape()
112 E3dCompoundObject* p3DObj = NULL;
114 switch (nSlotId)
116 default:
117 case SID_3D_CUBE:
119 p3DObj = new E3dCubeObj(
120 mpView->Get3DDefaultAttributes(),
121 ::basegfx::B3DPoint(-2500, -2500, -2500),
122 ::basegfx::B3DVector(5000, 5000, 5000));
123 break;
126 case SID_3D_SPHERE:
128 p3DObj = new E3dSphereObj(
129 mpView->Get3DDefaultAttributes(),
130 ::basegfx::B3DPoint(0, 0, 0),
131 ::basegfx::B3DVector(5000, 5000, 5000));
132 break;
135 case SID_3D_SHELL:
137 XPolygon aXPoly(Point (0, 1250), 2500, 2500, 0, 900, FALSE);
138 aXPoly.Scale(5.0, 5.0);
140 ::basegfx::B2DPolygon aB2DPolygon(aXPoly.getB2DPolygon());
141 if(aB2DPolygon.areControlPointsUsed())
143 aB2DPolygon = ::basegfx::tools::adaptiveSubdivideByAngle(aB2DPolygon);
145 p3DObj = new E3dLatheObj(mpView->Get3DDefaultAttributes(), ::basegfx::B2DPolyPolygon(aB2DPolygon));
147 // Dies ist ein offenes Objekt, muss daher defaultmaessig
148 // doppelseitig behandelt werden
149 p3DObj->SetMergedItem(Svx3DDoubleSidedItem(TRUE));
150 break;
153 case SID_3D_HALF_SPHERE:
155 XPolygon aXPoly(Point (0, 1250), 2500, 2500, 0, 900, FALSE);
156 aXPoly.Scale(5.0, 5.0);
158 aXPoly.Insert(0, Point (2400*5, 1250*5), XPOLY_NORMAL);
159 aXPoly.Insert(0, Point (2000*5, 1250*5), XPOLY_NORMAL);
160 aXPoly.Insert(0, Point (1500*5, 1250*5), XPOLY_NORMAL);
161 aXPoly.Insert(0, Point (1000*5, 1250*5), XPOLY_NORMAL);
162 aXPoly.Insert(0, Point (500*5, 1250*5), XPOLY_NORMAL);
163 aXPoly.Insert(0, Point (250*5, 1250*5), XPOLY_NORMAL);
164 aXPoly.Insert(0, Point (50*5, 1250*5), XPOLY_NORMAL);
165 aXPoly.Insert(0, Point (0*5, 1250*5), XPOLY_NORMAL);
167 ::basegfx::B2DPolygon aB2DPolygon(aXPoly.getB2DPolygon());
168 if(aB2DPolygon.areControlPointsUsed())
170 aB2DPolygon = ::basegfx::tools::adaptiveSubdivideByAngle(aB2DPolygon);
172 p3DObj = new E3dLatheObj(mpView->Get3DDefaultAttributes(), ::basegfx::B2DPolyPolygon(aB2DPolygon));
173 break;
176 case SID_3D_TORUS:
178 ::basegfx::B2DPolygon aB2DPolygon(::basegfx::tools::createPolygonFromCircle(::basegfx::B2DPoint(1000.0, 0.0), 500.0));
179 if(aB2DPolygon.areControlPointsUsed())
181 aB2DPolygon = ::basegfx::tools::adaptiveSubdivideByAngle(aB2DPolygon);
183 p3DObj = new E3dLatheObj(mpView->Get3DDefaultAttributes(), ::basegfx::B2DPolyPolygon(aB2DPolygon));
184 break;
187 case SID_3D_CYLINDER:
189 ::basegfx::B2DPolygon aInnerPoly;
191 aInnerPoly.append(::basegfx::B2DPoint(0, 1000*5));
192 aInnerPoly.append(::basegfx::B2DPoint(50*5, 1000*5));
193 aInnerPoly.append(::basegfx::B2DPoint(100*5, 1000*5));
194 aInnerPoly.append(::basegfx::B2DPoint(200*5, 1000*5));
195 aInnerPoly.append(::basegfx::B2DPoint(300*5, 1000*5));
196 aInnerPoly.append(::basegfx::B2DPoint(400*5, 1000*5));
197 aInnerPoly.append(::basegfx::B2DPoint(450*5, 1000*5));
198 aInnerPoly.append(::basegfx::B2DPoint(500*5, 1000*5));
199 aInnerPoly.append(::basegfx::B2DPoint(500*5, -1000*5));
200 aInnerPoly.append(::basegfx::B2DPoint(450*5, -1000*5));
201 aInnerPoly.append(::basegfx::B2DPoint(400*5, -1000*5));
202 aInnerPoly.append(::basegfx::B2DPoint(300*5, -1000*5));
203 aInnerPoly.append(::basegfx::B2DPoint(200*5, -1000*5));
204 aInnerPoly.append(::basegfx::B2DPoint(100*5, -1000*5));
205 aInnerPoly.append(::basegfx::B2DPoint(50*5, -1000*5));
206 aInnerPoly.append(::basegfx::B2DPoint(0*5, -1000*5));
207 aInnerPoly.setClosed(true);
209 p3DObj = new E3dLatheObj(mpView->Get3DDefaultAttributes(), ::basegfx::B2DPolyPolygon(aInnerPoly));
210 break;
213 case SID_3D_CONE:
215 ::basegfx::B2DPolygon aInnerPoly;
217 aInnerPoly.append(::basegfx::B2DPoint(0, -1000*5));
218 aInnerPoly.append(::basegfx::B2DPoint(25*5, -900*5));
219 aInnerPoly.append(::basegfx::B2DPoint(50*5, -800*5));
220 aInnerPoly.append(::basegfx::B2DPoint(100*5, -600*5));
221 aInnerPoly.append(::basegfx::B2DPoint(200*5, -200*5));
222 aInnerPoly.append(::basegfx::B2DPoint(300*5, 200*5));
223 aInnerPoly.append(::basegfx::B2DPoint(400*5, 600*5));
224 aInnerPoly.append(::basegfx::B2DPoint(500*5, 1000*5));
225 aInnerPoly.append(::basegfx::B2DPoint(400*5, 1000*5));
226 aInnerPoly.append(::basegfx::B2DPoint(300*5, 1000*5));
227 aInnerPoly.append(::basegfx::B2DPoint(200*5, 1000*5));
228 aInnerPoly.append(::basegfx::B2DPoint(100*5, 1000*5));
229 aInnerPoly.append(::basegfx::B2DPoint(50*5, 1000*5));
230 aInnerPoly.append(::basegfx::B2DPoint(0*5, 1000*5));
231 aInnerPoly.setClosed(true);
233 p3DObj = new E3dLatheObj(mpView->Get3DDefaultAttributes(), ::basegfx::B2DPolyPolygon(aInnerPoly));
234 break;
237 case SID_3D_PYRAMID:
239 ::basegfx::B2DPolygon aInnerPoly;
241 aInnerPoly.append(::basegfx::B2DPoint(0, -1000*5));
242 aInnerPoly.append(::basegfx::B2DPoint(25*5, -900*5));
243 aInnerPoly.append(::basegfx::B2DPoint(50*5, -800*5));
244 aInnerPoly.append(::basegfx::B2DPoint(100*5, -600*5));
245 aInnerPoly.append(::basegfx::B2DPoint(200*5, -200*5));
246 aInnerPoly.append(::basegfx::B2DPoint(300*5, 200*5));
247 aInnerPoly.append(::basegfx::B2DPoint(400*5, 600*5));
248 aInnerPoly.append(::basegfx::B2DPoint(500*5, 1000*5));
249 aInnerPoly.append(::basegfx::B2DPoint(400*5, 1000*5));
250 aInnerPoly.append(::basegfx::B2DPoint(300*5, 1000*5));
251 aInnerPoly.append(::basegfx::B2DPoint(200*5, 1000*5));
252 aInnerPoly.append(::basegfx::B2DPoint(100*5, 1000*5));
253 aInnerPoly.append(::basegfx::B2DPoint(50*5, 1000*5));
254 aInnerPoly.append(::basegfx::B2DPoint(0, 1000*5));
255 aInnerPoly.setClosed(true);
257 p3DObj = new E3dLatheObj(mpView->Get3DDefaultAttributes(), ::basegfx::B2DPolyPolygon(aInnerPoly));
258 p3DObj->SetMergedItem(Svx3DHorizontalSegmentsItem(4));
259 break;
263 return p3DObj;
266 // #97016#
267 void FuConstruct3dObject::ImpPrepareBasic3DShape(E3dCompoundObject* p3DObj, E3dScene *pScene)
269 Camera3D &aCamera = (Camera3D&) pScene->GetCamera ();
271 // get transformed BoundVolume of the new object
272 basegfx::B3DRange aBoundVol;
273 basegfx::B3DRange aObjVol(p3DObj->GetBoundVolume());
274 aObjVol.transform(p3DObj->GetTransform());
275 aBoundVol.expand(aObjVol);
276 double fDeepth(aBoundVol.getDepth());
278 aCamera.SetPRP(::basegfx::B3DPoint(0.0, 0.0, 1000.0));
279 aCamera.SetPosition(::basegfx::B3DPoint(0.0, 0.0, mpView->GetDefaultCamPosZ() + fDeepth / 2));
280 aCamera.SetFocalLength(mpView->GetDefaultCamFocal());
281 pScene->SetCamera(aCamera);
282 basegfx::B3DHomMatrix aTransformation;
284 switch (nSlotId)
286 case SID_3D_CUBE:
288 aTransformation.rotate(DEG2RAD(20), 0.0, 0.0);
290 break;
292 case SID_3D_SPHERE:
294 // pScene->RotateX(DEG2RAD(60));
296 break;
298 case SID_3D_SHELL:
299 case SID_3D_HALF_SPHERE:
301 aTransformation.rotate(DEG2RAD(200), 0.0, 0.0);
303 break;
305 case SID_3D_CYLINDER:
306 case SID_3D_CONE:
307 case SID_3D_PYRAMID:
309 // pScene->RotateX(DEG2RAD(25));
311 break;
313 case SID_3D_TORUS:
315 // pScene->RotateX(DEG2RAD(15));
316 aTransformation.rotate(DEG2RAD(90), 0.0, 0.0);
318 break;
320 default:
323 break;
326 pScene->SetTransform(aTransformation * pScene->GetTransform());
328 SfxItemSet aAttr (mpViewShell->GetPool());
329 pScene->SetMergedItemSetAndBroadcast(aAttr);
332 BOOL FuConstruct3dObject::MouseButtonDown(const MouseEvent& rMEvt)
334 BOOL bReturn = FuConstruct::MouseButtonDown(rMEvt);
336 if ( rMEvt.IsLeft() && !mpView->IsAction() )
338 Point aPnt( mpWindow->PixelToLogic( rMEvt.GetPosPixel() ) );
340 mpWindow->CaptureMouse();
341 USHORT nDrgLog = USHORT ( mpWindow->PixelToLogic(Size(DRGPIX,0)).Width() );
343 E3dCompoundObject* p3DObj = NULL;
345 WaitObject aWait( (Window*)mpViewShell->GetActiveWindow() );
347 // #97016#
348 p3DObj = ImpCreateBasic3DShape();
349 E3dScene* pScene = mpView->SetCurrent3DObj(p3DObj);
351 // #97016#
352 ImpPrepareBasic3DShape(p3DObj, pScene);
353 bReturn = mpView->BegCreatePreparedObject(aPnt, nDrgLog, pScene);
355 SdrObject* pObj = mpView->GetCreateObj();
357 if (pObj)
359 SfxItemSet aAttr(mpDoc->GetPool());
360 SetStyleSheet(aAttr, pObj);
362 // LineStyle rausnehmen
363 aAttr.Put(XLineStyleItem (XLINE_NONE));
365 pObj->SetMergedItemSet(aAttr);
369 return bReturn;
372 /*************************************************************************
374 |* MouseMove-event
376 \************************************************************************/
378 BOOL FuConstruct3dObject::MouseMove(const MouseEvent& rMEvt)
380 return FuConstruct::MouseMove(rMEvt);
383 /*************************************************************************
385 |* MouseButtonUp-event
387 \************************************************************************/
389 BOOL FuConstruct3dObject::MouseButtonUp(const MouseEvent& rMEvt)
391 BOOL bReturn = FALSE;
393 if ( mpView->IsCreateObj() && rMEvt.IsLeft() )
395 Point aPnt( mpWindow->PixelToLogic( rMEvt.GetPosPixel() ) );
396 mpView->EndCreateObj(SDRCREATE_FORCEEND);
397 bReturn = TRUE;
400 bReturn = FuConstruct::MouseButtonUp(rMEvt) || bReturn;
402 if (!bPermanent)
403 mpViewShell->GetViewFrame()->GetDispatcher()->Execute(SID_OBJECT_SELECT, SFX_CALLMODE_ASYNCHRON);
405 return bReturn;
408 /*************************************************************************
410 |* Tastaturereignisse bearbeiten
412 |* Wird ein KeyEvent bearbeitet, so ist der Return-Wert TRUE, andernfalls
413 |* FALSE.
415 \************************************************************************/
417 BOOL FuConstruct3dObject::KeyInput(const KeyEvent& rKEvt)
419 return( FuConstruct::KeyInput(rKEvt) );
422 /*************************************************************************
424 |* Function aktivieren
426 \************************************************************************/
428 void FuConstruct3dObject::Activate()
430 mpView->SetCurrentObj(OBJ_NONE);
432 FuConstruct::Activate();
435 /*************************************************************************
437 |* Function deaktivieren
439 \************************************************************************/
441 void FuConstruct3dObject::Deactivate()
443 FuConstruct::Deactivate();
446 // #97016#
447 SdrObject* FuConstruct3dObject::CreateDefaultObject(const sal_uInt16 nID, const Rectangle& rRectangle)
449 // case SID_3D_CUBE:
450 // case SID_3D_SHELL:
451 // case SID_3D_SPHERE:
452 // case SID_3D_TORUS:
453 // case SID_3D_HALF_SPHERE:
454 // case SID_3D_CYLINDER:
455 // case SID_3D_CONE:
456 // case SID_3D_PYRAMID:
458 E3dCompoundObject* p3DObj = ImpCreateBasic3DShape();
460 // E3dView::SetCurrent3DObj part
461 // get transformed BoundVolume of the object
462 basegfx::B3DRange aObjVol(p3DObj->GetBoundVolume());
463 aObjVol.transform(p3DObj->GetTransform());
464 basegfx::B3DRange aVolume(aObjVol);
465 double fW(aVolume.getWidth());
466 double fH(aVolume.getHeight());
467 Rectangle a3DRect(0, 0, (long)fW, (long)fH);
468 E3dScene* pScene = new E3dPolyScene(mpView->Get3DDefaultAttributes());
470 // mpView->InitScene(pScene, fW, fH, aVolume.MaxVec().Z() + ((fW + fH) / 4.0));
471 // copied code from E3dView::InitScene
472 double fCamZ(aVolume.getMaxZ() + ((fW + fH) / 4.0));
473 Camera3D aCam(pScene->GetCamera());
474 aCam.SetAutoAdjustProjection(FALSE);
475 aCam.SetViewWindow(- fW / 2, - fH / 2, fW, fH);
476 ::basegfx::B3DPoint aLookAt;
477 double fDefaultCamPosZ = mpView->GetDefaultCamPosZ();
478 ::basegfx::B3DPoint aCamPos(0.0, 0.0, fCamZ < fDefaultCamPosZ ? fDefaultCamPosZ : fCamZ);
479 aCam.SetPosAndLookAt(aCamPos, aLookAt);
480 aCam.SetFocalLength(mpView->GetDefaultCamFocal());
481 aCam.SetDefaults(::basegfx::B3DPoint(0.0, 0.0, fDefaultCamPosZ), aLookAt, mpView->GetDefaultCamFocal());
482 pScene->SetCamera(aCam);
484 pScene->Insert3DObj(p3DObj);
485 pScene->NbcSetSnapRect(a3DRect);
486 pScene->SetModel(mpDoc);
488 ImpPrepareBasic3DShape(p3DObj, pScene);
490 SfxItemSet aAttr(mpDoc->GetPool());
491 SetStyleSheet(aAttr, p3DObj);
492 aAttr.Put(XLineStyleItem (XLINE_NONE));
493 p3DObj->SetMergedItemSet(aAttr);
495 // make object interactive at once
496 pScene->SetRectsDirty();
498 // Take care of restrictions for the rectangle
499 Rectangle aRect(rRectangle);
501 switch(nID)
503 case SID_3D_CUBE:
504 case SID_3D_SPHERE:
505 case SID_3D_TORUS:
507 // force quadratic
508 ImpForceQuadratic(aRect);
509 break;
512 case SID_3D_SHELL:
513 case SID_3D_HALF_SPHERE:
515 // force horizontal layout
516 break;
519 case SID_3D_CYLINDER:
520 case SID_3D_CONE:
521 case SID_3D_PYRAMID:
523 // force vertical layout
524 break;
528 // #97016#, #98245# use changed rectangle, not original one
529 pScene->SetLogicRect(aRect);
531 return pScene;
534 } // end of namespace sd