tdf#130857 qt weld: Support mail merge "Server Auth" dialog
[LibreOffice.git] / svx / source / dialog / dlgctl3d.cxx
blob781a8fdf9c17073fcaeb27c8006c28a6229a2e1c
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 <svx/dlgctl3d.hxx>
22 #include <svx/strings.hrc>
23 #include <svx/view3d.hxx>
24 #include <svx/fmmodel.hxx>
25 #include <svl/itempool.hxx>
26 #include <svx/fmpage.hxx>
27 #include <svx/sphere3d.hxx>
28 #include <svx/cube3d.hxx>
29 #include <svx/scene3d.hxx>
30 #include <vcl/svapp.hxx>
31 #include <svx/helperhittest3d.hxx>
32 #include <basegfx/polygon/b2dpolygontools.hxx>
33 #include <polygn3d.hxx>
34 #include <svx/xfillit0.hxx>
35 #include <svx/xflclit.hxx>
36 #include <svx/xlineit0.hxx>
37 #include <svx/xlnclit.hxx>
38 #include <svx/xlnwtit.hxx>
39 #include <helpids.h>
40 #include <svx/dialmgr.hxx>
41 #include <tools/helpers.hxx>
42 #include <vcl/settings.hxx>
44 using namespace com::sun::star;
46 Svx3DPreviewControl::Svx3DPreviewControl()
47 : mnObjectType(SvxPreviewObjectType::SPHERE)
51 void Svx3DPreviewControl::SetDrawingArea(weld::DrawingArea* pDrawingArea)
53 Size aSize(pDrawingArea->get_ref_device().LogicToPixel(Size(80, 100), MapMode(MapUnit::MapAppFont)));
54 pDrawingArea->set_size_request(aSize.Width(), aSize.Height());
55 CustomWidgetController::SetDrawingArea(pDrawingArea);
56 SetOutputSizePixel(aSize);
58 Construct();
61 void Svx3DPreviewControl::ClearPageView()
63 mp3DView->ClearPageView();
66 Svx3DPreviewControl::~Svx3DPreviewControl()
68 mp3DObj.clear();
69 mxFmPage.clear();
70 mpScene.clear();
71 mp3DView.reset();
72 mpModel.reset();
75 void Svx3DPreviewControl::Construct()
77 // Do never mirror the preview window. This explicitly includes right
78 // to left writing environments.
79 EnableRTL (false);
80 OutputDevice& rDevice = GetDrawingArea()->get_ref_device();
81 rDevice.SetMapMode(MapMode(MapUnit::Map100thMM));
83 // Model
84 mpModel.reset(new FmFormModel());
86 // Page
87 mxFmPage = new FmFormPage( *mpModel );
88 mpModel->InsertPage( mxFmPage.get(), 0 );
90 // 3D View
91 mp3DView.reset(new E3dView(*mpModel, &rDevice));
92 mp3DView->SetBufferedOutputAllowed(true);
93 mp3DView->SetBufferedOverlayAllowed(true);
95 // 3D Scene
96 mpScene = new E3dScene(*mpModel);
98 // initially create object
99 SetObjectType(SvxPreviewObjectType::SPHERE);
101 // camera and perspective
102 Camera3D rCamera = mpScene->GetCamera();
103 const basegfx::B3DRange& rVolume = mpScene->GetBoundVolume();
104 double fW = rVolume.getWidth();
105 double fH = rVolume.getHeight();
106 double fCamZ = rVolume.getMaxZ() + ((fW + fH) / 2.0);
108 rCamera.SetAutoAdjustProjection(false);
109 rCamera.SetViewWindow(- fW / 2, - fH / 2, fW, fH);
110 basegfx::B3DPoint aLookAt;
111 double fDefaultCamPosZ = mp3DView->GetDefaultCamPosZ();
112 basegfx::B3DPoint aCamPos(0.0, 0.0, fCamZ < fDefaultCamPosZ ? fDefaultCamPosZ : fCamZ);
113 rCamera.SetPosAndLookAt(aCamPos, aLookAt);
114 double fDefaultCamFocal = mp3DView->GetDefaultCamFocal();
115 rCamera.SetFocalLength(fDefaultCamFocal);
117 mpScene->SetCamera( rCamera );
118 mxFmPage->InsertObject( mpScene.get() );
120 basegfx::B3DHomMatrix aRotation;
121 aRotation.rotate(basegfx::deg2rad( 25 ), 0.0, 0.0);
122 aRotation.rotate(0.0, basegfx::deg2rad( 40 ), 0.0);
123 mpScene->SetTransform(aRotation * mpScene->GetTransform());
125 // invalidate SnapRects of objects
126 mpScene->SetBoundAndSnapRectsDirty();
128 SfxItemSetFixed<XATTR_LINESTYLE, XATTR_LINESTYLE,
129 XATTR_FILL_FIRST, XATTR_FILLBITMAP> aSet( mpModel->GetItemPool() );
130 aSet.Put( XLineStyleItem( drawing::LineStyle_NONE ) );
131 aSet.Put( XFillStyleItem( drawing::FillStyle_SOLID ) );
132 aSet.Put( XFillColorItem( u""_ustr, COL_WHITE ) );
134 mpScene->SetMergedItemSet(aSet);
136 // PageView
137 SdrPageView* pPageView = mp3DView->ShowSdrPage( mxFmPage.get() );
138 mp3DView->hideMarkHandles();
140 // mark scene
141 mp3DView->MarkObj( mpScene.get(), pPageView );
144 void Svx3DPreviewControl::Resize()
146 // size of page
147 Size aSize(GetOutputSizePixel());
148 aSize = GetDrawingArea()->get_ref_device().PixelToLogic(aSize);
149 mxFmPage->SetSize(aSize);
151 // set size
152 Size aObjSize( aSize.Width()*5/6, aSize.Height()*5/6 );
153 Point aObjPoint( (aSize.Width() - aObjSize.Width()) / 2,
154 (aSize.Height() - aObjSize.Height()) / 2);
155 tools::Rectangle aRect( aObjPoint, aObjSize);
156 mpScene->SetSnapRect( aRect );
159 void Svx3DPreviewControl::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect)
161 mp3DView->CompleteRedraw(&rRenderContext, vcl::Region(rRect));
164 bool Svx3DPreviewControl::MouseButtonDown(const MouseEvent& rMEvt)
166 if (rMEvt.IsShift() && rMEvt.IsMod1())
168 if(SvxPreviewObjectType::SPHERE == GetObjectType())
170 SetObjectType(SvxPreviewObjectType::CUBE);
172 else
174 SetObjectType(SvxPreviewObjectType::SPHERE);
177 return false;
180 void Svx3DPreviewControl::SetObjectType(SvxPreviewObjectType nType)
182 if(mnObjectType == nType && mp3DObj)
183 return;
185 SfxItemSetFixed<SDRATTR_START, SDRATTR_END> aSet(mpModel->GetItemPool());
186 mnObjectType = nType;
188 if( mp3DObj )
190 aSet.Put(mp3DObj->GetMergedItemSet());
191 mpScene->RemoveObject( mp3DObj->GetOrdNum() );
192 mp3DObj.clear();
195 switch( nType )
197 case SvxPreviewObjectType::SPHERE:
199 mp3DObj = new E3dSphereObj(
200 *mpModel,
201 mp3DView->Get3DDefaultAttributes(),
202 basegfx::B3DPoint( 0, 0, 0 ),
203 basegfx::B3DVector( 5000, 5000, 5000 ));
205 break;
207 case SvxPreviewObjectType::CUBE:
209 mp3DObj = new E3dCubeObj(
210 *mpModel,
211 mp3DView->Get3DDefaultAttributes(),
212 basegfx::B3DPoint( -2500, -2500, -2500 ),
213 basegfx::B3DVector( 5000, 5000, 5000 ));
215 break;
218 if (mp3DObj)
220 mpScene->InsertObject( mp3DObj.get() );
221 mp3DObj->SetMergedItemSet(aSet);
224 Invalidate();
227 SfxItemSet const & Svx3DPreviewControl::Get3DAttributes() const
229 return mp3DObj->GetMergedItemSet();
232 void Svx3DPreviewControl::Set3DAttributes( const SfxItemSet& rAttr )
234 mp3DObj->SetMergedItemSet(rAttr, true);
235 Resize();
236 Invalidate();
239 #define RADIUS_LAMP_PREVIEW_SIZE (4500.0)
240 #define RADIUS_LAMP_SMALL (600.0)
241 #define RADIUS_LAMP_BIG (1000.0)
242 #define NO_LIGHT_SELECTED (0xffffffff)
243 #define MAX_NUMBER_LIGHTS (8)
245 const sal_Int32 g_nInteractionStartDistance = 5 * 5 * 2;
247 Svx3DLightControl::Svx3DLightControl()
248 : maSelectedLight(NO_LIGHT_SELECTED),
249 maLightObjects(MAX_NUMBER_LIGHTS, nullptr),
250 mfRotateX(-20.0),
251 mfRotateY(45.0),
252 mfRotateZ(0.0),
253 mfSaveActionStartHor(0.0),
254 mfSaveActionStartVer(0.0),
255 mfSaveActionStartRotZ(0.0),
256 mbMouseMoved(false),
257 mbMouseCaptured(false),
258 mbGeometrySelected(false)
262 void Svx3DLightControl::SetDrawingArea(weld::DrawingArea* pDrawingArea)
264 Svx3DPreviewControl::SetDrawingArea(pDrawingArea);
265 Construct2();
268 void Svx3DLightControl::Construct2()
271 // hide all page stuff, use control background (normally gray)
272 const Color aDialogColor(Application::GetSettings().GetStyleSettings().GetDialogColor());
273 mp3DView->SetPageVisible(false);
274 mp3DView->SetApplicationBackgroundColor(aDialogColor);
275 mp3DView->SetApplicationDocumentColor(aDialogColor);
279 // create invisible expansion object
280 const double fMaxExpansion(RADIUS_LAMP_BIG + RADIUS_LAMP_PREVIEW_SIZE);
281 mpExpansionObject = new E3dCubeObj(
282 *mpModel,
283 mp3DView->Get3DDefaultAttributes(),
284 basegfx::B3DPoint(-fMaxExpansion, -fMaxExpansion, -fMaxExpansion),
285 basegfx::B3DVector(2.0 * fMaxExpansion, 2.0 * fMaxExpansion, 2.0 * fMaxExpansion));
286 mpScene->InsertObject( mpExpansionObject.get() );
287 SfxItemSet aSet(mpModel->GetItemPool());
288 aSet.Put( XLineStyleItem( drawing::LineStyle_NONE ) );
289 aSet.Put( XFillStyleItem( drawing::FillStyle_NONE ) );
290 mpExpansionObject->SetMergedItemSet(aSet);
294 // create lamp control object (Yellow lined object)
295 // base circle
296 const basegfx::B2DPolygon a2DCircle(basegfx::utils::createPolygonFromCircle(basegfx::B2DPoint(0.0, 0.0), RADIUS_LAMP_PREVIEW_SIZE));
297 basegfx::B3DPolygon a3DCircle(basegfx::utils::createB3DPolygonFromB2DPolygon(a2DCircle));
298 basegfx::B3DHomMatrix aTransform;
300 aTransform.rotate(M_PI_2, 0.0, 0.0);
301 aTransform.translate(0.0, -RADIUS_LAMP_PREVIEW_SIZE, 0.0);
302 a3DCircle.transform(aTransform);
304 // create object for it
305 mpLampBottomObject = new E3dPolygonObj(
306 *mpModel,
307 basegfx::B3DPolyPolygon(a3DCircle));
308 mpScene->InsertObject( mpLampBottomObject.get() );
310 // half circle with stand
311 basegfx::B2DPolygon a2DHalfCircle;
312 a2DHalfCircle.append(basegfx::B2DPoint(RADIUS_LAMP_PREVIEW_SIZE, 0.0));
313 a2DHalfCircle.append(basegfx::B2DPoint(RADIUS_LAMP_PREVIEW_SIZE, -RADIUS_LAMP_PREVIEW_SIZE));
314 a2DHalfCircle.append(basegfx::utils::createPolygonFromEllipseSegment(
315 basegfx::B2DPoint(0.0, 0.0), RADIUS_LAMP_PREVIEW_SIZE, RADIUS_LAMP_PREVIEW_SIZE, 2 * M_PI - M_PI_2, M_PI_2));
316 basegfx::B3DPolygon a3DHalfCircle(basegfx::utils::createB3DPolygonFromB2DPolygon(a2DHalfCircle));
318 // create object for it
319 mpLampShaftObject = new E3dPolygonObj(
320 *mpModel,
321 basegfx::B3DPolyPolygon(a3DHalfCircle));
322 mpScene->InsertObject( mpLampShaftObject.get() );
324 // initially invisible
325 SfxItemSet aSet(mpModel->GetItemPool());
326 aSet.Put( XLineStyleItem( drawing::LineStyle_NONE ) );
327 aSet.Put( XFillStyleItem( drawing::FillStyle_NONE ) );
329 mpLampBottomObject->SetMergedItemSet(aSet);
330 mpLampShaftObject->SetMergedItemSet(aSet);
334 // change camera settings
335 Camera3D rCamera = mpScene->GetCamera();
336 const basegfx::B3DRange& rVolume = mpScene->GetBoundVolume();
337 double fW = rVolume.getWidth();
338 double fH = rVolume.getHeight();
339 double fCamZ = rVolume.getMaxZ() + ((fW + fH) / 2.0);
341 rCamera.SetAutoAdjustProjection(false);
342 rCamera.SetViewWindow(- fW / 2, - fH / 2, fW, fH);
343 basegfx::B3DPoint aLookAt;
344 double fDefaultCamPosZ = mp3DView->GetDefaultCamPosZ();
345 basegfx::B3DPoint aCamPos(0.0, 0.0, fCamZ < fDefaultCamPosZ ? fDefaultCamPosZ : fCamZ);
346 rCamera.SetPosAndLookAt(aCamPos, aLookAt);
347 double fDefaultCamFocal = mp3DView->GetDefaultCamFocal();
348 rCamera.SetFocalLength(fDefaultCamFocal);
350 mpScene->SetCamera( rCamera );
352 basegfx::B3DHomMatrix aNeutral;
353 mpScene->SetTransform(aNeutral);
356 // invalidate SnapRects of objects
357 mpScene->SetBoundAndSnapRectsDirty();
360 void Svx3DLightControl::ConstructLightObjects()
362 for(sal_uInt32 a(0); a < MAX_NUMBER_LIGHTS; a++)
364 // get rid of possible existing light object
365 if(maLightObjects[a])
367 mpScene->RemoveObject(maLightObjects[a]->GetOrdNum());
368 maLightObjects[a] = nullptr;
371 if(GetLightOnOff(a))
373 const bool bIsSelectedLight(a == maSelectedLight);
374 basegfx::B3DVector aDirection(GetLightDirection(a));
375 aDirection.normalize();
376 aDirection *= RADIUS_LAMP_PREVIEW_SIZE;
378 const double fLampSize(bIsSelectedLight ? RADIUS_LAMP_BIG : RADIUS_LAMP_SMALL);
379 rtl::Reference<E3dObject> pNewLight = new E3dSphereObj(
380 *mpModel,
381 mp3DView->Get3DDefaultAttributes(),
382 basegfx::B3DPoint( 0, 0, 0 ),
383 basegfx::B3DVector( fLampSize, fLampSize, fLampSize));
384 mpScene->InsertObject(pNewLight.get());
386 basegfx::B3DHomMatrix aTransform;
387 aTransform.translate(aDirection.getX(), aDirection.getY(), aDirection.getZ());
388 pNewLight->SetTransform(aTransform);
390 SfxItemSet aSet(mpModel->GetItemPool());
391 aSet.Put( XLineStyleItem( drawing::LineStyle_NONE ) );
392 aSet.Put( XFillStyleItem( drawing::FillStyle_SOLID ) );
393 aSet.Put( XFillColorItem(OUString(), GetLightColor(a)));
394 pNewLight->SetMergedItemSet(aSet);
396 maLightObjects[a] = pNewLight.get();
401 void Svx3DLightControl::AdaptToSelectedLight()
403 if(NO_LIGHT_SELECTED == maSelectedLight)
405 // make mpLampBottomObject/mpLampShaftObject invisible
406 SfxItemSet aSet(mpModel->GetItemPool());
407 aSet.Put( XLineStyleItem( drawing::LineStyle_NONE ) );
408 aSet.Put( XFillStyleItem( drawing::FillStyle_NONE ) );
409 mpLampBottomObject->SetMergedItemSet(aSet);
410 mpLampShaftObject->SetMergedItemSet(aSet);
412 else
414 basegfx::B3DVector aDirection(GetLightDirection(maSelectedLight));
415 aDirection.normalize();
417 // make mpLampBottomObject/mpLampShaftObject visible (yellow hairline)
418 SfxItemSet aSet(mpModel->GetItemPool());
419 aSet.Put( XLineStyleItem( drawing::LineStyle_SOLID ) );
420 aSet.Put( XLineColorItem(OUString(), COL_YELLOW));
421 aSet.Put( XLineWidthItem(0));
422 aSet.Put( XFillStyleItem( drawing::FillStyle_NONE ) );
423 mpLampBottomObject->SetMergedItemSet(aSet);
424 mpLampShaftObject->SetMergedItemSet(aSet);
426 // adapt transformation of mpLampShaftObject
427 basegfx::B3DHomMatrix aTransform;
428 double fRotateY(0.0);
430 if(!basegfx::fTools::equalZero(aDirection.getZ()) || !basegfx::fTools::equalZero(aDirection.getX()))
432 fRotateY = atan2(-aDirection.getZ(), aDirection.getX());
435 aTransform.rotate(0.0, fRotateY, 0.0);
436 mpLampShaftObject->SetTransform(aTransform);
438 // adapt transformation of selected light
439 E3dObject* pSelectedLight = maLightObjects[sal_Int32(maSelectedLight)];
441 if(pSelectedLight)
443 aTransform.identity();
444 aTransform.translate(
445 aDirection.getX() * RADIUS_LAMP_PREVIEW_SIZE,
446 aDirection.getY() * RADIUS_LAMP_PREVIEW_SIZE,
447 aDirection.getZ() * RADIUS_LAMP_PREVIEW_SIZE);
448 pSelectedLight->SetTransform(aTransform);
453 void Svx3DLightControl::TrySelection(Point aPosPixel)
455 if(!mpScene)
456 return;
458 const Point aPosLogic(GetDrawingArea()->get_ref_device().PixelToLogic(aPosPixel));
459 const basegfx::B2DPoint aPoint(aPosLogic.X(), aPosLogic.Y());
460 std::vector< const E3dCompoundObject* > aResult;
461 getAllHit3DObjectsSortedFrontToBack(aPoint, *mpScene, aResult);
463 if(aResult.empty())
464 return;
466 // exclude expansion object which will be part of
467 // the hits. It's invisible, but for HitTest, it's included
468 const E3dCompoundObject* pResult = nullptr;
470 for(auto const & b: aResult)
472 if(b && b != mpExpansionObject.get())
474 pResult = b;
475 break;
479 if(pResult == mp3DObj.get())
481 if(!mbGeometrySelected)
483 mbGeometrySelected = true;
484 maSelectedLight = NO_LIGHT_SELECTED;
485 ConstructLightObjects();
486 AdaptToSelectedLight();
487 Invalidate();
489 if(maSelectionChangeCallback.IsSet())
491 maSelectionChangeCallback.Call(this);
495 else
497 sal_uInt32 aNewSelectedLight(NO_LIGHT_SELECTED);
499 for(sal_uInt32 a(0); a < MAX_NUMBER_LIGHTS; a++)
501 if(maLightObjects[a] && maLightObjects[a] == pResult)
503 aNewSelectedLight = a;
507 if(aNewSelectedLight != maSelectedLight)
509 SelectLight(aNewSelectedLight);
511 if(maSelectionChangeCallback.IsSet())
513 maSelectionChangeCallback.Call(this);
519 void Svx3DLightControl::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect)
521 Svx3DPreviewControl::Paint(rRenderContext, rRect);
524 tools::Rectangle Svx3DLightControl::GetFocusRect()
526 if (!HasFocus())
527 return tools::Rectangle();
528 Size aFocusSize = GetOutputSizePixel();
529 aFocusSize.AdjustWidth( -4 );
530 aFocusSize.AdjustHeight( -4 );
531 return tools::Rectangle(Point(2, 2), aFocusSize);
534 bool Svx3DLightControl::MouseButtonDown( const MouseEvent& rMEvt )
536 bool bCallParent(true);
538 // switch state
539 if(rMEvt.IsLeft())
541 if(IsSelectionValid() || mbGeometrySelected)
543 mbMouseMoved = false;
544 bCallParent = false;
545 maActionStartPoint = rMEvt.GetPosPixel();
546 CaptureMouse();
547 mbMouseCaptured = true;
549 else
551 // Single click without moving much trying to do a selection
552 TrySelection(rMEvt.GetPosPixel());
553 bCallParent = false;
557 // call parent
558 if (bCallParent)
559 return Svx3DPreviewControl::MouseButtonDown(rMEvt);
560 return true;
563 bool Svx3DLightControl::MouseMove(const MouseEvent& rMEvt)
565 if (!mbMouseCaptured)
566 return false;
568 Point aDeltaPos = rMEvt.GetPosPixel() - maActionStartPoint;
570 if(!mbMouseMoved)
572 if(sal_Int32(aDeltaPos.X() * aDeltaPos.X() + aDeltaPos.Y() * aDeltaPos.Y()) > g_nInteractionStartDistance)
574 if(mbGeometrySelected)
576 GetRotation(mfSaveActionStartVer, mfSaveActionStartHor, mfSaveActionStartRotZ);
578 else
580 // interaction start, save values
581 GetPosition(mfSaveActionStartHor, mfSaveActionStartVer);
584 mbMouseMoved = true;
588 if(mbMouseMoved)
590 if(mbGeometrySelected)
592 double fNewRotX = mfSaveActionStartVer - basegfx::deg2rad(aDeltaPos.Y());
593 double fNewRotY = mfSaveActionStartHor + basegfx::deg2rad(aDeltaPos.X());
595 // cut horizontal
596 while(fNewRotY < 0.0)
598 fNewRotY += 2 * M_PI;
601 while(fNewRotY >= 2 * M_PI)
603 fNewRotY -= 2 * M_PI;
606 // cut vertical
607 if(fNewRotX < -M_PI_2)
609 fNewRotX = -M_PI_2;
612 if(fNewRotX > M_PI_2)
614 fNewRotX = M_PI_2;
617 SetRotation(fNewRotX, fNewRotY, mfSaveActionStartRotZ);
619 if(maChangeCallback.IsSet())
621 maChangeCallback.Call(this);
624 else
626 // interaction in progress
627 double fNewPosHor = mfSaveActionStartHor + static_cast<double>(aDeltaPos.X());
628 double fNewPosVer = mfSaveActionStartVer - static_cast<double>(aDeltaPos.Y());
630 // cut horizontal
631 fNewPosHor = NormAngle360(fNewPosHor);
633 // cut vertical
634 if(fNewPosVer < -90.0)
636 fNewPosVer = -90.0;
639 if(fNewPosVer > 90.0)
641 fNewPosVer = 90.0;
644 SetPosition(fNewPosHor, fNewPosVer);
646 if(maChangeCallback.IsSet())
648 maChangeCallback.Call(this);
652 return true;
655 bool Svx3DLightControl::MouseButtonUp(const MouseEvent& rMEvt)
657 if (!mbMouseCaptured)
658 return false;
659 ReleaseMouse();
660 mbMouseCaptured = false;
662 if (mbMouseMoved)
664 // was change interactively
666 else
668 // simple click without much movement, try selection
669 TrySelection(rMEvt.GetPosPixel());
672 return true;
675 void Svx3DLightControl::Resize()
677 // set size of page
678 const Size aSize(GetDrawingArea()->get_ref_device().PixelToLogic(GetOutputSizePixel()));
679 mxFmPage->SetSize(aSize);
681 // set position and size of scene
682 mpScene->SetSnapRect(tools::Rectangle(Point(0, 0), aSize));
685 void Svx3DLightControl::SetObjectType(SvxPreviewObjectType nType)
687 // call parent
688 Svx3DPreviewControl::SetObjectType(nType);
690 // apply object rotation
691 if(mp3DObj)
693 basegfx::B3DHomMatrix aObjectRotation;
694 aObjectRotation.rotate(mfRotateX, mfRotateY, mfRotateZ);
695 mp3DObj->SetTransform(aObjectRotation);
699 bool Svx3DLightControl::IsSelectionValid()
701 return (NO_LIGHT_SELECTED != maSelectedLight) && GetLightOnOff(maSelectedLight);
704 void Svx3DLightControl::GetPosition(double& rHor, double& rVer)
706 if(IsSelectionValid())
708 basegfx::B3DVector aDirection(GetLightDirection(maSelectedLight));
709 aDirection.normalize();
710 rHor = basegfx::rad2deg(atan2(-aDirection.getX(), -aDirection.getZ()) + M_PI); // 0..360.0
711 rVer = basegfx::rad2deg(atan2(aDirection.getY(), aDirection.getXZLength())); // -90.0..90.0
713 if(IsGeometrySelected())
715 rHor = basegfx::rad2deg(mfRotateY); // 0..360.0
716 rVer = basegfx::rad2deg(mfRotateX); // -90.0..90.0
720 void Svx3DLightControl::SetPosition(double fHor, double fVer)
722 if(IsSelectionValid())
724 // set selected light's direction
725 fHor = basegfx::deg2rad(fHor) - M_PI; // -PI..PI
726 fVer = basegfx::deg2rad(fVer); // -PI2..PI2
727 basegfx::B3DVector aDirection(cos(fVer) * -sin(fHor), sin(fVer), cos(fVer) * -cos(fHor));
728 aDirection.normalize();
730 if(!aDirection.equal(GetLightDirection(maSelectedLight)))
732 // set changed light direction at SdrScene
733 SfxItemSet aSet(mpModel->GetItemPool());
735 switch(maSelectedLight)
737 case 0: aSet.Put(makeSvx3DLightDirection1Item(aDirection)); break;
738 case 1: aSet.Put(makeSvx3DLightDirection2Item(aDirection)); break;
739 case 2: aSet.Put(makeSvx3DLightDirection3Item(aDirection)); break;
740 case 3: aSet.Put(makeSvx3DLightDirection4Item(aDirection)); break;
741 case 4: aSet.Put(makeSvx3DLightDirection5Item(aDirection)); break;
742 case 5: aSet.Put(makeSvx3DLightDirection6Item(aDirection)); break;
743 case 6: aSet.Put(makeSvx3DLightDirection7Item(aDirection)); break;
744 default:
745 case 7: aSet.Put(makeSvx3DLightDirection8Item(aDirection)); break;
748 mpScene->SetMergedItemSet(aSet);
750 // correct 3D light's and LampFrame's geometries
751 AdaptToSelectedLight();
752 Invalidate();
755 if(!IsGeometrySelected())
756 return;
758 if(mfRotateX == fVer && mfRotateY == fHor)
759 return;
761 mfRotateX = basegfx::deg2rad(fVer);
762 mfRotateY = basegfx::deg2rad(fHor);
764 if(mp3DObj)
766 basegfx::B3DHomMatrix aObjectRotation;
767 aObjectRotation.rotate(mfRotateX, mfRotateY, mfRotateZ);
768 mp3DObj->SetTransform(aObjectRotation);
770 Invalidate();
774 void Svx3DLightControl::SetRotation(double fRotX, double fRotY, double fRotZ)
776 if(!IsGeometrySelected())
777 return;
779 if(fRotX == mfRotateX && fRotY == mfRotateY && fRotZ == mfRotateZ)
780 return;
782 mfRotateX = fRotX;
783 mfRotateY = fRotY;
784 mfRotateZ = fRotZ;
786 if(mp3DObj)
788 basegfx::B3DHomMatrix aObjectRotation;
789 aObjectRotation.rotate(mfRotateX, mfRotateY, mfRotateZ);
790 mp3DObj->SetTransform(aObjectRotation);
792 Invalidate();
796 void Svx3DLightControl::GetRotation(double& rRotX, double& rRotY, double& rRotZ)
798 rRotX = mfRotateX;
799 rRotY = mfRotateY;
800 rRotZ = mfRotateZ;
803 void Svx3DLightControl::Set3DAttributes( const SfxItemSet& rAttr )
805 // call parent
806 Svx3DPreviewControl::Set3DAttributes(rAttr);
808 if(maSelectedLight != NO_LIGHT_SELECTED && !GetLightOnOff(maSelectedLight))
810 // selected light is no more active, select new one
811 maSelectedLight = NO_LIGHT_SELECTED;
814 // local updates
815 ConstructLightObjects();
816 AdaptToSelectedLight();
817 Invalidate();
820 void Svx3DLightControl::SelectLight(sal_uInt32 nLightNumber)
822 if(nLightNumber > 7)
824 nLightNumber = NO_LIGHT_SELECTED;
827 if(NO_LIGHT_SELECTED != nLightNumber)
829 if(!GetLightOnOff(nLightNumber))
831 nLightNumber = NO_LIGHT_SELECTED;
835 if(nLightNumber != maSelectedLight)
837 maSelectedLight = nLightNumber;
838 mbGeometrySelected = false;
839 ConstructLightObjects();
840 AdaptToSelectedLight();
841 Invalidate();
845 bool Svx3DLightControl::GetLightOnOff(sal_uInt32 nNum) const
847 if(nNum <= 7)
849 const SfxItemSet aLightItemSet(Get3DAttributes());
851 switch(nNum)
853 case 0 : return aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTON_1).GetValue();
854 case 1 : return aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTON_2).GetValue();
855 case 2 : return aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTON_3).GetValue();
856 case 3 : return aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTON_4).GetValue();
857 case 4 : return aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTON_5).GetValue();
858 case 5 : return aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTON_6).GetValue();
859 case 6 : return aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTON_7).GetValue();
860 case 7 : return aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTON_8).GetValue();
864 return false;
867 Color Svx3DLightControl::GetLightColor(sal_uInt32 nNum) const
869 if(nNum <= 7)
871 const SfxItemSet aLightItemSet(Get3DAttributes());
873 switch(nNum)
875 case 0 : return aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTCOLOR_1).GetValue();
876 case 1 : return aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTCOLOR_2).GetValue();
877 case 2 : return aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTCOLOR_3).GetValue();
878 case 3 : return aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTCOLOR_4).GetValue();
879 case 4 : return aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTCOLOR_5).GetValue();
880 case 5 : return aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTCOLOR_6).GetValue();
881 case 6 : return aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTCOLOR_7).GetValue();
882 case 7 : return aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTCOLOR_8).GetValue();
886 return COL_BLACK;
889 basegfx::B3DVector Svx3DLightControl::GetLightDirection(sal_uInt32 nNum) const
891 if(nNum <= 7)
893 const SfxItemSet aLightItemSet(Get3DAttributes());
895 switch(nNum)
897 case 0 : return aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_1).GetValue();
898 case 1 : return aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_2).GetValue();
899 case 2 : return aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_3).GetValue();
900 case 3 : return aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_4).GetValue();
901 case 4 : return aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_5).GetValue();
902 case 5 : return aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_6).GetValue();
903 case 6 : return aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_7).GetValue();
904 case 7 : return aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_8).GetValue();
908 return basegfx::B3DVector();
911 SvxLightCtl3D::SvxLightCtl3D(Svx3DLightControl& rLightControl, weld::Scale& rHori,
912 weld::Scale& rVert, weld::Button& rSwitcher)
913 : mrLightControl(rLightControl)
914 , mrHorScroller(rHori)
915 , mrVerScroller(rVert)
916 , mrSwitcher(rSwitcher)
918 // init members
919 Init();
922 void SvxLightCtl3D::Init()
924 Size aSize(mrLightControl.GetDrawingArea()->get_ref_device().LogicToPixel(Size(80, 100), MapMode(MapUnit::MapAppFont)));
925 mrLightControl.set_size_request(aSize.Width(), aSize.Height());
927 // #i58240# set HelpIDs for scrollbars and switcher
928 mrHorScroller.set_help_id(HID_CTRL3D_HSCROLL);
929 mrVerScroller.set_help_id(HID_CTRL3D_VSCROLL);
930 mrSwitcher.set_help_id(HID_CTRL3D_SWITCHER);
931 mrSwitcher.set_accessible_name(SvxResId(STR_SWITCH));
933 // Light preview
934 mrLightControl.Show();
935 mrLightControl.SetChangeCallback( LINK(this, SvxLightCtl3D, InternalInteractiveChange) );
936 mrLightControl.SetSelectionChangeCallback( LINK(this, SvxLightCtl3D, InternalSelectionChange) );
938 // Horiz Scrollbar
939 mrHorScroller.show();
940 mrHorScroller.set_range(0, 36000);
941 mrHorScroller.connect_value_changed( LINK(this, SvxLightCtl3D, ScrollBarMove) );
943 // Vert Scrollbar
944 mrVerScroller.show();
945 mrVerScroller.set_range(0, 18000);
946 mrVerScroller.connect_value_changed( LINK(this, SvxLightCtl3D, ScrollBarMove) );
948 // Switch Button
949 mrSwitcher.show();
950 mrSwitcher.connect_clicked( LINK(this, SvxLightCtl3D, ButtonPress) );
952 weld::DrawingArea* pArea = mrLightControl.GetDrawingArea();
953 pArea->connect_key_press(Link<const KeyEvent&, bool>()); //acknowledge we first remove the old one
954 pArea->connect_key_press(LINK(this, SvxLightCtl3D, KeyInput));
956 pArea->connect_focus_in(Link<weld::Widget&, void>()); //acknowledge we first remove the old one
957 pArea->connect_focus_in(LINK(this, SvxLightCtl3D, FocusIn));
959 // check selection
960 CheckSelection();
963 void SvxLightCtl3D::CheckSelection()
965 const bool bSelectionValid(mrLightControl.IsSelectionValid() || mrLightControl.IsGeometrySelected());
966 mrHorScroller.set_sensitive(bSelectionValid);
967 mrVerScroller.set_sensitive(bSelectionValid);
969 if (bSelectionValid)
971 double fHor(0.0), fVer(0.0);
972 mrLightControl.GetPosition(fHor, fVer);
973 mrHorScroller.set_value( sal_Int32(fHor * 100.0) );
974 mrVerScroller.set_value( 18000 - sal_Int32((fVer + 90.0) * 100.0) );
978 void SvxLightCtl3D::move( double fDeltaHor, double fDeltaVer )
980 double fHor(0.0), fVer(0.0);
982 mrLightControl.GetPosition(fHor, fVer);
983 fHor += fDeltaHor;
984 fVer += fDeltaVer;
986 if( fVer > 90.0 )
987 return;
989 if ( fVer < -90.0 )
990 return;
992 mrLightControl.SetPosition(fHor, fVer);
993 mrHorScroller.set_value( sal_Int32(fHor * 100.0) );
994 mrVerScroller.set_value( 18000 - sal_Int32((fVer + 90.0) * 100.0) );
996 if(maUserInteractiveChangeCallback.IsSet())
998 maUserInteractiveChangeCallback.Call(this);
1002 IMPL_LINK(SvxLightCtl3D, KeyInput, const KeyEvent&, rKEvt, bool)
1004 const vcl::KeyCode aCode(rKEvt.GetKeyCode());
1006 if (aCode.GetModifier())
1007 return false;
1009 bool bHandled = true;
1011 switch ( aCode.GetCode() )
1013 case KEY_SPACE:
1015 break;
1017 case KEY_LEFT:
1019 move( -4.0, 0.0 ); // #i58242# changed move direction in X
1020 break;
1022 case KEY_RIGHT:
1024 move( 4.0, 0.0 ); // #i58242# changed move direction in X
1025 break;
1027 case KEY_UP:
1029 move( 0.0, 4.0 );
1030 break;
1032 case KEY_DOWN:
1034 move( 0.0, -4.0 );
1035 break;
1037 case KEY_PAGEUP:
1039 sal_Int32 nLight(mrLightControl.GetSelectedLight() - 1);
1041 while((nLight >= 0) && !mrLightControl.GetLightOnOff(nLight))
1043 nLight--;
1046 if(nLight < 0)
1048 nLight = 7;
1050 while((nLight >= 0) && !mrLightControl.GetLightOnOff(nLight))
1052 nLight--;
1056 if(nLight >= 0)
1058 mrLightControl.SelectLight(nLight);
1059 CheckSelection();
1061 if(maUserSelectionChangeCallback.IsSet())
1063 maUserSelectionChangeCallback.Call(this);
1067 break;
1069 case KEY_PAGEDOWN:
1071 sal_Int32 nLight(mrLightControl.GetSelectedLight() - 1);
1073 while(nLight <= 7 && !mrLightControl.GetLightOnOff(nLight))
1075 nLight++;
1078 if(nLight > 7)
1080 nLight = 0;
1082 while(nLight <= 7 && !mrLightControl.GetLightOnOff(nLight))
1084 nLight++;
1088 if(nLight <= 7)
1090 mrLightControl.SelectLight(nLight);
1091 CheckSelection();
1093 if(maUserSelectionChangeCallback.IsSet())
1095 maUserSelectionChangeCallback.Call(this);
1099 break;
1101 default:
1103 bHandled = false;
1104 break;
1107 return bHandled;
1110 IMPL_LINK_NOARG(SvxLightCtl3D, FocusIn, weld::Widget&, void)
1112 if (mrLightControl.IsEnabled())
1114 CheckSelection();
1118 IMPL_LINK_NOARG(SvxLightCtl3D, ScrollBarMove, weld::Scale&, void)
1120 const sal_Int32 nHor(mrHorScroller.get_value());
1121 const sal_Int32 nVer(mrVerScroller.get_value());
1123 mrLightControl.SetPosition(
1124 static_cast<double>(nHor) / 100.0,
1125 static_cast<double>((18000 - nVer) - 9000) / 100.0);
1127 if (maUserInteractiveChangeCallback.IsSet())
1129 maUserInteractiveChangeCallback.Call(this);
1133 IMPL_LINK_NOARG(SvxLightCtl3D, ButtonPress, weld::Button&, void)
1135 if(SvxPreviewObjectType::SPHERE == GetSvx3DLightControl().GetObjectType())
1137 GetSvx3DLightControl().SetObjectType(SvxPreviewObjectType::CUBE);
1139 else
1141 GetSvx3DLightControl().SetObjectType(SvxPreviewObjectType::SPHERE);
1145 IMPL_LINK_NOARG(SvxLightCtl3D, InternalInteractiveChange, Svx3DLightControl*, void)
1147 double fHor(0.0), fVer(0.0);
1149 mrLightControl.GetPosition(fHor, fVer);
1150 mrHorScroller.set_value( sal_Int32(fHor * 100.0) );
1151 mrVerScroller.set_value( 18000 - sal_Int32((fVer + 90.0) * 100.0) );
1153 if(maUserInteractiveChangeCallback.IsSet())
1155 maUserInteractiveChangeCallback.Call(this);
1159 IMPL_LINK_NOARG(SvxLightCtl3D, InternalSelectionChange, Svx3DLightControl*, void)
1161 CheckSelection();
1163 if(maUserSelectionChangeCallback.IsSet())
1165 maUserSelectionChangeCallback.Call(this);
1169 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */