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 .
21 #include <svx/dlgctl3d.hxx>
22 #include <svx/dialogs.hrc>
23 #include <svx/view3d.hxx>
24 #include <svx/fmmodel.hxx>
25 #include <svl/itempool.hxx>
26 #include <svx/fmpage.hxx>
27 #include <svx/polysc3d.hxx>
28 #include <svx/sphere3d.hxx>
29 #include <svx/cube3d.hxx>
30 #include <vcl/svapp.hxx>
31 #include <vcl/builder.hxx>
32 #include <svx/helperhittest3d.hxx>
33 #include <basegfx/polygon/b2dpolygontools.hxx>
34 #include <polygn3d.hxx>
35 #include <svx/xlnclit.hxx>
36 #include <svx/xlnwtit.hxx>
39 #include <svx/dialmgr.hxx>
40 #include <vcl/settings.hxx>
44 Svx3DPreviewControl::Svx3DPreviewControl(Window
* pParent
, const ResId
& rResId
)
45 : Control(pParent
, rResId
),
51 mnObjectType(PREVIEW_OBJECTTYPE_SPHERE
)
55 // do not paint background self, DrawingLayer paints this buffered and as page
56 SetControlBackground();
60 Svx3DPreviewControl::Svx3DPreviewControl(Window
* pParent
, WinBits nStyle
)
61 : Control(pParent
, nStyle
),
67 mnObjectType(PREVIEW_OBJECTTYPE_SPHERE
)
71 // do not paint background self, DrawingLayer paints this buffered and as page
72 SetControlBackground();
76 Svx3DPreviewControl::~Svx3DPreviewControl()
82 void Svx3DPreviewControl::Construct()
84 // Do never mirror the preview window. This explicitly includes right
85 // to left writing environments.
87 SetMapMode( MAP_100TH_MM
);
90 mpModel
= new FmFormModel();
91 mpModel
->GetItemPool().FreezeIdRanges();
94 mpFmPage
= new FmFormPage( *mpModel
);
95 mpModel
->InsertPage( mpFmPage
, 0 );
98 mp3DView
= new E3dView( mpModel
, this );
99 mp3DView
->SetBufferedOutputAllowed(true);
100 mp3DView
->SetBufferedOverlayAllowed(true);
103 mpScene
= new E3dPolyScene(mp3DView
->Get3DDefaultAttributes());
105 // initially create object
106 SetObjectType(PREVIEW_OBJECTTYPE_SPHERE
);
108 // camera and perspective
109 Camera3D
& rCamera
= (Camera3D
&) mpScene
->GetCamera();
110 const basegfx::B3DRange
& rVolume
= mpScene
->GetBoundVolume();
111 double fW
= rVolume
.getWidth();
112 double fH
= rVolume
.getHeight();
113 double fCamZ
= rVolume
.getMaxZ() + ((fW
+ fH
) / 2.0);
115 rCamera
.SetAutoAdjustProjection(false);
116 rCamera
.SetViewWindow(- fW
/ 2, - fH
/ 2, fW
, fH
);
117 basegfx::B3DPoint aLookAt
;
118 double fDefaultCamPosZ
= mp3DView
->GetDefaultCamPosZ();
119 basegfx::B3DPoint
aCamPos(0.0, 0.0, fCamZ
< fDefaultCamPosZ
? fDefaultCamPosZ
: fCamZ
);
120 rCamera
.SetPosAndLookAt(aCamPos
, aLookAt
);
121 double fDefaultCamFocal
= mp3DView
->GetDefaultCamFocal();
122 rCamera
.SetFocalLength(fDefaultCamFocal
);
123 rCamera
.SetDefaults(basegfx::B3DPoint(0.0, 0.0, fDefaultCamPosZ
), aLookAt
, fDefaultCamFocal
);
125 mpScene
->SetCamera( rCamera
);
126 mpFmPage
->InsertObject( mpScene
);
128 basegfx::B3DHomMatrix aRotation
;
129 aRotation
.rotate(DEG2RAD( 25 ), 0.0, 0.0);
130 aRotation
.rotate(0.0, DEG2RAD( 40 ), 0.0);
131 mpScene
->SetTransform(aRotation
* mpScene
->GetTransform());
133 // invalidate SnapRects of objects
134 mpScene
->SetRectsDirty();
136 SfxItemSet
aSet( mpModel
->GetItemPool(),
137 XATTR_LINESTYLE
, XATTR_LINESTYLE
,
138 XATTR_FILL_FIRST
, XATTR_FILLBITMAP
,
140 aSet
.Put( XLineStyleItem( XLINE_NONE
) );
141 aSet
.Put( XFillStyleItem( XFILL_SOLID
) );
142 aSet
.Put( XFillColorItem( "", Color( COL_WHITE
) ) );
144 mpScene
->SetMergedItemSet(aSet
);
147 SdrPageView
* pPageView
= mp3DView
->ShowSdrPage( mpFmPage
);
148 mp3DView
->hideMarkHandles();
151 mp3DView
->MarkObj( mpScene
, pPageView
);
154 void Svx3DPreviewControl::Resize()
157 Size
aSize( GetSizePixel() );
158 aSize
= PixelToLogic( aSize
);
159 mpFmPage
->SetSize( aSize
);
162 Size
aObjSize( aSize
.Width()*5/6, aSize
.Height()*5/6 );
163 Point
aObjPoint( (aSize
.Width() - aObjSize
.Width()) / 2,
164 (aSize
.Height() - aObjSize
.Height()) / 2);
165 Rectangle
aRect( aObjPoint
, aObjSize
);
166 mpScene
->SetSnapRect( aRect
);
169 void Svx3DPreviewControl::Paint(const Rectangle
& rRect
)
171 mp3DView
->CompleteRedraw(this, Region(rRect
));
174 void Svx3DPreviewControl::MouseButtonDown(const MouseEvent
& rMEvt
)
176 Control::MouseButtonDown(rMEvt
);
178 if( rMEvt
.IsShift() && rMEvt
.IsMod1() )
180 if(PREVIEW_OBJECTTYPE_SPHERE
== GetObjectType())
182 SetObjectType(PREVIEW_OBJECTTYPE_CUBE
);
186 SetObjectType(PREVIEW_OBJECTTYPE_SPHERE
);
191 void Svx3DPreviewControl::SetObjectType(sal_uInt16 nType
)
193 if( mnObjectType
!= nType
|| !mp3DObj
)
195 SfxItemSet
aSet(mpModel
->GetItemPool(), SDRATTR_START
, SDRATTR_END
, 0, 0);
196 mnObjectType
= nType
;
200 aSet
.Put(mp3DObj
->GetMergedItemSet());
201 mpScene
->Remove3DObj( mp3DObj
);
208 case PREVIEW_OBJECTTYPE_SPHERE
:
210 mp3DObj
= new E3dSphereObj(
211 mp3DView
->Get3DDefaultAttributes(),
212 basegfx::B3DPoint( 0, 0, 0 ),
213 basegfx::B3DVector( 5000, 5000, 5000 ));
217 case PREVIEW_OBJECTTYPE_CUBE
:
219 mp3DObj
= new E3dCubeObj(
220 mp3DView
->Get3DDefaultAttributes(),
221 basegfx::B3DPoint( -2500, -2500, -2500 ),
222 basegfx::B3DVector( 5000, 5000, 5000 ));
227 mpScene
->Insert3DObj( mp3DObj
);
228 mp3DObj
->SetMergedItemSet(aSet
);
234 SfxItemSet
Svx3DPreviewControl::Get3DAttributes() const
236 return mp3DObj
->GetMergedItemSet();
239 void Svx3DPreviewControl::Set3DAttributes( const SfxItemSet
& rAttr
)
241 mp3DObj
->SetMergedItemSet(rAttr
, true);
247 #define RADIUS_LAMP_PREVIEW_SIZE (4500.0)
248 #define RADIUS_LAMP_SMALL (600.0)
249 #define RADIUS_LAMP_BIG (1000.0)
250 #define NO_LIGHT_SELECTED (0xffffffff)
251 #define MAX_NUMBER_LIGHTS (8)
253 Svx3DLightControl::Svx3DLightControl(Window
* pParent
, WinBits nStyle
)
254 : Svx3DPreviewControl(pParent
, nStyle
),
255 maUserInteractiveChangeCallback(),
256 maUserSelectionChangeCallback(),
258 maSelectionChangeCallback(),
259 maSelectedLight(NO_LIGHT_SELECTED
),
260 mpExpansionObject(0),
261 mpLampBottomObject(0),
262 mpLampShaftObject(0),
263 maLightObjects(MAX_NUMBER_LIGHTS
, (E3dObject
*)0),
267 maActionStartPoint(),
268 mnInteractionStartDistance(5 * 5 * 2),
269 mfSaveActionStartHor(0.0),
270 mfSaveActionStartVer(0.0),
271 mfSaveActionStartRotZ(0.0),
273 mbGeometrySelected(false)
278 Svx3DLightControl::~Svx3DLightControl()
280 // SdrObjects like mpExpansionObject and mpLampBottomObject/mpLampShaftObject get deleted
281 // with deletion of the DrawingLayer and model
284 void Svx3DLightControl::Construct2()
287 // hide all page stuff, use control background (normally gray)
288 const Color
aDialogColor(Application::GetSettings().GetStyleSettings().GetDialogColor());
289 mp3DView
->SetPageVisible(false);
290 mp3DView
->SetApplicationBackgroundColor(aDialogColor
);
291 mp3DView
->SetApplicationDocumentColor(aDialogColor
);
295 // create invisible expansion object
296 const double fMaxExpansion(RADIUS_LAMP_BIG
+ RADIUS_LAMP_PREVIEW_SIZE
);
297 mpExpansionObject
= new E3dCubeObj(
298 mp3DView
->Get3DDefaultAttributes(),
299 basegfx::B3DPoint(-fMaxExpansion
, -fMaxExpansion
, -fMaxExpansion
),
300 basegfx::B3DVector(2.0 * fMaxExpansion
, 2.0 * fMaxExpansion
, 2.0 * fMaxExpansion
));
301 mpScene
->Insert3DObj( mpExpansionObject
);
302 SfxItemSet
aSet(mpModel
->GetItemPool());
303 aSet
.Put( XLineStyleItem( XLINE_NONE
) );
304 aSet
.Put( XFillStyleItem( XFILL_NONE
) );
305 mpExpansionObject
->SetMergedItemSet(aSet
);
309 // create lamp control object (Yellow lined object)
311 const basegfx::B2DPolygon
a2DCircle(basegfx::tools::createPolygonFromCircle(basegfx::B2DPoint(0.0, 0.0), RADIUS_LAMP_PREVIEW_SIZE
));
312 basegfx::B3DPolygon
a3DCircle(basegfx::tools::createB3DPolygonFromB2DPolygon(a2DCircle
));
313 basegfx::B3DHomMatrix aTransform
;
315 aTransform
.rotate(F_PI2
, 0.0, 0.0);
316 aTransform
.translate(0.0, -RADIUS_LAMP_PREVIEW_SIZE
, 0.0);
317 a3DCircle
.transform(aTransform
);
319 // create object for it
320 mpLampBottomObject
= new E3dPolygonObj(
321 mp3DView
->Get3DDefaultAttributes(),
322 basegfx::B3DPolyPolygon(a3DCircle
),
324 mpScene
->Insert3DObj( mpLampBottomObject
);
326 // half circle with stand
327 basegfx::B2DPolygon a2DHalfCircle
;
328 a2DHalfCircle
.append(basegfx::B2DPoint(RADIUS_LAMP_PREVIEW_SIZE
, 0.0));
329 a2DHalfCircle
.append(basegfx::B2DPoint(RADIUS_LAMP_PREVIEW_SIZE
, -RADIUS_LAMP_PREVIEW_SIZE
));
330 a2DHalfCircle
.append(basegfx::tools::createPolygonFromEllipseSegment(
331 basegfx::B2DPoint(0.0, 0.0), RADIUS_LAMP_PREVIEW_SIZE
, RADIUS_LAMP_PREVIEW_SIZE
, F_2PI
- F_PI2
, F_PI2
));
332 basegfx::B3DPolygon
a3DHalfCircle(basegfx::tools::createB3DPolygonFromB2DPolygon(a2DHalfCircle
));
334 // create object for it
335 mpLampShaftObject
= new E3dPolygonObj(
336 mp3DView
->Get3DDefaultAttributes(),
337 basegfx::B3DPolyPolygon(a3DHalfCircle
),
339 mpScene
->Insert3DObj( mpLampShaftObject
);
341 // initially invisible
342 SfxItemSet
aSet(mpModel
->GetItemPool());
343 aSet
.Put( XLineStyleItem( XLINE_NONE
) );
344 aSet
.Put( XFillStyleItem( XFILL_NONE
) );
346 mpLampBottomObject
->SetMergedItemSet(aSet
);
347 mpLampShaftObject
->SetMergedItemSet(aSet
);
351 // change camera settings
352 Camera3D
& rCamera
= (Camera3D
&) mpScene
->GetCamera();
353 const basegfx::B3DRange
& rVolume
= mpScene
->GetBoundVolume();
354 double fW
= rVolume
.getWidth();
355 double fH
= rVolume
.getHeight();
356 double fCamZ
= rVolume
.getMaxZ() + ((fW
+ fH
) / 2.0);
358 rCamera
.SetAutoAdjustProjection(false);
359 rCamera
.SetViewWindow(- fW
/ 2, - fH
/ 2, fW
, fH
);
360 basegfx::B3DPoint aLookAt
;
361 double fDefaultCamPosZ
= mp3DView
->GetDefaultCamPosZ();
362 basegfx::B3DPoint
aCamPos(0.0, 0.0, fCamZ
< fDefaultCamPosZ
? fDefaultCamPosZ
: fCamZ
);
363 rCamera
.SetPosAndLookAt(aCamPos
, aLookAt
);
364 double fDefaultCamFocal
= mp3DView
->GetDefaultCamFocal();
365 rCamera
.SetFocalLength(fDefaultCamFocal
);
366 rCamera
.SetDefaults(basegfx::B3DPoint(0.0, 0.0, fDefaultCamPosZ
), aLookAt
, fDefaultCamFocal
);
368 mpScene
->SetCamera( rCamera
);
370 basegfx::B3DHomMatrix aNeutral
;
371 mpScene
->SetTransform(aNeutral
);
374 // invalidate SnapRects of objects
375 mpScene
->SetRectsDirty();
378 void Svx3DLightControl::ConstructLightObjects()
380 for(sal_uInt32
a(0); a
< MAX_NUMBER_LIGHTS
; a
++)
382 // get rid of possible existing light object
383 if(maLightObjects
[a
])
385 mpScene
->Remove3DObj(maLightObjects
[a
]);
386 delete maLightObjects
[a
];
387 maLightObjects
[a
] = 0;
392 const bool bIsSelectedLight(a
== maSelectedLight
);
393 basegfx::B3DVector
aDirection(GetLightDirection(a
));
394 aDirection
.normalize();
395 aDirection
*= RADIUS_LAMP_PREVIEW_SIZE
;
397 const double fLampSize(bIsSelectedLight
? RADIUS_LAMP_BIG
: RADIUS_LAMP_SMALL
);
398 E3dObject
* pNewLight
= new E3dSphereObj(
399 mp3DView
->Get3DDefaultAttributes(),
400 basegfx::B3DPoint( 0, 0, 0 ),
401 basegfx::B3DVector( fLampSize
, fLampSize
, fLampSize
));
402 mpScene
->Insert3DObj(pNewLight
);
404 basegfx::B3DHomMatrix aTransform
;
405 aTransform
.translate(aDirection
.getX(), aDirection
.getY(), aDirection
.getZ());
406 pNewLight
->SetTransform(aTransform
);
408 SfxItemSet
aSet(mpModel
->GetItemPool());
409 aSet
.Put( XLineStyleItem( XLINE_NONE
) );
410 aSet
.Put( XFillStyleItem( XFILL_SOLID
) );
411 aSet
.Put( XFillColorItem(OUString(), GetLightColor(a
)));
412 pNewLight
->SetMergedItemSet(aSet
);
414 maLightObjects
[a
] = pNewLight
;
419 void Svx3DLightControl::AdaptToSelectedLight()
421 if(NO_LIGHT_SELECTED
== maSelectedLight
)
423 // make mpLampBottomObject/mpLampShaftObject invisible
424 SfxItemSet
aSet(mpModel
->GetItemPool());
425 aSet
.Put( XLineStyleItem( XLINE_NONE
) );
426 aSet
.Put( XFillStyleItem( XFILL_NONE
) );
427 mpLampBottomObject
->SetMergedItemSet(aSet
);
428 mpLampShaftObject
->SetMergedItemSet(aSet
);
432 basegfx::B3DVector
aDirection(GetLightDirection(maSelectedLight
));
433 aDirection
.normalize();
435 // make mpLampBottomObject/mpLampShaftObject visible (yellow hairline)
436 SfxItemSet
aSet(mpModel
->GetItemPool());
437 aSet
.Put( XLineStyleItem( XLINE_SOLID
) );
438 aSet
.Put( XLineColorItem(OUString(), COL_YELLOW
));
439 aSet
.Put( XLineWidthItem(0));
440 aSet
.Put( XFillStyleItem( XFILL_NONE
) );
441 mpLampBottomObject
->SetMergedItemSet(aSet
);
442 mpLampShaftObject
->SetMergedItemSet(aSet
);
444 // adapt transformation of mpLampShaftObject
445 basegfx::B3DHomMatrix aTransform
;
446 double fRotateY(0.0);
448 if(!basegfx::fTools::equalZero(aDirection
.getZ()) || !basegfx::fTools::equalZero(aDirection
.getX()))
450 fRotateY
= atan2(-aDirection
.getZ(), aDirection
.getX());
453 aTransform
.rotate(0.0, fRotateY
, 0.0);
454 mpLampShaftObject
->SetTransform(aTransform
);
456 // adapt transformation of selected light
457 E3dObject
* pSelectedLight
= maLightObjects
[sal_Int32(maSelectedLight
)];
461 aTransform
.identity();
462 aTransform
.translate(
463 aDirection
.getX() * RADIUS_LAMP_PREVIEW_SIZE
,
464 aDirection
.getY() * RADIUS_LAMP_PREVIEW_SIZE
,
465 aDirection
.getZ() * RADIUS_LAMP_PREVIEW_SIZE
);
466 pSelectedLight
->SetTransform(aTransform
);
471 void Svx3DLightControl::TrySelection(Point aPosPixel
)
475 const Point
aPosLogic(PixelToLogic(aPosPixel
));
476 const basegfx::B2DPoint
aPoint(aPosLogic
.X(), aPosLogic
.Y());
477 std::vector
< const E3dCompoundObject
* > aResult
;
478 getAllHit3DObjectsSortedFrontToBack(aPoint
, *mpScene
, aResult
);
482 // exclude expansion object which will be part of
483 // the hits. It's invisible, but for HitTest, it's included
484 const E3dCompoundObject
* pResult
= 0;
486 for(sal_uInt32
b(0); !pResult
&& b
< aResult
.size(); b
++)
488 if(aResult
[b
] && aResult
[b
] != mpExpansionObject
)
490 pResult
= aResult
[b
];
494 if(pResult
== mp3DObj
)
496 if(!mbGeometrySelected
)
498 mbGeometrySelected
= true;
499 maSelectedLight
= NO_LIGHT_SELECTED
;
500 ConstructLightObjects();
501 AdaptToSelectedLight();
504 if(maSelectionChangeCallback
.IsSet())
506 maSelectionChangeCallback
.Call(this);
512 sal_uInt32
aNewSelectedLight(NO_LIGHT_SELECTED
);
514 for(sal_uInt32
a(0); a
< MAX_NUMBER_LIGHTS
; a
++)
516 if(maLightObjects
[a
] && maLightObjects
[a
] == pResult
)
518 aNewSelectedLight
= a
;
522 if(aNewSelectedLight
!= maSelectedLight
)
524 SelectLight(aNewSelectedLight
);
526 if(maSelectionChangeCallback
.IsSet())
528 maSelectionChangeCallback
.Call(this);
536 void Svx3DLightControl::Paint(const Rectangle
& rRect
)
538 Svx3DPreviewControl::Paint(rRect
);
541 void Svx3DLightControl::MouseButtonDown( const MouseEvent
& rMEvt
)
543 bool bCallParent(true);
548 if(IsSelectionValid() || mbGeometrySelected
)
550 mbMouseMoved
= false;
552 maActionStartPoint
= rMEvt
.GetPosPixel();
557 // Single click without moving much trying to do a selection
558 TrySelection(rMEvt
.GetPosPixel());
566 Svx3DPreviewControl::MouseButtonDown(rMEvt
);
570 void Svx3DLightControl::Tracking( const TrackingEvent
& rTEvt
)
572 if(rTEvt
.IsTrackingEnded())
574 if(rTEvt
.IsTrackingCanceled())
578 // interrupt tracking
579 mbMouseMoved
= false;
581 if(mbGeometrySelected
)
583 SetRotation(mfSaveActionStartVer
, mfSaveActionStartHor
, mfSaveActionStartRotZ
);
587 SetPosition(mfSaveActionStartHor
, mfSaveActionStartVer
);
590 if(maChangeCallback
.IsSet())
592 maChangeCallback
.Call(this);
598 const MouseEvent
& rMEvt
= rTEvt
.GetMouseEvent();
602 // was change dinteractively
606 // simple click without much movement, try selection
607 TrySelection(rMEvt
.GetPosPixel());
613 const MouseEvent
& rMEvt
= rTEvt
.GetMouseEvent();
614 Point aDeltaPos
= rMEvt
.GetPosPixel() - maActionStartPoint
;
618 if(sal_Int32(aDeltaPos
.X() * aDeltaPos
.X() + aDeltaPos
.Y() * aDeltaPos
.Y()) > mnInteractionStartDistance
)
620 if(mbGeometrySelected
)
622 GetRotation(mfSaveActionStartVer
, mfSaveActionStartHor
, mfSaveActionStartRotZ
);
626 // intercation start, save values
627 GetPosition(mfSaveActionStartHor
, mfSaveActionStartVer
);
636 if(mbGeometrySelected
)
638 double fNewRotX
= mfSaveActionStartVer
- ((double)aDeltaPos
.Y() * F_PI180
);
639 double fNewRotY
= mfSaveActionStartHor
+ ((double)aDeltaPos
.X() * F_PI180
);
642 while(fNewRotY
< 0.0)
647 while(fNewRotY
>= F_2PI
)
653 if(fNewRotX
< -F_PI2
)
663 SetRotation(fNewRotX
, fNewRotY
, mfSaveActionStartRotZ
);
665 if(maChangeCallback
.IsSet())
667 maChangeCallback
.Call(this);
672 // interaction in progress
673 double fNewPosHor
= mfSaveActionStartHor
+ ((double)aDeltaPos
.X());
674 double fNewPosVer
= mfSaveActionStartVer
- ((double)aDeltaPos
.Y());
677 while(fNewPosHor
< 0.0)
682 while(fNewPosHor
>= 360.0)
688 if(fNewPosVer
< -90.0)
693 if(fNewPosVer
> 90.0)
698 SetPosition(fNewPosHor
, fNewPosVer
);
700 if(maChangeCallback
.IsSet())
702 maChangeCallback
.Call(this);
709 void Svx3DLightControl::Resize()
712 const Size
aSize(PixelToLogic(GetSizePixel()));
713 mpFmPage
->SetSize(aSize
);
715 // set position and size of scene
716 mpScene
->SetSnapRect(Rectangle(Point(0, 0), aSize
));
719 void Svx3DLightControl::SetObjectType(sal_uInt16 nType
)
722 Svx3DPreviewControl::SetObjectType(nType
);
724 // apply object rotation
727 basegfx::B3DHomMatrix aObjectRotation
;
728 aObjectRotation
.rotate(mfRotateX
, mfRotateY
, mfRotateZ
);
729 mp3DObj
->SetTransform(aObjectRotation
);
733 bool Svx3DLightControl::IsSelectionValid()
735 if((NO_LIGHT_SELECTED
!= maSelectedLight
) && (GetLightOnOff(maSelectedLight
)))
743 void Svx3DLightControl::GetPosition(double& rHor
, double& rVer
)
745 if(IsSelectionValid())
747 basegfx::B3DVector
aDirection(GetLightDirection(maSelectedLight
));
748 aDirection
.normalize();
749 rHor
= atan2(-aDirection
.getX(), -aDirection
.getZ()) + F_PI
; // 0..2PI
750 rVer
= atan2(aDirection
.getY(), aDirection
.getXZLength()); // -PI2..PI2
751 rHor
/= F_PI180
; // 0..360.0
752 rVer
/= F_PI180
; // -90.0..90.0
754 if(IsGeometrySelected())
756 rHor
= mfRotateY
/ F_PI180
; // 0..360.0
757 rVer
= mfRotateX
/ F_PI180
; // -90.0..90.0
761 void Svx3DLightControl::SetPosition(double fHor
, double fVer
)
763 if(IsSelectionValid())
765 // set selected light's direction
766 fHor
= (fHor
* F_PI180
) - F_PI
; // -PI..PI
767 fVer
*= F_PI180
; // -PI2..PI2
768 basegfx::B3DVector
aDirection(cos(fVer
) * -sin(fHor
), sin(fVer
), cos(fVer
) * -cos(fHor
));
769 aDirection
.normalize();
771 if(!aDirection
.equal(GetLightDirection(maSelectedLight
)))
773 // set changed light direction at SdrScene
774 SfxItemSet
aSet(mpModel
->GetItemPool());
776 switch(maSelectedLight
)
778 case 0: aSet
.Put(Svx3DLightDirection1Item(aDirection
)); break;
779 case 1: aSet
.Put(Svx3DLightDirection2Item(aDirection
)); break;
780 case 2: aSet
.Put(Svx3DLightDirection3Item(aDirection
)); break;
781 case 3: aSet
.Put(Svx3DLightDirection4Item(aDirection
)); break;
782 case 4: aSet
.Put(Svx3DLightDirection5Item(aDirection
)); break;
783 case 5: aSet
.Put(Svx3DLightDirection6Item(aDirection
)); break;
784 case 6: aSet
.Put(Svx3DLightDirection7Item(aDirection
)); break;
786 case 7: aSet
.Put(Svx3DLightDirection8Item(aDirection
)); break;
789 mpScene
->SetMergedItemSet(aSet
);
791 // correct 3D light's and LampFrame's geometries
792 AdaptToSelectedLight();
796 if(IsGeometrySelected())
798 if(mfRotateX
!= fVer
|| mfRotateY
!= fHor
)
800 mfRotateX
= fVer
* F_PI180
;
801 mfRotateY
= fHor
* F_PI180
;
805 basegfx::B3DHomMatrix aObjectRotation
;
806 aObjectRotation
.rotate(mfRotateX
, mfRotateY
, mfRotateZ
);
807 mp3DObj
->SetTransform(aObjectRotation
);
815 void Svx3DLightControl::SetRotation(double fRotX
, double fRotY
, double fRotZ
)
817 if(IsGeometrySelected())
819 if(fRotX
!= mfRotateX
|| fRotY
!= mfRotateY
|| fRotZ
!= mfRotateZ
)
827 basegfx::B3DHomMatrix aObjectRotation
;
828 aObjectRotation
.rotate(mfRotateX
, mfRotateY
, mfRotateZ
);
829 mp3DObj
->SetTransform(aObjectRotation
);
837 void Svx3DLightControl::GetRotation(double& rRotX
, double& rRotY
, double& rRotZ
)
844 void Svx3DLightControl::Set3DAttributes( const SfxItemSet
& rAttr
)
847 Svx3DPreviewControl::Set3DAttributes(rAttr
);
849 if(maSelectedLight
!= NO_LIGHT_SELECTED
&& !GetLightOnOff(maSelectedLight
))
851 // selected light is no more active, select new one
852 maSelectedLight
= NO_LIGHT_SELECTED
;
856 ConstructLightObjects();
857 AdaptToSelectedLight();
861 void Svx3DLightControl::SelectLight(sal_uInt32 nLightNumber
)
865 nLightNumber
= NO_LIGHT_SELECTED
;
868 if(NO_LIGHT_SELECTED
!= nLightNumber
)
870 if(!GetLightOnOff(nLightNumber
))
872 nLightNumber
= NO_LIGHT_SELECTED
;
876 if(nLightNumber
!= maSelectedLight
)
878 maSelectedLight
= nLightNumber
;
879 mbGeometrySelected
= false;
880 ConstructLightObjects();
881 AdaptToSelectedLight();
886 bool Svx3DLightControl::GetLightOnOff(sal_uInt32 nNum
) const
890 const SfxItemSet
aLightItemSet(Get3DAttributes());
894 case 0 : return ((const Svx3DLightOnOff1Item
&)aLightItemSet
.Get(SDRATTR_3DSCENE_LIGHTON_1
)).GetValue();
895 case 1 : return ((const Svx3DLightOnOff2Item
&)aLightItemSet
.Get(SDRATTR_3DSCENE_LIGHTON_2
)).GetValue();
896 case 2 : return ((const Svx3DLightOnOff3Item
&)aLightItemSet
.Get(SDRATTR_3DSCENE_LIGHTON_3
)).GetValue();
897 case 3 : return ((const Svx3DLightOnOff4Item
&)aLightItemSet
.Get(SDRATTR_3DSCENE_LIGHTON_4
)).GetValue();
898 case 4 : return ((const Svx3DLightOnOff5Item
&)aLightItemSet
.Get(SDRATTR_3DSCENE_LIGHTON_5
)).GetValue();
899 case 5 : return ((const Svx3DLightOnOff6Item
&)aLightItemSet
.Get(SDRATTR_3DSCENE_LIGHTON_6
)).GetValue();
900 case 6 : return ((const Svx3DLightOnOff7Item
&)aLightItemSet
.Get(SDRATTR_3DSCENE_LIGHTON_7
)).GetValue();
901 case 7 : return ((const Svx3DLightOnOff8Item
&)aLightItemSet
.Get(SDRATTR_3DSCENE_LIGHTON_8
)).GetValue();
908 Color
Svx3DLightControl::GetLightColor(sal_uInt32 nNum
) const
912 const SfxItemSet
aLightItemSet(Get3DAttributes());
916 case 0 : return ((const Svx3DLightcolor1Item
&)aLightItemSet
.Get(SDRATTR_3DSCENE_LIGHTCOLOR_1
)).GetValue();
917 case 1 : return ((const Svx3DLightcolor2Item
&)aLightItemSet
.Get(SDRATTR_3DSCENE_LIGHTCOLOR_2
)).GetValue();
918 case 2 : return ((const Svx3DLightcolor3Item
&)aLightItemSet
.Get(SDRATTR_3DSCENE_LIGHTCOLOR_3
)).GetValue();
919 case 3 : return ((const Svx3DLightcolor4Item
&)aLightItemSet
.Get(SDRATTR_3DSCENE_LIGHTCOLOR_4
)).GetValue();
920 case 4 : return ((const Svx3DLightcolor5Item
&)aLightItemSet
.Get(SDRATTR_3DSCENE_LIGHTCOLOR_5
)).GetValue();
921 case 5 : return ((const Svx3DLightcolor6Item
&)aLightItemSet
.Get(SDRATTR_3DSCENE_LIGHTCOLOR_6
)).GetValue();
922 case 6 : return ((const Svx3DLightcolor7Item
&)aLightItemSet
.Get(SDRATTR_3DSCENE_LIGHTCOLOR_7
)).GetValue();
923 case 7 : return ((const Svx3DLightcolor8Item
&)aLightItemSet
.Get(SDRATTR_3DSCENE_LIGHTCOLOR_8
)).GetValue();
927 return Color(COL_BLACK
);
930 basegfx::B3DVector
Svx3DLightControl::GetLightDirection(sal_uInt32 nNum
) const
934 const SfxItemSet
aLightItemSet(Get3DAttributes());
938 case 0 : return ((const Svx3DLightDirection1Item
&)aLightItemSet
.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_1
)).GetValue();
939 case 1 : return ((const Svx3DLightDirection2Item
&)aLightItemSet
.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_2
)).GetValue();
940 case 2 : return ((const Svx3DLightDirection3Item
&)aLightItemSet
.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_3
)).GetValue();
941 case 3 : return ((const Svx3DLightDirection4Item
&)aLightItemSet
.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_4
)).GetValue();
942 case 4 : return ((const Svx3DLightDirection5Item
&)aLightItemSet
.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_5
)).GetValue();
943 case 5 : return ((const Svx3DLightDirection6Item
&)aLightItemSet
.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_6
)).GetValue();
944 case 6 : return ((const Svx3DLightDirection7Item
&)aLightItemSet
.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_7
)).GetValue();
945 case 7 : return ((const Svx3DLightDirection8Item
&)aLightItemSet
.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_8
)).GetValue();
949 return basegfx::B3DVector();
954 SvxLightCtl3D::SvxLightCtl3D( Window
* pParent
, const ResId
& rResId
)
955 : Control(pParent
, rResId
),
956 maLightControl(this, 0),
957 maHorScroller(this, WB_HORZ
| WB_DRAG
),
958 maVerScroller(this, WB_VERT
| WB_DRAG
),
965 SvxLightCtl3D::SvxLightCtl3D( Window
* pParent
)
966 : Control(pParent
, WB_BORDER
| WB_TABSTOP
),
967 maLightControl(this, 0),
968 maHorScroller(this, WB_HORZ
| WB_DRAG
),
969 maVerScroller(this, WB_VERT
| WB_DRAG
),
976 Size
SvxLightCtl3D::GetOptimalSize() const
978 return LogicToPixel(Size(80, 100), MAP_APPFONT
);
981 extern "C" SAL_DLLPUBLIC_EXPORT Window
* SAL_CALL
makeSvxLightCtl3D(Window
*pParent
, VclBuilder::stringmap
&)
983 return new SvxLightCtl3D(pParent
);
987 void SvxLightCtl3D::Init()
989 // #i58240# set HelpIDs for scrollbars and switcher
990 maHorScroller
.SetHelpId(HID_CTRL3D_HSCROLL
);
991 maVerScroller
.SetHelpId(HID_CTRL3D_VSCROLL
);
992 maSwitcher
.SetHelpId(HID_CTRL3D_SWITCHER
);
993 maSwitcher
.SetAccessibleName(SVX_RESSTR(STR_SWITCH
));
996 maLightControl
.Show();
997 maLightControl
.SetChangeCallback( LINK(this, SvxLightCtl3D
, InternalInteractiveChange
) );
998 maLightControl
.SetSelectionChangeCallback( LINK(this, SvxLightCtl3D
, InternalSelectionChange
) );
1001 maHorScroller
.Show();
1002 maHorScroller
.SetRange(Range(0, 36000));
1003 maHorScroller
.SetLineSize(100);
1004 maHorScroller
.SetPageSize(1000);
1005 maHorScroller
.SetScrollHdl( LINK(this, SvxLightCtl3D
, ScrollBarMove
) );
1008 maVerScroller
.Show();
1009 maVerScroller
.SetRange(Range(0, 18000));
1010 maVerScroller
.SetLineSize(100);
1011 maVerScroller
.SetPageSize(1000);
1012 maVerScroller
.SetScrollHdl( LINK(this, SvxLightCtl3D
, ScrollBarMove
) );
1016 maSwitcher
.SetClickHdl( LINK(this, SvxLightCtl3D
, ButtonPress
) );
1025 SvxLightCtl3D::~SvxLightCtl3D()
1029 void SvxLightCtl3D::Resize()
1038 void SvxLightCtl3D::NewLayout()
1041 const Size
aSize(GetOutputSizePixel());
1042 const sal_Int32
nScrollSize(maHorScroller
.GetSizePixel().Height());
1046 Size
aDestSize(aSize
.Width() - nScrollSize
, aSize
.Height() - nScrollSize
);
1047 maLightControl
.SetPosSizePixel(aPoint
, aDestSize
);
1050 aPoint
.Y() = aSize
.Height() - nScrollSize
;
1051 aDestSize
.Height() = nScrollSize
;
1052 maHorScroller
.SetPosSizePixel(aPoint
, aDestSize
);
1055 aPoint
.X() = aSize
.Width() - nScrollSize
;
1057 aDestSize
.Width() = nScrollSize
;
1058 aDestSize
.Height() = aSize
.Height() - nScrollSize
;
1059 maVerScroller
.SetPosSizePixel(aPoint
, aDestSize
);
1062 aPoint
.Y() = aSize
.Height() - nScrollSize
;
1063 aDestSize
.Height() = nScrollSize
;
1064 maSwitcher
.SetPosSizePixel(aPoint
, aDestSize
);
1067 void SvxLightCtl3D::CheckSelection()
1069 const bool bSelectionValid(maLightControl
.IsSelectionValid() || maLightControl
.IsGeometrySelected());
1070 maHorScroller
.Enable(bSelectionValid
);
1071 maVerScroller
.Enable(bSelectionValid
);
1076 maLightControl
.GetPosition(fHor
, fVer
);
1077 maHorScroller
.SetThumbPos( sal_Int32(fHor
* 100.0) );
1078 maVerScroller
.SetThumbPos( 18000 - sal_Int32((fVer
+ 90.0) * 100.0) );
1082 void SvxLightCtl3D::move( double fDeltaHor
, double fDeltaVer
)
1086 maLightControl
.GetPosition(fHor
, fVer
);
1096 maLightControl
.SetPosition(fHor
, fVer
);
1097 maHorScroller
.SetThumbPos( sal_Int32(fHor
* 100.0) );
1098 maVerScroller
.SetThumbPos( 18000 - sal_Int32((fVer
+ 90.0) * 100.0) );
1100 if(maUserInteractiveChangeCallback
.IsSet())
1102 maUserInteractiveChangeCallback
.Call(this);
1106 void SvxLightCtl3D::KeyInput( const KeyEvent
& rKEvt
)
1108 const KeyCode
aCode(rKEvt
.GetKeyCode());
1110 if( aCode
.GetModifier() )
1112 Control::KeyInput( rKEvt
);
1116 switch ( aCode
.GetCode() )
1124 move( -4.0, 0.0 ); // #i58242# changed move direction in X
1129 move( 4.0, 0.0 ); // #i58242# changed move direction in X
1144 sal_Int32
nLight(maLightControl
.GetSelectedLight() - 1);
1146 while((nLight
>= 0) && !maLightControl
.GetLightOnOff(nLight
))
1155 while((nLight
>= 0) && !maLightControl
.GetLightOnOff(nLight
))
1163 maLightControl
.SelectLight(nLight
);
1166 if(maUserSelectionChangeCallback
.IsSet())
1168 maUserSelectionChangeCallback
.Call(this);
1176 sal_Int32
nLight(maLightControl
.GetSelectedLight() - 1);
1178 while(nLight
<= 7 && !maLightControl
.GetLightOnOff(nLight
))
1187 while(nLight
<= 7 && !maLightControl
.GetLightOnOff(nLight
))
1195 maLightControl
.SelectLight(nLight
);
1198 if(maUserSelectionChangeCallback
.IsSet())
1200 maUserSelectionChangeCallback
.Call(this);
1208 Control::KeyInput( rKEvt
);
1214 void SvxLightCtl3D::GetFocus()
1216 Control::GetFocus();
1218 if(HasFocus() && IsEnabled())
1222 Size aFocusSize
= maLightControl
.GetOutputSizePixel();
1224 aFocusSize
.Width() -= 4;
1225 aFocusSize
.Height() -= 4;
1227 Rectangle
aFocusRect( Point( 2, 2 ), aFocusSize
);
1229 aFocusRect
= maLightControl
.PixelToLogic( aFocusRect
);
1231 maLightControl
.ShowFocus( aFocusRect
);
1235 void SvxLightCtl3D::LoseFocus()
1237 Control::LoseFocus();
1239 maLightControl
.HideFocus();
1242 IMPL_LINK_NOARG(SvxLightCtl3D
, ScrollBarMove
)
1244 const sal_Int32
nHor(maHorScroller
.GetThumbPos());
1245 const sal_Int32
nVer(maVerScroller
.GetThumbPos());
1247 maLightControl
.SetPosition(
1248 ((double)nHor
) / 100.0,
1249 ((double)((18000 - nVer
) - 9000)) / 100.0);
1251 if(maUserInteractiveChangeCallback
.IsSet())
1253 maUserInteractiveChangeCallback
.Call(this);
1259 IMPL_LINK_NOARG(SvxLightCtl3D
, ButtonPress
)
1261 if(PREVIEW_OBJECTTYPE_SPHERE
== GetSvx3DLightControl().GetObjectType())
1263 GetSvx3DLightControl().SetObjectType(PREVIEW_OBJECTTYPE_CUBE
);
1267 GetSvx3DLightControl().SetObjectType(PREVIEW_OBJECTTYPE_SPHERE
);
1273 IMPL_LINK_NOARG(SvxLightCtl3D
, InternalInteractiveChange
)
1277 maLightControl
.GetPosition(fHor
, fVer
);
1278 maHorScroller
.SetThumbPos( sal_Int32(fHor
* 100.0) );
1279 maVerScroller
.SetThumbPos( 18000 - sal_Int32((fVer
+ 90.0) * 100.0) );
1281 if(maUserInteractiveChangeCallback
.IsSet())
1283 maUserInteractiveChangeCallback
.Call(this);
1289 IMPL_LINK_NOARG(SvxLightCtl3D
, InternalSelectionChange
)
1293 if(maUserSelectionChangeCallback
.IsSet())
1295 maUserSelectionChangeCallback
.Call(this);
1301 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */