Update ooo320-m1
[ooovba.git] / svx / source / dialog / dlgctl3d.cxx
blobfe75592b6e9409dfa7117bccb7ecdbfc5b4f6ec2
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: dlgctl3d.cxx,v $
10 * $Revision: 1.20.226.2 $
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_svx.hxx"
34 #include <svx/dlgctl3d.hxx>
35 #include <svx/dialogs.hrc>
36 #include <svx/view3d.hxx>
37 #include <svx/fmmodel.hxx>
38 #include <svtools/itempool.hxx>
39 #include <svx/fmpage.hxx>
40 #include <svx/polysc3d.hxx>
41 #include <svx/sphere3d.hxx>
42 #include <svx/cube3d.hxx>
43 #include <vcl/svapp.hxx>
44 #include <svx/helperhittest3d.hxx>
45 #include <basegfx/polygon/b2dpolygontools.hxx>
46 #include <svx/polygn3d.hxx>
47 #include <svx/xlnclit.hxx>
48 #include <svx/xlnwtit.hxx>
49 #include "helpid.hrc"
50 #include <algorithm>
52 //////////////////////////////////////////////////////////////////////////////
54 Svx3DPreviewControl::Svx3DPreviewControl(Window* pParent, const ResId& rResId)
55 : Control(pParent, rResId),
56 mpModel(0),
57 mpFmPage(0),
58 mp3DView(0),
59 mpScene(0),
60 mp3DObj(0),
61 mnObjectType(PREVIEW_OBJECTTYPE_SPHERE)
63 Construct();
65 // do not paint background self, DrawingLayer paints this buffered and as page
66 SetControlBackground();
67 SetBackground();
70 Svx3DPreviewControl::Svx3DPreviewControl(Window* pParent, WinBits nStyle)
71 : Control(pParent, nStyle),
72 mpModel(0),
73 mpFmPage(0),
74 mp3DView(0),
75 mpScene(0),
76 mp3DObj(0),
77 mnObjectType(PREVIEW_OBJECTTYPE_SPHERE)
79 Construct();
81 // do not paint background self, DrawingLayer paints this buffered and as page
82 SetControlBackground();
83 SetBackground();
86 Svx3DPreviewControl::~Svx3DPreviewControl()
88 delete mp3DView;
89 delete mpModel;
92 void Svx3DPreviewControl::Construct()
94 // Do never mirror the preview window. This explicitly includes right
95 // to left writing environments.
96 EnableRTL (FALSE);
97 SetMapMode( MAP_100TH_MM );
99 // Model
100 mpModel = new FmFormModel();
101 mpModel->GetItemPool().FreezeIdRanges();
103 // Page
104 mpFmPage = new FmFormPage( *mpModel, NULL );
105 mpModel->InsertPage( mpFmPage, 0 );
107 // 3D View
108 mp3DView = new E3dView( mpModel, this );
109 mp3DView->SetBufferedOutputAllowed(true);
110 mp3DView->SetBufferedOverlayAllowed(true);
112 // 3D Scene
113 mpScene = new E3dPolyScene(mp3DView->Get3DDefaultAttributes());
115 // initially create object
116 SetObjectType(PREVIEW_OBJECTTYPE_SPHERE);
118 // camera and perspective
119 Camera3D& rCamera = (Camera3D&) mpScene->GetCamera();
120 const basegfx::B3DRange& rVolume = mpScene->GetBoundVolume();
121 double fW = rVolume.getWidth();
122 double fH = rVolume.getHeight();
123 double fCamZ = rVolume.getMaxZ() + ((fW + fH) / 2.0);
125 rCamera.SetAutoAdjustProjection(FALSE);
126 rCamera.SetViewWindow(- fW / 2, - fH / 2, fW, fH);
127 basegfx::B3DPoint aLookAt;
128 double fDefaultCamPosZ = mp3DView->GetDefaultCamPosZ();
129 basegfx::B3DPoint aCamPos(0.0, 0.0, fCamZ < fDefaultCamPosZ ? fDefaultCamPosZ : fCamZ);
130 rCamera.SetPosAndLookAt(aCamPos, aLookAt);
131 double fDefaultCamFocal = mp3DView->GetDefaultCamFocal();
132 rCamera.SetFocalLength(fDefaultCamFocal);
133 rCamera.SetDefaults(basegfx::B3DPoint(0.0, 0.0, fDefaultCamPosZ), aLookAt, fDefaultCamFocal);
135 mpScene->SetCamera( rCamera );
136 mpFmPage->InsertObject( mpScene );
138 basegfx::B3DHomMatrix aRotation;
139 aRotation.rotate(DEG2RAD( 25 ), 0.0, 0.0);
140 aRotation.rotate(0.0, DEG2RAD( 40 ), 0.0);
141 mpScene->SetTransform(aRotation * mpScene->GetTransform());
143 // invalidate SnapRects of objects
144 mpScene->SetRectsDirty();
146 SfxItemSet aSet( mpModel->GetItemPool(),
147 XATTR_LINESTYLE, XATTR_LINESTYLE,
148 XATTR_FILL_FIRST, XATTR_FILLBITMAP,
149 0, 0 );
150 aSet.Put( XLineStyleItem( XLINE_NONE ) );
151 aSet.Put( XFillStyleItem( XFILL_SOLID ) );
152 aSet.Put( XFillColorItem( String(), Color( COL_WHITE ) ) );
154 mpScene->SetMergedItemSet(aSet);
156 // PageView
157 SdrPageView* pPageView = mp3DView->ShowSdrPage( mpFmPage );
158 mp3DView->hideMarkHandles();
160 // mark scene
161 mp3DView->MarkObj( mpScene, pPageView );
164 void Svx3DPreviewControl::Resize()
166 // size of page
167 Size aSize( GetSizePixel() );
168 aSize = PixelToLogic( aSize );
169 mpFmPage->SetSize( aSize );
171 // set size
172 Size aObjSize( aSize.Width()*5/6, aSize.Height()*5/6 );
173 Point aObjPoint( (aSize.Width() - aObjSize.Width()) / 2,
174 (aSize.Height() - aObjSize.Height()) / 2);
175 Rectangle aRect( aObjPoint, aObjSize);
176 mpScene->SetSnapRect( aRect );
179 void Svx3DPreviewControl::Paint(const Rectangle& rRect)
181 mp3DView->CompleteRedraw(this, Region(rRect));
184 void Svx3DPreviewControl::MouseButtonDown(const MouseEvent& rMEvt)
186 Control::MouseButtonDown(rMEvt);
188 if( rMEvt.IsShift() && rMEvt.IsMod1() )
190 if(PREVIEW_OBJECTTYPE_SPHERE == GetObjectType())
192 SetObjectType(PREVIEW_OBJECTTYPE_CUBE);
194 else
196 SetObjectType(PREVIEW_OBJECTTYPE_SPHERE);
201 void Svx3DPreviewControl::SetObjectType(sal_uInt16 nType)
203 if( mnObjectType != nType || !mp3DObj)
205 SfxItemSet aSet(mpModel->GetItemPool(), SDRATTR_START, SDRATTR_END, 0, 0);
206 mnObjectType = nType;
208 if( mp3DObj )
210 aSet.Put(mp3DObj->GetMergedItemSet());
211 mpScene->Remove3DObj( mp3DObj );
212 delete mp3DObj;
213 mp3DObj = NULL;
216 switch( nType )
218 case PREVIEW_OBJECTTYPE_SPHERE:
220 mp3DObj = new E3dSphereObj(
221 mp3DView->Get3DDefaultAttributes(),
222 basegfx::B3DPoint( 0, 0, 0 ),
223 basegfx::B3DVector( 5000, 5000, 5000 ));
225 break;
227 case PREVIEW_OBJECTTYPE_CUBE:
229 mp3DObj = new E3dCubeObj(
230 mp3DView->Get3DDefaultAttributes(),
231 basegfx::B3DPoint( -2500, -2500, -2500 ),
232 basegfx::B3DVector( 5000, 5000, 5000 ));
234 break;
237 mpScene->Insert3DObj( mp3DObj );
238 mp3DObj->SetMergedItemSet(aSet);
240 Resize();
244 SfxItemSet Svx3DPreviewControl::Get3DAttributes() const
246 return mp3DObj->GetMergedItemSet();
249 void Svx3DPreviewControl::Set3DAttributes( const SfxItemSet& rAttr )
251 mp3DObj->SetMergedItemSet(rAttr, true);
252 Resize();
255 //////////////////////////////////////////////////////////////////////////////
257 #define RADIUS_LAMP_PREVIEW_SIZE (4500.0)
258 #define RADIUS_LAMP_SMALL (600.0)
259 #define RADIUS_LAMP_BIG (1000.0)
260 #define NO_LIGHT_SELECTED (0xffffffff)
261 #define MAX_NUMBER_LIGHTS (8)
263 Svx3DLightControl::Svx3DLightControl(Window* pParent, const ResId& rResId)
264 : Svx3DPreviewControl(pParent, rResId),
265 maUserInteractiveChangeCallback(),
266 maUserSelectionChangeCallback(),
267 maChangeCallback(),
268 maSelectionChangeCallback(),
269 maSelectedLight(NO_LIGHT_SELECTED),
270 mpExpansionObject(0),
271 mpLampBottomObject(0),
272 mpLampShaftObject(0),
273 maLightObjects(MAX_NUMBER_LIGHTS, (E3dObject*)0),
274 mfRotateX(-20.0),
275 mfRotateY(45.0),
276 mfRotateZ(0.0),
277 maActionStartPoint(),
278 mnInteractionStartDistance(5 * 5 * 2),
279 mfSaveActionStartHor(0.0),
280 mfSaveActionStartVer(0.0),
281 mfSaveActionStartRotZ(0.0),
282 mbMouseMoved(false),
283 mbGeometrySelected(false)
285 Construct2();
288 Svx3DLightControl::Svx3DLightControl(Window* pParent, WinBits nStyle)
289 : Svx3DPreviewControl(pParent, nStyle),
290 maUserInteractiveChangeCallback(),
291 maUserSelectionChangeCallback(),
292 maChangeCallback(),
293 maSelectionChangeCallback(),
294 maSelectedLight(NO_LIGHT_SELECTED),
295 mpExpansionObject(0),
296 mpLampBottomObject(0),
297 mpLampShaftObject(0),
298 maLightObjects(MAX_NUMBER_LIGHTS, (E3dObject*)0),
299 mfRotateX(-20.0),
300 mfRotateY(45.0),
301 mfRotateZ(0.0),
302 maActionStartPoint(),
303 mnInteractionStartDistance(5 * 5 * 2),
304 mfSaveActionStartHor(0.0),
305 mfSaveActionStartVer(0.0),
306 mfSaveActionStartRotZ(0.0),
307 mbMouseMoved(false),
308 mbGeometrySelected(false)
310 Construct2();
313 Svx3DLightControl::~Svx3DLightControl()
315 // SdrObjects like mpExpansionObject and mpLampBottomObject/mpLampShaftObject get deleted
316 // with deletion of the DrawingLayer and model
319 void Svx3DLightControl::Construct2()
322 // hide all page stuff, use control background (normally gray)
323 const Color aDialogColor(Application::GetSettings().GetStyleSettings().GetDialogColor());
324 mp3DView->SetPageVisible(false);
325 mp3DView->SetApplicationBackgroundColor(aDialogColor);
326 mp3DView->SetApplicationDocumentColor(aDialogColor);
330 // create invisible expansion object
331 const double fMaxExpansion(RADIUS_LAMP_BIG + RADIUS_LAMP_PREVIEW_SIZE);
332 mpExpansionObject = new E3dCubeObj(
333 mp3DView->Get3DDefaultAttributes(),
334 basegfx::B3DPoint(-fMaxExpansion, -fMaxExpansion, -fMaxExpansion),
335 basegfx::B3DVector(2.0 * fMaxExpansion, 2.0 * fMaxExpansion, 2.0 * fMaxExpansion));
336 mpScene->Insert3DObj( mpExpansionObject );
337 SfxItemSet aSet(mpModel->GetItemPool());
338 aSet.Put( XLineStyleItem( XLINE_NONE ) );
339 aSet.Put( XFillStyleItem( XFILL_NONE ) );
340 mpExpansionObject->SetMergedItemSet(aSet);
344 // create lamp control object (Yellow lined object)
345 // base circle
346 const basegfx::B2DPolygon a2DCircle(basegfx::tools::createPolygonFromCircle(basegfx::B2DPoint(0.0, 0.0), RADIUS_LAMP_PREVIEW_SIZE));
347 basegfx::B3DPolygon a3DCircle(basegfx::tools::createB3DPolygonFromB2DPolygon(a2DCircle));
348 basegfx::B3DHomMatrix aTransform;
350 aTransform.rotate(F_PI2, 0.0, 0.0);
351 aTransform.translate(0.0, -RADIUS_LAMP_PREVIEW_SIZE, 0.0);
352 a3DCircle.transform(aTransform);
354 // create object for it
355 mpLampBottomObject = new E3dPolygonObj(
356 mp3DView->Get3DDefaultAttributes(),
357 basegfx::B3DPolyPolygon(a3DCircle),
358 true);
359 mpScene->Insert3DObj( mpLampBottomObject );
361 // half circle with stand
362 basegfx::B2DPolygon a2DHalfCircle;
363 a2DHalfCircle.append(basegfx::B2DPoint(RADIUS_LAMP_PREVIEW_SIZE, 0.0));
364 a2DHalfCircle.append(basegfx::B2DPoint(RADIUS_LAMP_PREVIEW_SIZE, -RADIUS_LAMP_PREVIEW_SIZE));
365 a2DHalfCircle.append(basegfx::tools::createPolygonFromEllipseSegment(
366 basegfx::B2DPoint(0.0, 0.0), RADIUS_LAMP_PREVIEW_SIZE, RADIUS_LAMP_PREVIEW_SIZE, F_2PI - F_PI2, F_PI2));
367 basegfx::B3DPolygon a3DHalfCircle(basegfx::tools::createB3DPolygonFromB2DPolygon(a2DHalfCircle));
369 // create object for it
370 mpLampShaftObject = new E3dPolygonObj(
371 mp3DView->Get3DDefaultAttributes(),
372 basegfx::B3DPolyPolygon(a3DHalfCircle),
373 true);
374 mpScene->Insert3DObj( mpLampShaftObject );
376 // initially invisible
377 SfxItemSet aSet(mpModel->GetItemPool());
378 aSet.Put( XLineStyleItem( XLINE_NONE ) );
379 aSet.Put( XFillStyleItem( XFILL_NONE ) );
381 mpLampBottomObject->SetMergedItemSet(aSet);
382 mpLampShaftObject->SetMergedItemSet(aSet);
386 // change camera settings
387 Camera3D& rCamera = (Camera3D&) mpScene->GetCamera();
388 const basegfx::B3DRange& rVolume = mpScene->GetBoundVolume();
389 double fW = rVolume.getWidth();
390 double fH = rVolume.getHeight();
391 double fCamZ = rVolume.getMaxZ() + ((fW + fH) / 2.0);
393 rCamera.SetAutoAdjustProjection(FALSE);
394 rCamera.SetViewWindow(- fW / 2, - fH / 2, fW, fH);
395 basegfx::B3DPoint aLookAt;
396 double fDefaultCamPosZ = mp3DView->GetDefaultCamPosZ();
397 basegfx::B3DPoint aCamPos(0.0, 0.0, fCamZ < fDefaultCamPosZ ? fDefaultCamPosZ : fCamZ);
398 rCamera.SetPosAndLookAt(aCamPos, aLookAt);
399 double fDefaultCamFocal = mp3DView->GetDefaultCamFocal();
400 rCamera.SetFocalLength(fDefaultCamFocal);
401 rCamera.SetDefaults(basegfx::B3DPoint(0.0, 0.0, fDefaultCamPosZ), aLookAt, fDefaultCamFocal);
403 mpScene->SetCamera( rCamera );
405 basegfx::B3DHomMatrix aNeutral;
406 mpScene->SetTransform(aNeutral);
409 // invalidate SnapRects of objects
410 mpScene->SetRectsDirty();
413 void Svx3DLightControl::ConstructLightObjects()
415 for(sal_uInt32 a(0); a < MAX_NUMBER_LIGHTS; a++)
417 // get rid of evtl. existing light object
418 if(maLightObjects[a])
420 mpScene->Remove3DObj(maLightObjects[a]);
421 delete maLightObjects[a];
422 maLightObjects[a] = 0;
425 if(GetLightOnOff(a))
427 const bool bIsSelectedLight(a == maSelectedLight);
428 basegfx::B3DVector aDirection(GetLightDirection(a));
429 aDirection.normalize();
430 aDirection *= RADIUS_LAMP_PREVIEW_SIZE;
432 const double fLampSize(bIsSelectedLight ? RADIUS_LAMP_BIG : RADIUS_LAMP_SMALL);
433 E3dObject* pNewLight = new E3dSphereObj(
434 mp3DView->Get3DDefaultAttributes(),
435 basegfx::B3DPoint( 0, 0, 0 ),
436 basegfx::B3DVector( fLampSize, fLampSize, fLampSize));
437 mpScene->Insert3DObj(pNewLight);
439 basegfx::B3DHomMatrix aTransform;
440 aTransform.translate(aDirection.getX(), aDirection.getY(), aDirection.getZ());
441 pNewLight->SetTransform(aTransform);
443 SfxItemSet aSet(mpModel->GetItemPool());
444 aSet.Put( XLineStyleItem( XLINE_NONE ) );
445 aSet.Put( XFillStyleItem( XFILL_SOLID ) );
446 aSet.Put( XFillColorItem(String(), GetLightColor(a)));
447 pNewLight->SetMergedItemSet(aSet);
449 maLightObjects[a] = pNewLight;
454 void Svx3DLightControl::AdaptToSelectedLight()
456 if(NO_LIGHT_SELECTED == maSelectedLight)
458 // make mpLampBottomObject/mpLampShaftObject invisible
459 SfxItemSet aSet(mpModel->GetItemPool());
460 aSet.Put( XLineStyleItem( XLINE_NONE ) );
461 aSet.Put( XFillStyleItem( XFILL_NONE ) );
462 mpLampBottomObject->SetMergedItemSet(aSet);
463 mpLampShaftObject->SetMergedItemSet(aSet);
465 else
467 basegfx::B3DVector aDirection(GetLightDirection(maSelectedLight));
468 aDirection.normalize();
470 // make mpLampBottomObject/mpLampShaftObject visible (yellow hairline)
471 SfxItemSet aSet(mpModel->GetItemPool());
472 aSet.Put( XLineStyleItem( XLINE_SOLID ) );
473 aSet.Put( XLineColorItem(String(), COL_YELLOW));
474 aSet.Put( XLineWidthItem(0));
475 aSet.Put( XFillStyleItem( XFILL_NONE ) );
476 mpLampBottomObject->SetMergedItemSet(aSet);
477 mpLampShaftObject->SetMergedItemSet(aSet);
479 // adapt transformation of mpLampShaftObject
480 basegfx::B3DHomMatrix aTransform;
481 double fRotateY(0.0);
483 if(!basegfx::fTools::equalZero(aDirection.getZ()) || !basegfx::fTools::equalZero(aDirection.getX()))
485 fRotateY = atan2(-aDirection.getZ(), aDirection.getX());
488 aTransform.rotate(0.0, fRotateY, 0.0);
489 mpLampShaftObject->SetTransform(aTransform);
491 // adapt transformation of selected light
492 E3dObject* pSelectedLight = maLightObjects[sal_Int32(maSelectedLight)];
494 if(pSelectedLight)
496 aTransform.identity();
497 aTransform.translate(
498 aDirection.getX() * RADIUS_LAMP_PREVIEW_SIZE,
499 aDirection.getY() * RADIUS_LAMP_PREVIEW_SIZE,
500 aDirection.getZ() * RADIUS_LAMP_PREVIEW_SIZE);
501 pSelectedLight->SetTransform(aTransform);
506 void Svx3DLightControl::TrySelection(Point aPosPixel)
508 if(mpScene)
510 const Point aPosLogic(PixelToLogic(aPosPixel));
511 const basegfx::B2DPoint aPoint(aPosLogic.X(), aPosLogic.Y());
512 std::vector< const E3dCompoundObject* > aResult;
513 getAllHit3DObjectsSortedFrontToBack(aPoint, *mpScene, aResult);
515 if(aResult.size())
517 // take the frontmost one
518 const E3dCompoundObject* pResult = aResult[0];
520 if(pResult == mp3DObj)
522 if(!mbGeometrySelected)
524 mbGeometrySelected = true;
525 maSelectedLight = NO_LIGHT_SELECTED;
526 ConstructLightObjects();
527 AdaptToSelectedLight();
528 Invalidate();
530 if(maSelectionChangeCallback.IsSet())
532 maSelectionChangeCallback.Call(this);
536 else
538 sal_uInt32 aNewSelectedLight(NO_LIGHT_SELECTED);
540 for(sal_uInt32 a(0); a < MAX_NUMBER_LIGHTS; a++)
542 if(maLightObjects[a] && maLightObjects[a] == pResult)
544 aNewSelectedLight = a;
548 if(aNewSelectedLight != maSelectedLight)
550 SelectLight(aNewSelectedLight);
552 if(maSelectionChangeCallback.IsSet())
554 maSelectionChangeCallback.Call(this);
562 void Svx3DLightControl::Paint(const Rectangle& rRect)
564 Svx3DPreviewControl::Paint(rRect);
567 void Svx3DLightControl::MouseButtonDown( const MouseEvent& rMEvt )
569 bool bCallParent(true);
571 // switch state
572 if(rMEvt.IsLeft())
574 if(IsSelectionValid() || mbGeometrySelected)
576 mbMouseMoved = false;
577 bCallParent = false;
578 maActionStartPoint = rMEvt.GetPosPixel();
579 StartTracking();
581 else
583 // Einfacher Click ohne viel Bewegen, versuche eine
584 // Selektion
585 TrySelection(rMEvt.GetPosPixel());
586 bCallParent = false;
590 // call parent
591 if(bCallParent)
593 Svx3DPreviewControl::MouseButtonDown(rMEvt);
597 void Svx3DLightControl::Tracking( const TrackingEvent& rTEvt )
599 if(rTEvt.IsTrackingEnded())
601 if(rTEvt.IsTrackingCanceled())
603 if(mbMouseMoved)
605 // interrupt tracking
606 mbMouseMoved = false;
608 if(mbGeometrySelected)
610 SetRotation(mfSaveActionStartVer, mfSaveActionStartHor, mfSaveActionStartRotZ);
612 else
614 SetPosition(mfSaveActionStartHor, mfSaveActionStartVer);
617 if(maChangeCallback.IsSet())
619 maChangeCallback.Call(this);
623 else
625 const MouseEvent& rMEvt = rTEvt.GetMouseEvent();
627 if(mbMouseMoved)
629 // was change dinteractively
631 else
633 // simple click without much movement, try selection
634 TrySelection(rMEvt.GetPosPixel());
638 else
640 const MouseEvent& rMEvt = rTEvt.GetMouseEvent();
641 Point aDeltaPos = rMEvt.GetPosPixel() - maActionStartPoint;
643 if(!mbMouseMoved)
645 if(sal_Int32(aDeltaPos.X() * aDeltaPos.X() + aDeltaPos.Y() * aDeltaPos.Y()) > mnInteractionStartDistance)
647 if(mbGeometrySelected)
649 GetRotation(mfSaveActionStartVer, mfSaveActionStartHor, mfSaveActionStartRotZ);
651 else
653 // intercation start, save values
654 GetPosition(mfSaveActionStartHor, mfSaveActionStartVer);
657 mbMouseMoved = true;
661 if(mbMouseMoved)
663 if(mbGeometrySelected)
665 double fNewRotX = mfSaveActionStartVer - ((double)aDeltaPos.Y() * F_PI180);
666 double fNewRotY = mfSaveActionStartHor + ((double)aDeltaPos.X() * F_PI180);
668 // cut horizontal
669 while(fNewRotY < 0.0)
671 fNewRotY += F_2PI;
674 while(fNewRotY >= F_2PI)
676 fNewRotY -= F_2PI;
679 // cut vertical
680 if(fNewRotX < -F_PI2)
682 fNewRotX = -F_PI2;
685 if(fNewRotX > F_PI2)
687 fNewRotX = F_PI2;
690 SetRotation(fNewRotX, fNewRotY, mfSaveActionStartRotZ);
692 if(maChangeCallback.IsSet())
694 maChangeCallback.Call(this);
697 else
699 // interaction in progress
700 double fNewPosHor = mfSaveActionStartHor + ((double)aDeltaPos.X());
701 double fNewPosVer = mfSaveActionStartVer - ((double)aDeltaPos.Y());
703 // cut horizontal
704 while(fNewPosHor < 0.0)
706 fNewPosHor += 360.0;
709 while(fNewPosHor >= 360.0)
711 fNewPosHor -= 360.0;
714 // cut vertical
715 if(fNewPosVer < -90.0)
717 fNewPosVer = -90.0;
720 if(fNewPosVer > 90.0)
722 fNewPosVer = 90.0;
725 SetPosition(fNewPosHor, fNewPosVer);
727 if(maChangeCallback.IsSet())
729 maChangeCallback.Call(this);
736 void Svx3DLightControl::Resize()
738 // set size of page
739 const Size aSize(PixelToLogic(GetSizePixel()));
740 mpFmPage->SetSize(aSize);
742 // set position and size of scene
743 mpScene->SetSnapRect(Rectangle(Point(0, 0), aSize));
746 void Svx3DLightControl::SetObjectType(sal_uInt16 nType)
748 // call parent
749 Svx3DPreviewControl::SetObjectType(nType);
751 // apply object rotation
752 if(mp3DObj)
754 basegfx::B3DHomMatrix aObjectRotation;
755 aObjectRotation.rotate(mfRotateX, mfRotateY, mfRotateZ);
756 mp3DObj->SetTransform(aObjectRotation);
760 bool Svx3DLightControl::IsSelectionValid()
762 if((NO_LIGHT_SELECTED != maSelectedLight) && (GetLightOnOff(maSelectedLight)))
764 return true;
767 return false;
770 void Svx3DLightControl::GetPosition(double& rHor, double& rVer)
772 if(IsSelectionValid())
774 basegfx::B3DVector aDirection(GetLightDirection(maSelectedLight));
775 aDirection.normalize();
776 rHor = atan2(-aDirection.getX(), -aDirection.getZ()) + F_PI; // 0..2PI
777 rVer = atan2(aDirection.getY(), aDirection.getXZLength()); // -PI2..PI2
778 rHor /= F_PI180; // 0..360.0
779 rVer /= F_PI180; // -90.0..90.0
781 if(IsGeometrySelected())
783 rHor = mfRotateY;
784 rVer = mfRotateX;
788 void Svx3DLightControl::SetPosition(double fHor, double fVer)
790 if(IsSelectionValid())
792 // set selected light's direction
793 fHor = (fHor * F_PI180) - F_PI; // -PI..PI
794 fVer *= F_PI180; // -PI2..PI2
795 basegfx::B3DVector aDirection(cos(fVer) * -sin(fHor), sin(fVer), cos(fVer) * -cos(fHor));
796 aDirection.normalize();
798 if(!aDirection.equal(GetLightDirection(maSelectedLight)))
800 // set changed light direction at SdrScene
801 SfxItemSet aSet(mpModel->GetItemPool());
803 switch(maSelectedLight)
805 case 0: aSet.Put(Svx3DLightDirection1Item(aDirection)); break;
806 case 1: aSet.Put(Svx3DLightDirection2Item(aDirection)); break;
807 case 2: aSet.Put(Svx3DLightDirection3Item(aDirection)); break;
808 case 3: aSet.Put(Svx3DLightDirection4Item(aDirection)); break;
809 case 4: aSet.Put(Svx3DLightDirection5Item(aDirection)); break;
810 case 5: aSet.Put(Svx3DLightDirection6Item(aDirection)); break;
811 case 6: aSet.Put(Svx3DLightDirection7Item(aDirection)); break;
812 default:
813 case 7: aSet.Put(Svx3DLightDirection8Item(aDirection)); break;
816 mpScene->SetMergedItemSet(aSet);
818 // correct 3D light's and LampFrame's geometries
819 AdaptToSelectedLight();
820 Invalidate();
823 if(IsGeometrySelected())
825 if(mfRotateX != fVer || mfRotateY != fHor)
827 mfRotateX = fVer;
828 mfRotateY = fHor;
830 if(mp3DObj)
832 basegfx::B3DHomMatrix aObjectRotation;
833 aObjectRotation.rotate(mfRotateX, mfRotateY, mfRotateZ);
834 mp3DObj->SetTransform(aObjectRotation);
836 Invalidate();
842 void Svx3DLightControl::SetRotation(double fRotX, double fRotY, double fRotZ)
844 if(IsGeometrySelected())
846 if(fRotX != mfRotateX || fRotY != mfRotateY || fRotZ != mfRotateZ)
848 mfRotateX = fRotX;
849 mfRotateY = fRotY;
850 mfRotateZ = fRotZ;
852 if(mp3DObj)
854 basegfx::B3DHomMatrix aObjectRotation;
855 aObjectRotation.rotate(mfRotateX, mfRotateY, mfRotateZ);
856 mp3DObj->SetTransform(aObjectRotation);
858 Invalidate();
864 void Svx3DLightControl::GetRotation(double& rRotX, double& rRotY, double& rRotZ)
866 rRotX = mfRotateX;
867 rRotY = mfRotateY;
868 rRotZ = mfRotateZ;
871 void Svx3DLightControl::Set3DAttributes( const SfxItemSet& rAttr )
873 // call parent
874 Svx3DPreviewControl::Set3DAttributes(rAttr);
876 if(maSelectedLight != NO_LIGHT_SELECTED && !GetLightOnOff(maSelectedLight))
878 // selected light is no more active, select new one
879 maSelectedLight = NO_LIGHT_SELECTED;
882 // local updates
883 ConstructLightObjects();
884 AdaptToSelectedLight();
885 Invalidate();
888 void Svx3DLightControl::SelectLight(sal_uInt32 nLightNumber)
890 if(nLightNumber > 7)
892 nLightNumber = NO_LIGHT_SELECTED;
895 if(NO_LIGHT_SELECTED != nLightNumber)
897 if(!GetLightOnOff(nLightNumber))
899 nLightNumber = NO_LIGHT_SELECTED;
903 if(nLightNumber != maSelectedLight)
905 maSelectedLight = nLightNumber;
906 mbGeometrySelected = false;
907 ConstructLightObjects();
908 AdaptToSelectedLight();
909 Invalidate();
913 bool Svx3DLightControl::GetLightOnOff(sal_uInt32 nNum) const
915 if(nNum <= 7)
917 const SfxItemSet aLightItemSet(Get3DAttributes());
919 switch(nNum)
921 case 0 : return ((const Svx3DLightOnOff1Item&)aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTON_1)).GetValue();
922 case 1 : return ((const Svx3DLightOnOff2Item&)aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTON_2)).GetValue();
923 case 2 : return ((const Svx3DLightOnOff3Item&)aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTON_3)).GetValue();
924 case 3 : return ((const Svx3DLightOnOff4Item&)aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTON_4)).GetValue();
925 case 4 : return ((const Svx3DLightOnOff5Item&)aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTON_5)).GetValue();
926 case 5 : return ((const Svx3DLightOnOff6Item&)aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTON_6)).GetValue();
927 case 6 : return ((const Svx3DLightOnOff7Item&)aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTON_7)).GetValue();
928 case 7 : return ((const Svx3DLightOnOff8Item&)aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTON_8)).GetValue();
932 return false;
935 Color Svx3DLightControl::GetLightColor(sal_uInt32 nNum) const
937 if(nNum <= 7)
939 const SfxItemSet aLightItemSet(Get3DAttributes());
941 switch(nNum)
943 case 0 : return ((const Svx3DLightcolor1Item&)aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTCOLOR_1)).GetValue();
944 case 1 : return ((const Svx3DLightcolor2Item&)aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTCOLOR_2)).GetValue();
945 case 2 : return ((const Svx3DLightcolor3Item&)aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTCOLOR_3)).GetValue();
946 case 3 : return ((const Svx3DLightcolor4Item&)aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTCOLOR_4)).GetValue();
947 case 4 : return ((const Svx3DLightcolor5Item&)aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTCOLOR_5)).GetValue();
948 case 5 : return ((const Svx3DLightcolor6Item&)aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTCOLOR_6)).GetValue();
949 case 6 : return ((const Svx3DLightcolor7Item&)aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTCOLOR_7)).GetValue();
950 case 7 : return ((const Svx3DLightcolor8Item&)aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTCOLOR_8)).GetValue();
954 return Color(COL_BLACK);
957 basegfx::B3DVector Svx3DLightControl::GetLightDirection(sal_uInt32 nNum) const
959 if(nNum <= 7)
961 const SfxItemSet aLightItemSet(Get3DAttributes());
963 switch(nNum)
965 case 0 : return ((const Svx3DLightDirection1Item&)aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_1)).GetValue();
966 case 1 : return ((const Svx3DLightDirection2Item&)aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_2)).GetValue();
967 case 2 : return ((const Svx3DLightDirection3Item&)aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_3)).GetValue();
968 case 3 : return ((const Svx3DLightDirection4Item&)aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_4)).GetValue();
969 case 4 : return ((const Svx3DLightDirection5Item&)aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_5)).GetValue();
970 case 5 : return ((const Svx3DLightDirection6Item&)aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_6)).GetValue();
971 case 6 : return ((const Svx3DLightDirection7Item&)aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_7)).GetValue();
972 case 7 : return ((const Svx3DLightDirection8Item&)aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_8)).GetValue();
976 return basegfx::B3DVector();
979 //////////////////////////////////////////////////////////////////////////////
981 SvxLightCtl3D::SvxLightCtl3D( Window* pParent, const ResId& rResId)
982 : Control(pParent, rResId),
983 maLightControl(this, 0),
984 maHorScroller(this, WB_HORZ | WB_DRAG),
985 maVerScroller(this, WB_VERT | WB_DRAG),
986 maSwitcher(this, 0)
988 // init members
989 Init();
992 SvxLightCtl3D::SvxLightCtl3D( Window* pParent, WinBits nStyle )
993 : Control(pParent, nStyle),
994 maLightControl(this, 0),
995 maHorScroller(this, WB_HORZ | WB_DRAG),
996 maVerScroller(this, WB_VERT | WB_DRAG),
997 maSwitcher(this, 0)
999 // init members
1000 Init();
1003 void SvxLightCtl3D::Init()
1005 // #i58240# set HelpIDs for scrollbars and switcher
1006 maHorScroller.SetHelpId(HID_CTRL3D_HSCROLL);
1007 maVerScroller.SetHelpId(HID_CTRL3D_VSCROLL);
1008 maSwitcher.SetHelpId(HID_CTRL3D_SWITCHER);
1010 // Light preview
1011 maLightControl.Show();
1012 maLightControl.SetChangeCallback( LINK(this, SvxLightCtl3D, InternalInteractiveChange) );
1013 maLightControl.SetSelectionChangeCallback( LINK(this, SvxLightCtl3D, InternalSelectionChange) );
1015 // Horiz Scrollbar
1016 maHorScroller.Show();
1017 maHorScroller.SetRange(Range(0, 36000));
1018 maHorScroller.SetLineSize(100);
1019 maHorScroller.SetPageSize(1000);
1020 maHorScroller.SetScrollHdl( LINK(this, SvxLightCtl3D, ScrollBarMove) );
1022 // Vert Scrollbar
1023 maVerScroller.Show();
1024 maVerScroller.SetRange(Range(0, 18000));
1025 maVerScroller.SetLineSize(100);
1026 maVerScroller.SetPageSize(1000);
1027 maVerScroller.SetScrollHdl( LINK(this, SvxLightCtl3D, ScrollBarMove) );
1029 // Switch Button
1030 maSwitcher.Show();
1031 maSwitcher.SetClickHdl( LINK(this, SvxLightCtl3D, ButtonPress) );
1033 // check selection
1034 CheckSelection();
1036 // new layout
1037 NewLayout();
1040 SvxLightCtl3D::~SvxLightCtl3D()
1044 void SvxLightCtl3D::Resize()
1046 // call parent
1047 Control::Resize();
1049 // new layout
1050 NewLayout();
1053 void SvxLightCtl3D::NewLayout()
1055 // Layout members
1056 const Size aSize(GetOutputSizePixel());
1057 const sal_Int32 nScrollSize(maHorScroller.GetSizePixel().Height());
1059 // Preview control
1060 Point aPoint(0, 0);
1061 Size aDestSize(aSize.Width() - nScrollSize, aSize.Height() - nScrollSize);
1062 maLightControl.SetPosSizePixel(aPoint, aDestSize);
1064 // hor scrollbar
1065 aPoint.Y() = aSize.Height() - nScrollSize;
1066 aDestSize.Height() = nScrollSize;
1067 maHorScroller.SetPosSizePixel(aPoint, aDestSize);
1069 // vert scrollbar
1070 aPoint.X() = aSize.Width() - nScrollSize;
1071 aPoint.Y() = 0;
1072 aDestSize.Width() = nScrollSize;
1073 aDestSize.Height() = aSize.Height() - nScrollSize;
1074 maVerScroller.SetPosSizePixel(aPoint, aDestSize);
1076 // button
1077 aPoint.Y() = aSize.Height() - nScrollSize;
1078 aDestSize.Height() = nScrollSize;
1079 maSwitcher.SetPosSizePixel(aPoint, aDestSize);
1082 void SvxLightCtl3D::CheckSelection()
1084 const bool bSelectionValid(maLightControl.IsSelectionValid() || maLightControl.IsGeometrySelected());
1085 maHorScroller.Enable(bSelectionValid);
1086 maVerScroller.Enable(bSelectionValid);
1088 if(bSelectionValid)
1090 double fHor, fVer;
1091 maLightControl.GetPosition(fHor, fVer);
1092 maHorScroller.SetThumbPos( INT32(fHor * 100.0) );
1093 maVerScroller.SetThumbPos( 18000 - INT32((fVer + 90.0) * 100.0) );
1097 void SvxLightCtl3D::move( double fDeltaHor, double fDeltaVer )
1099 double fHor, fVer;
1101 maLightControl.GetPosition(fHor, fVer);
1102 fHor += fDeltaHor;
1103 fVer += fDeltaVer;
1105 if( fVer > 90.0 )
1106 return;
1108 if ( fVer < -90.0 )
1109 return;
1111 maLightControl.SetPosition(fHor, fVer);
1112 maHorScroller.SetThumbPos( INT32(fHor * 100.0) );
1113 maVerScroller.SetThumbPos( 18000 - INT32((fVer + 90.0) * 100.0) );
1115 if(maUserInteractiveChangeCallback.IsSet())
1117 maUserInteractiveChangeCallback.Call(this);
1121 void SvxLightCtl3D::KeyInput( const KeyEvent& rKEvt )
1123 const KeyCode aCode(rKEvt.GetKeyCode());
1125 if( aCode.GetModifier() )
1127 Control::KeyInput( rKEvt );
1128 return;
1131 switch ( aCode.GetCode() )
1133 case KEY_SPACE:
1135 break;
1137 case KEY_LEFT:
1139 move( -4.0, 0.0 ); // #i58242# changed move direction in X
1140 break;
1142 case KEY_RIGHT:
1144 move( 4.0, 0.0 ); // #i58242# changed move direction in X
1145 break;
1147 case KEY_UP:
1149 move( 0.0, 4.0 );
1150 break;
1152 case KEY_DOWN:
1154 move( 0.0, -4.0 );
1155 break;
1157 case KEY_PAGEUP:
1159 sal_Int32 nLight(maLightControl.GetSelectedLight() - 1);
1161 while((nLight >= 0) && !maLightControl.GetLightOnOff(nLight))
1163 nLight--;
1166 if(nLight < 0)
1168 nLight = 7;
1170 while((nLight >= 0) && !maLightControl.GetLightOnOff(nLight))
1172 nLight--;
1176 if(nLight >= 0)
1178 maLightControl.SelectLight(nLight);
1179 CheckSelection();
1181 if(maUserSelectionChangeCallback.IsSet())
1183 maUserSelectionChangeCallback.Call(this);
1187 break;
1189 case KEY_PAGEDOWN:
1191 sal_Int32 nLight(maLightControl.GetSelectedLight() - 1);
1193 while(nLight <= 7 && !maLightControl.GetLightOnOff(nLight))
1195 nLight++;
1198 if(nLight > 7)
1200 nLight = 0;
1202 while(nLight <= 7 && !maLightControl.GetLightOnOff(nLight))
1204 nLight++;
1208 if(nLight <= 7)
1210 maLightControl.SelectLight(nLight);
1211 CheckSelection();
1213 if(maUserSelectionChangeCallback.IsSet())
1215 maUserSelectionChangeCallback.Call(this);
1219 break;
1221 default:
1223 Control::KeyInput( rKEvt );
1224 break;
1229 void SvxLightCtl3D::GetFocus()
1231 Control::GetFocus();
1233 if(HasFocus() && IsEnabled())
1235 CheckSelection();
1237 Size aFocusSize = maLightControl.GetOutputSizePixel();
1239 aFocusSize.Width() -= 4;
1240 aFocusSize.Height() -= 4;
1242 Rectangle aFocusRect( Point( 2, 2 ), aFocusSize );
1244 aFocusRect = maLightControl.PixelToLogic( aFocusRect );
1246 maLightControl.ShowFocus( aFocusRect );
1250 void SvxLightCtl3D::LoseFocus()
1252 Control::LoseFocus();
1254 maLightControl.HideFocus();
1257 IMPL_LINK( SvxLightCtl3D, ScrollBarMove, void*, EMPTYARG)
1259 const sal_Int32 nHor(maHorScroller.GetThumbPos());
1260 const sal_Int32 nVer(maVerScroller.GetThumbPos());
1262 maLightControl.SetPosition(
1263 ((double)nHor) / 100.0,
1264 ((double)((18000 - nVer) - 9000)) / 100.0);
1266 if(maUserInteractiveChangeCallback.IsSet())
1268 maUserInteractiveChangeCallback.Call(this);
1271 return 0;
1274 IMPL_LINK( SvxLightCtl3D, ButtonPress, void*, EMPTYARG)
1276 if(PREVIEW_OBJECTTYPE_SPHERE == GetSvx3DLightControl().GetObjectType())
1278 GetSvx3DLightControl().SetObjectType(PREVIEW_OBJECTTYPE_CUBE);
1280 else
1282 GetSvx3DLightControl().SetObjectType(PREVIEW_OBJECTTYPE_SPHERE);
1285 return 0;
1288 IMPL_LINK( SvxLightCtl3D, InternalInteractiveChange, void*, EMPTYARG)
1290 double fHor, fVer;
1292 maLightControl.GetPosition(fHor, fVer);
1293 maHorScroller.SetThumbPos( INT32(fHor * 100.0) );
1294 maVerScroller.SetThumbPos( 18000 - INT32((fVer + 90.0) * 100.0) );
1296 if(maUserInteractiveChangeCallback.IsSet())
1298 maUserInteractiveChangeCallback.Call(this);
1301 return 0;
1304 IMPL_LINK( SvxLightCtl3D, InternalSelectionChange, void*, EMPTYARG)
1306 CheckSelection();
1308 if(maUserSelectionChangeCallback.IsSet())
1310 maUserSelectionChangeCallback.Call(this);
1313 return 0;
1316 //////////////////////////////////////////////////////////////////////////////
1317 // eof