xref: /AOO41X/main/svx/source/dialog/dlgctl3d.cxx (revision f6e50924346d0b8c0b07c91832a97665dd718b0c)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_svx.hxx"
26 
27 #include <svx/dlgctl3d.hxx>
28 #include <svx/dialogs.hrc>
29 #include <svx/view3d.hxx>
30 #include <svx/fmmodel.hxx>
31 #include <svl/itempool.hxx>
32 #include <svx/fmpage.hxx>
33 #include <svx/polysc3d.hxx>
34 #include <svx/sphere3d.hxx>
35 #include <svx/cube3d.hxx>
36 #include <vcl/svapp.hxx>
37 #include <svx/helperhittest3d.hxx>
38 #include <basegfx/polygon/b2dpolygontools.hxx>
39 #include <svx/polygn3d.hxx>
40 #include <svx/xlnclit.hxx>
41 #include <svx/xlnwtit.hxx>
42 #include "helpid.hrc"
43 #include <algorithm>
44 #include <svx/dialmgr.hxx>
45 
46 //////////////////////////////////////////////////////////////////////////////
47 
Svx3DPreviewControl(Window * pParent,const ResId & rResId)48 Svx3DPreviewControl::Svx3DPreviewControl(Window* pParent, const ResId& rResId)
49 :   Control(pParent, rResId),
50     mpModel(0),
51     mpFmPage(0),
52     mp3DView(0),
53     mpScene(0),
54     mp3DObj(0),
55     mnObjectType(PREVIEW_OBJECTTYPE_SPHERE)
56 {
57     Construct();
58 
59     // do not paint background self, DrawingLayer paints this buffered and as page
60     SetControlBackground();
61     SetBackground();
62 }
63 
Svx3DPreviewControl(Window * pParent,WinBits nStyle)64 Svx3DPreviewControl::Svx3DPreviewControl(Window* pParent, WinBits nStyle)
65 :   Control(pParent, nStyle),
66     mpModel(0),
67     mpFmPage(0),
68     mp3DView(0),
69     mpScene(0),
70     mp3DObj(0),
71     mnObjectType(PREVIEW_OBJECTTYPE_SPHERE)
72 {
73     Construct();
74 
75     // do not paint background self, DrawingLayer paints this buffered and as page
76     SetControlBackground();
77     SetBackground();
78 }
79 
~Svx3DPreviewControl()80 Svx3DPreviewControl::~Svx3DPreviewControl()
81 {
82     delete mp3DView;
83     delete mpModel;
84 }
85 
Construct()86 void Svx3DPreviewControl::Construct()
87 {
88     // Do never mirror the preview window.  This explicitly includes right
89     // to left writing environments.
90     EnableRTL (sal_False);
91     SetMapMode( MAP_100TH_MM );
92 
93     // Model
94     mpModel = new FmFormModel();
95     mpModel->GetItemPool().FreezeIdRanges();
96 
97     // Page
98     mpFmPage = new FmFormPage( *mpModel, NULL );
99     mpModel->InsertPage( mpFmPage, 0 );
100 
101     // 3D View
102     mp3DView = new E3dView( mpModel, this );
103     mp3DView->SetBufferedOutputAllowed(true);
104     mp3DView->SetBufferedOverlayAllowed(true);
105 
106     // 3D Scene
107     mpScene = new E3dPolyScene(mp3DView->Get3DDefaultAttributes());
108 
109     // initially create object
110     SetObjectType(PREVIEW_OBJECTTYPE_SPHERE);
111 
112     // camera and perspective
113     Camera3D& rCamera  = (Camera3D&) mpScene->GetCamera();
114     const basegfx::B3DRange& rVolume = mpScene->GetBoundVolume();
115     double fW = rVolume.getWidth();
116     double fH = rVolume.getHeight();
117     double fCamZ = rVolume.getMaxZ() + ((fW + fH) / 2.0);
118 
119     rCamera.SetAutoAdjustProjection(sal_False);
120     rCamera.SetViewWindow(- fW / 2, - fH / 2, fW, fH);
121     basegfx::B3DPoint aLookAt;
122     double fDefaultCamPosZ = mp3DView->GetDefaultCamPosZ();
123     basegfx::B3DPoint aCamPos(0.0, 0.0, fCamZ < fDefaultCamPosZ ? fDefaultCamPosZ : fCamZ);
124     rCamera.SetPosAndLookAt(aCamPos, aLookAt);
125     double fDefaultCamFocal = mp3DView->GetDefaultCamFocal();
126     rCamera.SetFocalLength(fDefaultCamFocal);
127     rCamera.SetDefaults(basegfx::B3DPoint(0.0, 0.0, fDefaultCamPosZ), aLookAt, fDefaultCamFocal);
128 
129     mpScene->SetCamera( rCamera );
130     mpFmPage->InsertObject( mpScene );
131 
132     basegfx::B3DHomMatrix aRotation;
133     aRotation.rotate(DEG2RAD( 25 ), 0.0, 0.0);
134     aRotation.rotate(0.0, DEG2RAD( 40 ), 0.0);
135     mpScene->SetTransform(aRotation * mpScene->GetTransform());
136 
137     // invalidate SnapRects of objects
138     mpScene->SetRectsDirty();
139 
140     SfxItemSet aSet( mpModel->GetItemPool(),
141         XATTR_LINESTYLE, XATTR_LINESTYLE,
142         XATTR_FILL_FIRST, XATTR_FILLBITMAP,
143         0, 0 );
144     aSet.Put( XLineStyleItem( XLINE_NONE ) );
145     aSet.Put( XFillStyleItem( XFILL_SOLID ) );
146     aSet.Put( XFillColorItem( String(), Color( COL_WHITE ) ) );
147 
148     mpScene->SetMergedItemSet(aSet);
149 
150     // PageView
151     SdrPageView* pPageView = mp3DView->ShowSdrPage( mpFmPage );
152     mp3DView->hideMarkHandles();
153 
154     // mark scene
155     mp3DView->MarkObj( mpScene, pPageView );
156 }
157 
Resize()158 void Svx3DPreviewControl::Resize()
159 {
160     // size of page
161     Size aSize( GetSizePixel() );
162     aSize = PixelToLogic( aSize );
163     mpFmPage->SetSize( aSize );
164 
165     // set size
166     Size aObjSize( aSize.Width()*5/6, aSize.Height()*5/6 );
167     Point aObjPoint( (aSize.Width() - aObjSize.Width()) / 2,
168         (aSize.Height() - aObjSize.Height()) / 2);
169     Rectangle aRect( aObjPoint, aObjSize);
170     mpScene->SetSnapRect( aRect );
171 }
172 
Paint(const Rectangle & rRect)173 void Svx3DPreviewControl::Paint(const Rectangle& rRect)
174 {
175     mp3DView->CompleteRedraw(this, Region(rRect));
176 }
177 
MouseButtonDown(const MouseEvent & rMEvt)178 void Svx3DPreviewControl::MouseButtonDown(const MouseEvent& rMEvt)
179 {
180     Control::MouseButtonDown(rMEvt);
181 
182     if( rMEvt.IsShift() && rMEvt.IsMod1() )
183     {
184         if(PREVIEW_OBJECTTYPE_SPHERE == GetObjectType())
185         {
186             SetObjectType(PREVIEW_OBJECTTYPE_CUBE);
187         }
188         else
189         {
190             SetObjectType(PREVIEW_OBJECTTYPE_SPHERE);
191         }
192     }
193 }
194 
SetObjectType(sal_uInt16 nType)195 void Svx3DPreviewControl::SetObjectType(sal_uInt16 nType)
196 {
197     if( mnObjectType != nType || !mp3DObj)
198     {
199         SfxItemSet aSet(mpModel->GetItemPool(), SDRATTR_START, SDRATTR_END, 0, 0);
200         mnObjectType = nType;
201 
202         if( mp3DObj )
203         {
204             aSet.Put(mp3DObj->GetMergedItemSet());
205             mpScene->Remove3DObj( mp3DObj );
206             delete mp3DObj;
207             mp3DObj = NULL;
208         }
209 
210         switch( nType )
211         {
212             case PREVIEW_OBJECTTYPE_SPHERE:
213             {
214                 mp3DObj = new E3dSphereObj(
215                     mp3DView->Get3DDefaultAttributes(),
216                     basegfx::B3DPoint( 0, 0, 0 ),
217                     basegfx::B3DVector( 5000, 5000, 5000 ));
218             }
219             break;
220 
221             case PREVIEW_OBJECTTYPE_CUBE:
222             {
223                 mp3DObj = new E3dCubeObj(
224                     mp3DView->Get3DDefaultAttributes(),
225                     basegfx::B3DPoint( -2500, -2500, -2500 ),
226                     basegfx::B3DVector( 5000, 5000, 5000 ));
227             }
228             break;
229         }
230 
231         mpScene->Insert3DObj( mp3DObj );
232         mp3DObj->SetMergedItemSet(aSet);
233 
234         Resize();
235     }
236 }
237 
Get3DAttributes() const238 SfxItemSet Svx3DPreviewControl::Get3DAttributes() const
239 {
240     return mp3DObj->GetMergedItemSet();
241 }
242 
Set3DAttributes(const SfxItemSet & rAttr)243 void Svx3DPreviewControl::Set3DAttributes( const SfxItemSet& rAttr )
244 {
245     mp3DObj->SetMergedItemSet(rAttr, true);
246     Resize();
247 }
248 
249 //////////////////////////////////////////////////////////////////////////////
250 
251 #define RADIUS_LAMP_PREVIEW_SIZE    (4500.0)
252 #define RADIUS_LAMP_SMALL           (600.0)
253 #define RADIUS_LAMP_BIG             (1000.0)
254 #define NO_LIGHT_SELECTED           (0xffffffff)
255 #define MAX_NUMBER_LIGHTS              (8)
256 
Svx3DLightControl(Window * pParent,const ResId & rResId)257 Svx3DLightControl::Svx3DLightControl(Window* pParent, const ResId& rResId)
258 :   Svx3DPreviewControl(pParent, rResId),
259     maUserInteractiveChangeCallback(),
260     maUserSelectionChangeCallback(),
261     maChangeCallback(),
262     maSelectionChangeCallback(),
263     maSelectedLight(NO_LIGHT_SELECTED),
264     mpExpansionObject(0),
265     mpLampBottomObject(0),
266     mpLampShaftObject(0),
267     maLightObjects(MAX_NUMBER_LIGHTS, (E3dObject*)0),
268     mfRotateX(-20.0),
269     mfRotateY(45.0),
270     mfRotateZ(0.0),
271     maActionStartPoint(),
272     mnInteractionStartDistance(5 * 5 * 2),
273     mfSaveActionStartHor(0.0),
274     mfSaveActionStartVer(0.0),
275     mfSaveActionStartRotZ(0.0),
276     mbMouseMoved(false),
277     mbGeometrySelected(false)
278 {
279     Construct2();
280 }
281 
Svx3DLightControl(Window * pParent,WinBits nStyle)282 Svx3DLightControl::Svx3DLightControl(Window* pParent, WinBits nStyle)
283 :   Svx3DPreviewControl(pParent, nStyle),
284     maUserInteractiveChangeCallback(),
285     maUserSelectionChangeCallback(),
286     maChangeCallback(),
287     maSelectionChangeCallback(),
288     maSelectedLight(NO_LIGHT_SELECTED),
289     mpExpansionObject(0),
290     mpLampBottomObject(0),
291     mpLampShaftObject(0),
292     maLightObjects(MAX_NUMBER_LIGHTS, (E3dObject*)0),
293     mfRotateX(-20.0),
294     mfRotateY(45.0),
295     mfRotateZ(0.0),
296     maActionStartPoint(),
297     mnInteractionStartDistance(5 * 5 * 2),
298     mfSaveActionStartHor(0.0),
299     mfSaveActionStartVer(0.0),
300     mfSaveActionStartRotZ(0.0),
301     mbMouseMoved(false),
302     mbGeometrySelected(false)
303 {
304     Construct2();
305 }
306 
~Svx3DLightControl()307 Svx3DLightControl::~Svx3DLightControl()
308 {
309     // SdrObjects like mpExpansionObject and mpLampBottomObject/mpLampShaftObject get deleted
310     // with deletion of the DrawingLayer and model
311 }
312 
Construct2()313 void Svx3DLightControl::Construct2()
314 {
315     {
316         // hide all page stuff, use control background (normally gray)
317         const Color aDialogColor(Application::GetSettings().GetStyleSettings().GetDialogColor());
318         mp3DView->SetPageVisible(false);
319         mp3DView->SetApplicationBackgroundColor(aDialogColor);
320         mp3DView->SetApplicationDocumentColor(aDialogColor);
321     }
322 
323     {
324         // create invisible expansion object
325         const double fMaxExpansion(RADIUS_LAMP_BIG + RADIUS_LAMP_PREVIEW_SIZE);
326         mpExpansionObject = new E3dCubeObj(
327             mp3DView->Get3DDefaultAttributes(),
328             basegfx::B3DPoint(-fMaxExpansion, -fMaxExpansion, -fMaxExpansion),
329             basegfx::B3DVector(2.0 * fMaxExpansion, 2.0 * fMaxExpansion, 2.0 * fMaxExpansion));
330         mpScene->Insert3DObj( mpExpansionObject );
331         SfxItemSet aSet(mpModel->GetItemPool());
332         aSet.Put( XLineStyleItem( XLINE_NONE ) );
333         aSet.Put( XFillStyleItem( XFILL_NONE ) );
334         mpExpansionObject->SetMergedItemSet(aSet);
335     }
336 
337     {
338         // create lamp control object (Yellow lined object)
339         // base circle
340         const basegfx::B2DPolygon a2DCircle(basegfx::tools::createPolygonFromCircle(basegfx::B2DPoint(0.0, 0.0), RADIUS_LAMP_PREVIEW_SIZE));
341         basegfx::B3DPolygon a3DCircle(basegfx::tools::createB3DPolygonFromB2DPolygon(a2DCircle));
342         basegfx::B3DHomMatrix aTransform;
343 
344         aTransform.rotate(F_PI2, 0.0, 0.0);
345         aTransform.translate(0.0, -RADIUS_LAMP_PREVIEW_SIZE, 0.0);
346         a3DCircle.transform(aTransform);
347 
348         // create object for it
349         mpLampBottomObject = new E3dPolygonObj(
350             mp3DView->Get3DDefaultAttributes(),
351             basegfx::B3DPolyPolygon(a3DCircle),
352             true);
353         mpScene->Insert3DObj( mpLampBottomObject );
354 
355         // half circle with stand
356         basegfx::B2DPolygon a2DHalfCircle;
357         a2DHalfCircle.append(basegfx::B2DPoint(RADIUS_LAMP_PREVIEW_SIZE, 0.0));
358         a2DHalfCircle.append(basegfx::B2DPoint(RADIUS_LAMP_PREVIEW_SIZE, -RADIUS_LAMP_PREVIEW_SIZE));
359         a2DHalfCircle.append(basegfx::tools::createPolygonFromEllipseSegment(
360             basegfx::B2DPoint(0.0, 0.0), RADIUS_LAMP_PREVIEW_SIZE, RADIUS_LAMP_PREVIEW_SIZE, F_2PI - F_PI2, F_PI2));
361         basegfx::B3DPolygon a3DHalfCircle(basegfx::tools::createB3DPolygonFromB2DPolygon(a2DHalfCircle));
362 
363         // create object for it
364         mpLampShaftObject = new E3dPolygonObj(
365             mp3DView->Get3DDefaultAttributes(),
366             basegfx::B3DPolyPolygon(a3DHalfCircle),
367             true);
368         mpScene->Insert3DObj( mpLampShaftObject );
369 
370         // initially invisible
371         SfxItemSet aSet(mpModel->GetItemPool());
372         aSet.Put( XLineStyleItem( XLINE_NONE ) );
373         aSet.Put( XFillStyleItem( XFILL_NONE ) );
374 
375         mpLampBottomObject->SetMergedItemSet(aSet);
376         mpLampShaftObject->SetMergedItemSet(aSet);
377     }
378 
379     {
380         // change camera settings
381         Camera3D& rCamera  = (Camera3D&) mpScene->GetCamera();
382         const basegfx::B3DRange& rVolume = mpScene->GetBoundVolume();
383         double fW = rVolume.getWidth();
384         double fH = rVolume.getHeight();
385         double fCamZ = rVolume.getMaxZ() + ((fW + fH) / 2.0);
386 
387         rCamera.SetAutoAdjustProjection(sal_False);
388         rCamera.SetViewWindow(- fW / 2, - fH / 2, fW, fH);
389         basegfx::B3DPoint aLookAt;
390         double fDefaultCamPosZ = mp3DView->GetDefaultCamPosZ();
391         basegfx::B3DPoint aCamPos(0.0, 0.0, fCamZ < fDefaultCamPosZ ? fDefaultCamPosZ : fCamZ);
392         rCamera.SetPosAndLookAt(aCamPos, aLookAt);
393         double fDefaultCamFocal = mp3DView->GetDefaultCamFocal();
394         rCamera.SetFocalLength(fDefaultCamFocal);
395         rCamera.SetDefaults(basegfx::B3DPoint(0.0, 0.0, fDefaultCamPosZ), aLookAt, fDefaultCamFocal);
396 
397         mpScene->SetCamera( rCamera );
398 
399         basegfx::B3DHomMatrix aNeutral;
400         mpScene->SetTransform(aNeutral);
401     }
402 
403     // invalidate SnapRects of objects
404     mpScene->SetRectsDirty();
405 }
406 
ConstructLightObjects()407 void Svx3DLightControl::ConstructLightObjects()
408 {
409     for(sal_uInt32 a(0); a < MAX_NUMBER_LIGHTS; a++)
410     {
411         // get rid of evtl. existing light object
412         if(maLightObjects[a])
413         {
414             mpScene->Remove3DObj(maLightObjects[a]);
415             delete maLightObjects[a];
416             maLightObjects[a] = 0;
417         }
418 
419         if(GetLightOnOff(a))
420         {
421             const bool bIsSelectedLight(a == maSelectedLight);
422             basegfx::B3DVector aDirection(GetLightDirection(a));
423             aDirection.normalize();
424             aDirection *= RADIUS_LAMP_PREVIEW_SIZE;
425 
426             const double fLampSize(bIsSelectedLight ? RADIUS_LAMP_BIG : RADIUS_LAMP_SMALL);
427             E3dObject* pNewLight = new E3dSphereObj(
428                 mp3DView->Get3DDefaultAttributes(),
429                 basegfx::B3DPoint( 0, 0, 0 ),
430                 basegfx::B3DVector( fLampSize, fLampSize, fLampSize));
431             mpScene->Insert3DObj(pNewLight);
432 
433             basegfx::B3DHomMatrix aTransform;
434             aTransform.translate(aDirection.getX(), aDirection.getY(), aDirection.getZ());
435             pNewLight->SetTransform(aTransform);
436 
437             SfxItemSet aSet(mpModel->GetItemPool());
438             aSet.Put( XLineStyleItem( XLINE_NONE ) );
439             aSet.Put( XFillStyleItem( XFILL_SOLID ) );
440             aSet.Put( XFillColorItem(String(), GetLightColor(a)));
441             pNewLight->SetMergedItemSet(aSet);
442 
443             maLightObjects[a] = pNewLight;
444         }
445     }
446 }
447 
AdaptToSelectedLight()448 void Svx3DLightControl::AdaptToSelectedLight()
449 {
450     if(NO_LIGHT_SELECTED == maSelectedLight)
451     {
452         // make mpLampBottomObject/mpLampShaftObject invisible
453         SfxItemSet aSet(mpModel->GetItemPool());
454         aSet.Put( XLineStyleItem( XLINE_NONE ) );
455         aSet.Put( XFillStyleItem( XFILL_NONE ) );
456         mpLampBottomObject->SetMergedItemSet(aSet);
457         mpLampShaftObject->SetMergedItemSet(aSet);
458     }
459     else
460     {
461         basegfx::B3DVector aDirection(GetLightDirection(maSelectedLight));
462         aDirection.normalize();
463 
464         // make mpLampBottomObject/mpLampShaftObject visible (yellow hairline)
465         SfxItemSet aSet(mpModel->GetItemPool());
466         aSet.Put( XLineStyleItem( XLINE_SOLID ) );
467         aSet.Put( XLineColorItem(String(), COL_YELLOW));
468         aSet.Put( XLineWidthItem(0));
469         aSet.Put( XFillStyleItem( XFILL_NONE ) );
470         mpLampBottomObject->SetMergedItemSet(aSet);
471         mpLampShaftObject->SetMergedItemSet(aSet);
472 
473         // adapt transformation of mpLampShaftObject
474         basegfx::B3DHomMatrix aTransform;
475         double fRotateY(0.0);
476 
477         if(!basegfx::fTools::equalZero(aDirection.getZ()) || !basegfx::fTools::equalZero(aDirection.getX()))
478         {
479             fRotateY = atan2(-aDirection.getZ(), aDirection.getX());
480         }
481 
482         aTransform.rotate(0.0, fRotateY, 0.0);
483         mpLampShaftObject->SetTransform(aTransform);
484 
485         // adapt transformation of selected light
486         E3dObject* pSelectedLight = maLightObjects[sal_Int32(maSelectedLight)];
487 
488         if(pSelectedLight)
489         {
490             aTransform.identity();
491             aTransform.translate(
492                 aDirection.getX() * RADIUS_LAMP_PREVIEW_SIZE,
493                 aDirection.getY() * RADIUS_LAMP_PREVIEW_SIZE,
494                 aDirection.getZ() * RADIUS_LAMP_PREVIEW_SIZE);
495             pSelectedLight->SetTransform(aTransform);
496         }
497     }
498 }
499 
TrySelection(Point aPosPixel)500 void Svx3DLightControl::TrySelection(Point aPosPixel)
501 {
502     if(mpScene)
503     {
504         const Point aPosLogic(PixelToLogic(aPosPixel));
505         const basegfx::B2DPoint aPoint(aPosLogic.X(), aPosLogic.Y());
506         std::vector< const E3dCompoundObject* > aResult;
507         getAllHit3DObjectsSortedFrontToBack(aPoint, *mpScene, aResult);
508 
509         if(!aResult.empty())
510         {
511             // exclude expansion object which will be part of
512             // the hits. It's invisible, but for HitTest, it's included
513             const E3dCompoundObject* pResult = 0;
514 
515             for(sal_uInt32 b(0); !pResult && b < aResult.size(); b++)
516             {
517                 if(aResult[b] && aResult[b] != mpExpansionObject)
518                 {
519                     pResult = aResult[b];
520                 }
521             }
522 
523             if(pResult == mp3DObj)
524             {
525                 if(!mbGeometrySelected)
526                 {
527                     mbGeometrySelected = true;
528                     maSelectedLight = NO_LIGHT_SELECTED;
529                     ConstructLightObjects();
530                     AdaptToSelectedLight();
531                     Invalidate();
532 
533                     if(maSelectionChangeCallback.IsSet())
534                     {
535                         maSelectionChangeCallback.Call(this);
536                     }
537                 }
538             }
539             else
540             {
541                 sal_uInt32 aNewSelectedLight(NO_LIGHT_SELECTED);
542 
543                 for(sal_uInt32 a(0); a < MAX_NUMBER_LIGHTS; a++)
544                 {
545                     if(maLightObjects[a] && maLightObjects[a] == pResult)
546                     {
547                         aNewSelectedLight = a;
548                     }
549                 }
550 
551                 if(aNewSelectedLight != maSelectedLight)
552                 {
553                     SelectLight(aNewSelectedLight);
554 
555                     if(maSelectionChangeCallback.IsSet())
556                     {
557                         maSelectionChangeCallback.Call(this);
558                     }
559                 }
560             }
561         }
562     }
563 }
564 
Paint(const Rectangle & rRect)565 void Svx3DLightControl::Paint(const Rectangle& rRect)
566 {
567     Svx3DPreviewControl::Paint(rRect);
568 }
569 
MouseButtonDown(const MouseEvent & rMEvt)570 void Svx3DLightControl::MouseButtonDown( const MouseEvent& rMEvt )
571 {
572     bool bCallParent(true);
573 
574     // switch state
575     if(rMEvt.IsLeft())
576     {
577         if(IsSelectionValid() || mbGeometrySelected)
578         {
579             mbMouseMoved = false;
580             bCallParent = false;
581             maActionStartPoint = rMEvt.GetPosPixel();
582             StartTracking();
583         }
584         else
585         {
586             // Einfacher Click ohne viel Bewegen, versuche eine
587             // Selektion
588             TrySelection(rMEvt.GetPosPixel());
589             bCallParent = false;
590         }
591     }
592 
593     // call parent
594     if(bCallParent)
595     {
596         Svx3DPreviewControl::MouseButtonDown(rMEvt);
597     }
598 }
599 
Tracking(const TrackingEvent & rTEvt)600 void Svx3DLightControl::Tracking( const TrackingEvent& rTEvt )
601 {
602     if(rTEvt.IsTrackingEnded())
603     {
604         if(rTEvt.IsTrackingCanceled())
605         {
606             if(mbMouseMoved)
607             {
608                 // interrupt tracking
609                 mbMouseMoved = false;
610 
611                 if(mbGeometrySelected)
612                 {
613                     SetRotation(mfSaveActionStartVer, mfSaveActionStartHor, mfSaveActionStartRotZ);
614                 }
615                 else
616                 {
617                     SetPosition(mfSaveActionStartHor, mfSaveActionStartVer);
618                 }
619 
620                 if(maChangeCallback.IsSet())
621                 {
622                     maChangeCallback.Call(this);
623                 }
624             }
625         }
626         else
627         {
628             const MouseEvent& rMEvt = rTEvt.GetMouseEvent();
629 
630             if(mbMouseMoved)
631             {
632                 // was change dinteractively
633             }
634             else
635             {
636                 // simple click without much movement, try selection
637                 TrySelection(rMEvt.GetPosPixel());
638             }
639         }
640     }
641     else
642     {
643         const MouseEvent& rMEvt = rTEvt.GetMouseEvent();
644         Point aDeltaPos = rMEvt.GetPosPixel() - maActionStartPoint;
645 
646         if(!mbMouseMoved)
647         {
648             if(sal_Int32(aDeltaPos.X() * aDeltaPos.X() + aDeltaPos.Y() * aDeltaPos.Y()) > mnInteractionStartDistance)
649             {
650                 if(mbGeometrySelected)
651                 {
652                     GetRotation(mfSaveActionStartVer, mfSaveActionStartHor, mfSaveActionStartRotZ);
653                 }
654                 else
655                 {
656                     // intercation start, save values
657                     GetPosition(mfSaveActionStartHor, mfSaveActionStartVer);
658                 }
659 
660                 mbMouseMoved = true;
661             }
662         }
663 
664         if(mbMouseMoved)
665         {
666             if(mbGeometrySelected)
667             {
668                 double fNewRotX = mfSaveActionStartVer - ((double)aDeltaPos.Y() * F_PI180);
669                 double fNewRotY = mfSaveActionStartHor + ((double)aDeltaPos.X() * F_PI180);
670 
671                 // cut horizontal
672                 while(fNewRotY < 0.0)
673                 {
674                     fNewRotY += F_2PI;
675                 }
676 
677                 while(fNewRotY >= F_2PI)
678                 {
679                     fNewRotY -= F_2PI;
680                 }
681 
682                 // cut vertical
683                 if(fNewRotX < -F_PI2)
684                 {
685                     fNewRotX = -F_PI2;
686                 }
687 
688                 if(fNewRotX > F_PI2)
689                 {
690                     fNewRotX = F_PI2;
691                 }
692 
693                 SetRotation(fNewRotX, fNewRotY, mfSaveActionStartRotZ);
694 
695                 if(maChangeCallback.IsSet())
696                 {
697                     maChangeCallback.Call(this);
698                 }
699             }
700             else
701             {
702                 // interaction in progress
703                 double fNewPosHor = mfSaveActionStartHor + ((double)aDeltaPos.X());
704                 double fNewPosVer = mfSaveActionStartVer - ((double)aDeltaPos.Y());
705 
706                 // cut horizontal
707                 while(fNewPosHor < 0.0)
708                 {
709                     fNewPosHor += 360.0;
710                 }
711 
712                 while(fNewPosHor >= 360.0)
713                 {
714                     fNewPosHor -= 360.0;
715                 }
716 
717                 // cut vertical
718                 if(fNewPosVer < -90.0)
719                 {
720                     fNewPosVer = -90.0;
721                 }
722 
723                 if(fNewPosVer > 90.0)
724                 {
725                     fNewPosVer = 90.0;
726                 }
727 
728                 SetPosition(fNewPosHor, fNewPosVer);
729 
730                 if(maChangeCallback.IsSet())
731                 {
732                     maChangeCallback.Call(this);
733                 }
734             }
735         }
736     }
737 }
738 
Resize()739 void Svx3DLightControl::Resize()
740 {
741     // set size of page
742     const Size aSize(PixelToLogic(GetSizePixel()));
743     mpFmPage->SetSize(aSize);
744 
745     // set position and size of scene
746     mpScene->SetSnapRect(Rectangle(Point(0, 0), aSize));
747 }
748 
SetObjectType(sal_uInt16 nType)749 void Svx3DLightControl::SetObjectType(sal_uInt16 nType)
750 {
751     // call parent
752     Svx3DPreviewControl::SetObjectType(nType);
753 
754     // apply object rotation
755     if(mp3DObj)
756     {
757         basegfx::B3DHomMatrix aObjectRotation;
758         aObjectRotation.rotate(mfRotateX, mfRotateY, mfRotateZ);
759         mp3DObj->SetTransform(aObjectRotation);
760     }
761 }
762 
IsSelectionValid()763 bool Svx3DLightControl::IsSelectionValid()
764 {
765     if((NO_LIGHT_SELECTED != maSelectedLight) && (GetLightOnOff(maSelectedLight)))
766     {
767         return true;
768     }
769 
770     return false;
771 }
772 
GetPosition(double & rHor,double & rVer)773 void Svx3DLightControl::GetPosition(double& rHor, double& rVer)
774 {
775     if(IsSelectionValid())
776     {
777         basegfx::B3DVector aDirection(GetLightDirection(maSelectedLight));
778         aDirection.normalize();
779         rHor = atan2(-aDirection.getX(), -aDirection.getZ()) + F_PI; // 0..2PI
780         rVer = atan2(aDirection.getY(), aDirection.getXZLength()); // -PI2..PI2
781         rHor /= F_PI180; // 0..360.0
782         rVer /= F_PI180; // -90.0..90.0
783     }
784     if(IsGeometrySelected())
785     {
786         rHor = mfRotateY / F_PI180; // 0..360.0
787         rVer = mfRotateX / F_PI180; // -90.0..90.0
788     }
789 }
790 
SetPosition(double fHor,double fVer)791 void Svx3DLightControl::SetPosition(double fHor, double fVer)
792 {
793     if(IsSelectionValid())
794     {
795         // set selected light's direction
796         fHor = (fHor * F_PI180) - F_PI; // -PI..PI
797         fVer *= F_PI180; // -PI2..PI2
798         basegfx::B3DVector aDirection(cos(fVer) * -sin(fHor), sin(fVer), cos(fVer) * -cos(fHor));
799         aDirection.normalize();
800 
801         if(!aDirection.equal(GetLightDirection(maSelectedLight)))
802         {
803             // set changed light direction at SdrScene
804             SfxItemSet aSet(mpModel->GetItemPool());
805 
806             switch(maSelectedLight)
807             {
808                 case 0: aSet.Put(Svx3DLightDirection1Item(aDirection)); break;
809                 case 1: aSet.Put(Svx3DLightDirection2Item(aDirection)); break;
810                 case 2: aSet.Put(Svx3DLightDirection3Item(aDirection)); break;
811                 case 3: aSet.Put(Svx3DLightDirection4Item(aDirection)); break;
812                 case 4: aSet.Put(Svx3DLightDirection5Item(aDirection)); break;
813                 case 5: aSet.Put(Svx3DLightDirection6Item(aDirection)); break;
814                 case 6: aSet.Put(Svx3DLightDirection7Item(aDirection)); break;
815                 default:
816                 case 7: aSet.Put(Svx3DLightDirection8Item(aDirection)); break;
817             }
818 
819             mpScene->SetMergedItemSet(aSet);
820 
821             // correct 3D light's and LampFrame's geometries
822             AdaptToSelectedLight();
823             Invalidate();
824         }
825     }
826     if(IsGeometrySelected())
827     {
828         if(mfRotateX != fVer || mfRotateY != fHor)
829         {
830             mfRotateX = fVer * F_PI180;
831             mfRotateY = fHor * F_PI180;
832 
833             if(mp3DObj)
834             {
835                 basegfx::B3DHomMatrix aObjectRotation;
836                 aObjectRotation.rotate(mfRotateX, mfRotateY, mfRotateZ);
837                 mp3DObj->SetTransform(aObjectRotation);
838 
839                 Invalidate();
840             }
841         }
842     }
843 }
844 
SetRotation(double fRotX,double fRotY,double fRotZ)845 void Svx3DLightControl::SetRotation(double fRotX, double fRotY, double fRotZ)
846 {
847     if(IsGeometrySelected())
848     {
849         if(fRotX != mfRotateX || fRotY != mfRotateY || fRotZ != mfRotateZ)
850         {
851             mfRotateX = fRotX;
852             mfRotateY = fRotY;
853             mfRotateZ = fRotZ;
854 
855             if(mp3DObj)
856             {
857                 basegfx::B3DHomMatrix aObjectRotation;
858                 aObjectRotation.rotate(mfRotateX, mfRotateY, mfRotateZ);
859                 mp3DObj->SetTransform(aObjectRotation);
860 
861                 Invalidate();
862             }
863         }
864     }
865 }
866 
GetRotation(double & rRotX,double & rRotY,double & rRotZ)867 void Svx3DLightControl::GetRotation(double& rRotX, double& rRotY, double& rRotZ)
868 {
869     rRotX = mfRotateX;
870     rRotY = mfRotateY;
871     rRotZ = mfRotateZ;
872 }
873 
Set3DAttributes(const SfxItemSet & rAttr)874 void Svx3DLightControl::Set3DAttributes( const SfxItemSet& rAttr )
875 {
876     // call parent
877     Svx3DPreviewControl::Set3DAttributes(rAttr);
878 
879     if(maSelectedLight != NO_LIGHT_SELECTED && !GetLightOnOff(maSelectedLight))
880     {
881         // selected light is no more active, select new one
882         maSelectedLight = NO_LIGHT_SELECTED;
883     }
884 
885     // local updates
886     ConstructLightObjects();
887     AdaptToSelectedLight();
888     Invalidate();
889 }
890 
SelectLight(sal_uInt32 nLightNumber)891 void Svx3DLightControl::SelectLight(sal_uInt32 nLightNumber)
892 {
893     if(nLightNumber > 7)
894     {
895         nLightNumber = NO_LIGHT_SELECTED;
896     }
897 
898     if(NO_LIGHT_SELECTED != nLightNumber)
899     {
900         if(!GetLightOnOff(nLightNumber))
901         {
902             nLightNumber = NO_LIGHT_SELECTED;
903         }
904     }
905 
906     if(nLightNumber != maSelectedLight)
907     {
908         maSelectedLight = nLightNumber;
909         mbGeometrySelected = false;
910         ConstructLightObjects();
911         AdaptToSelectedLight();
912         Invalidate();
913     }
914 }
915 
GetLightOnOff(sal_uInt32 nNum) const916 bool Svx3DLightControl::GetLightOnOff(sal_uInt32 nNum) const
917 {
918     if(nNum <= 7)
919     {
920         const SfxItemSet aLightItemSet(Get3DAttributes());
921 
922         switch(nNum)
923         {
924             case 0 : return ((const Svx3DLightOnOff1Item&)aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTON_1)).GetValue();
925             case 1 : return ((const Svx3DLightOnOff2Item&)aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTON_2)).GetValue();
926             case 2 : return ((const Svx3DLightOnOff3Item&)aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTON_3)).GetValue();
927             case 3 : return ((const Svx3DLightOnOff4Item&)aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTON_4)).GetValue();
928             case 4 : return ((const Svx3DLightOnOff5Item&)aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTON_5)).GetValue();
929             case 5 : return ((const Svx3DLightOnOff6Item&)aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTON_6)).GetValue();
930             case 6 : return ((const Svx3DLightOnOff7Item&)aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTON_7)).GetValue();
931             case 7 : return ((const Svx3DLightOnOff8Item&)aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTON_8)).GetValue();
932         }
933     }
934 
935     return false;
936 }
937 
GetLightColor(sal_uInt32 nNum) const938 Color Svx3DLightControl::GetLightColor(sal_uInt32 nNum) const
939 {
940     if(nNum <= 7)
941     {
942         const SfxItemSet aLightItemSet(Get3DAttributes());
943 
944         switch(nNum)
945         {
946             case 0 : return ((const Svx3DLightcolor1Item&)aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTCOLOR_1)).GetValue();
947             case 1 : return ((const Svx3DLightcolor2Item&)aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTCOLOR_2)).GetValue();
948             case 2 : return ((const Svx3DLightcolor3Item&)aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTCOLOR_3)).GetValue();
949             case 3 : return ((const Svx3DLightcolor4Item&)aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTCOLOR_4)).GetValue();
950             case 4 : return ((const Svx3DLightcolor5Item&)aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTCOLOR_5)).GetValue();
951             case 5 : return ((const Svx3DLightcolor6Item&)aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTCOLOR_6)).GetValue();
952             case 6 : return ((const Svx3DLightcolor7Item&)aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTCOLOR_7)).GetValue();
953             case 7 : return ((const Svx3DLightcolor8Item&)aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTCOLOR_8)).GetValue();
954         }
955     }
956 
957     return Color(COL_BLACK);
958 }
959 
GetLightDirection(sal_uInt32 nNum) const960 basegfx::B3DVector Svx3DLightControl::GetLightDirection(sal_uInt32 nNum) const
961 {
962     if(nNum <= 7)
963     {
964         const SfxItemSet aLightItemSet(Get3DAttributes());
965 
966         switch(nNum)
967         {
968             case 0 : return ((const Svx3DLightDirection1Item&)aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_1)).GetValue();
969             case 1 : return ((const Svx3DLightDirection2Item&)aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_2)).GetValue();
970             case 2 : return ((const Svx3DLightDirection3Item&)aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_3)).GetValue();
971             case 3 : return ((const Svx3DLightDirection4Item&)aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_4)).GetValue();
972             case 4 : return ((const Svx3DLightDirection5Item&)aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_5)).GetValue();
973             case 5 : return ((const Svx3DLightDirection6Item&)aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_6)).GetValue();
974             case 6 : return ((const Svx3DLightDirection7Item&)aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_7)).GetValue();
975             case 7 : return ((const Svx3DLightDirection8Item&)aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_8)).GetValue();
976         }
977     }
978 
979     return basegfx::B3DVector();
980 }
981 
982 //////////////////////////////////////////////////////////////////////////////
983 
SvxLightCtl3D(Window * pParent,const ResId & rResId)984 SvxLightCtl3D::SvxLightCtl3D( Window* pParent, const ResId& rResId)
985 :   Control(pParent, rResId),
986     maLightControl(this, 0),
987     maHorScroller(this, WB_HORZ | WB_DRAG),
988     maVerScroller(this, WB_VERT | WB_DRAG),
989     maSwitcher(this, 0)
990 {
991     // init members
992     Init();
993 }
994 
SvxLightCtl3D(Window * pParent,WinBits nStyle)995 SvxLightCtl3D::SvxLightCtl3D( Window* pParent, WinBits nStyle )
996 :   Control(pParent, nStyle),
997     maLightControl(this, 0),
998     maHorScroller(this, WB_HORZ | WB_DRAG),
999     maVerScroller(this, WB_VERT | WB_DRAG),
1000     maSwitcher(this, 0)
1001 {
1002     // init members
1003     Init();
1004 }
1005 
Init()1006 void SvxLightCtl3D::Init()
1007 {
1008     // #i58240# set HelpIDs for scrollbars and switcher
1009     maHorScroller.SetHelpId(HID_CTRL3D_HSCROLL);
1010     maVerScroller.SetHelpId(HID_CTRL3D_VSCROLL);
1011     maSwitcher.SetHelpId(HID_CTRL3D_SWITCHER);
1012     maSwitcher.SetAccessibleName(String(SVX_RES(STR_SWITCH)));
1013 
1014     // Light preview
1015     maLightControl.Show();
1016     maLightControl.SetChangeCallback( LINK(this, SvxLightCtl3D, InternalInteractiveChange) );
1017     maLightControl.SetSelectionChangeCallback( LINK(this, SvxLightCtl3D, InternalSelectionChange) );
1018 
1019     // Horiz Scrollbar
1020     maHorScroller.Show();
1021     maHorScroller.SetRange(Range(0, 36000));
1022     maHorScroller.SetLineSize(100);
1023     maHorScroller.SetPageSize(1000);
1024     maHorScroller.SetScrollHdl( LINK(this, SvxLightCtl3D, ScrollBarMove) );
1025 
1026     // Vert Scrollbar
1027     maVerScroller.Show();
1028     maVerScroller.SetRange(Range(0, 18000));
1029     maVerScroller.SetLineSize(100);
1030     maVerScroller.SetPageSize(1000);
1031     maVerScroller.SetScrollHdl( LINK(this, SvxLightCtl3D, ScrollBarMove) );
1032 
1033     // Switch Button
1034     maSwitcher.Show();
1035     maSwitcher.SetClickHdl( LINK(this, SvxLightCtl3D, ButtonPress) );
1036 
1037     // check selection
1038     CheckSelection();
1039 
1040     // new layout
1041     NewLayout();
1042 }
1043 
~SvxLightCtl3D()1044 SvxLightCtl3D::~SvxLightCtl3D()
1045 {
1046 }
1047 
Resize()1048 void SvxLightCtl3D::Resize()
1049 {
1050     // call parent
1051     Control::Resize();
1052 
1053     // new layout
1054     NewLayout();
1055 }
1056 
NewLayout()1057 void SvxLightCtl3D::NewLayout()
1058 {
1059     // Layout members
1060     const Size aSize(GetOutputSizePixel());
1061     const sal_Int32 nScrollSize(maHorScroller.GetSizePixel().Height());
1062 
1063     // Preview control
1064     Point aPoint(0, 0);
1065     Size aDestSize(aSize.Width() - nScrollSize, aSize.Height() - nScrollSize);
1066     maLightControl.SetPosSizePixel(aPoint, aDestSize);
1067 
1068     // hor scrollbar
1069     aPoint.Y() = aSize.Height() - nScrollSize;
1070     aDestSize.Height() = nScrollSize;
1071     maHorScroller.SetPosSizePixel(aPoint, aDestSize);
1072 
1073     // vert scrollbar
1074     aPoint.X() = aSize.Width() - nScrollSize;
1075     aPoint.Y() = 0;
1076     aDestSize.Width() = nScrollSize;
1077     aDestSize.Height() = aSize.Height() - nScrollSize;
1078     maVerScroller.SetPosSizePixel(aPoint, aDestSize);
1079 
1080     // button
1081     aPoint.Y() = aSize.Height() - nScrollSize;
1082     aDestSize.Height() = nScrollSize;
1083     maSwitcher.SetPosSizePixel(aPoint, aDestSize);
1084 }
1085 
CheckSelection()1086 void SvxLightCtl3D::CheckSelection()
1087 {
1088     const bool bSelectionValid(maLightControl.IsSelectionValid() || maLightControl.IsGeometrySelected());
1089     maHorScroller.Enable(bSelectionValid);
1090     maVerScroller.Enable(bSelectionValid);
1091 
1092     if(bSelectionValid)
1093     {
1094         double fHor, fVer;
1095         maLightControl.GetPosition(fHor, fVer);
1096         maHorScroller.SetThumbPos( sal_Int32(fHor * 100.0) );
1097         maVerScroller.SetThumbPos( 18000 - sal_Int32((fVer + 90.0) * 100.0) );
1098     }
1099 }
1100 
move(double fDeltaHor,double fDeltaVer)1101 void SvxLightCtl3D::move( double fDeltaHor, double fDeltaVer )
1102 {
1103     double fHor, fVer;
1104 
1105     maLightControl.GetPosition(fHor, fVer);
1106     fHor += fDeltaHor;
1107     fVer += fDeltaVer;
1108 
1109     if( fVer > 90.0 )
1110         return;
1111 
1112     if ( fVer < -90.0 )
1113         return;
1114 
1115     maLightControl.SetPosition(fHor, fVer);
1116     maHorScroller.SetThumbPos( sal_Int32(fHor * 100.0) );
1117     maVerScroller.SetThumbPos( 18000 - sal_Int32((fVer + 90.0) * 100.0) );
1118 
1119     if(maUserInteractiveChangeCallback.IsSet())
1120     {
1121         maUserInteractiveChangeCallback.Call(this);
1122     }
1123 }
1124 
KeyInput(const KeyEvent & rKEvt)1125 void SvxLightCtl3D::KeyInput( const KeyEvent& rKEvt )
1126 {
1127     const KeyCode aCode(rKEvt.GetKeyCode());
1128 
1129     if( aCode.GetModifier() )
1130     {
1131         Control::KeyInput( rKEvt );
1132         return;
1133     }
1134 
1135     switch ( aCode.GetCode() )
1136     {
1137         case KEY_SPACE:
1138         {
1139             break;
1140         }
1141         case KEY_LEFT:
1142         {
1143             move(  -4.0,  0.0 ); // #i58242# changed move direction in X
1144             break;
1145         }
1146         case KEY_RIGHT:
1147         {
1148             move( 4.0,  0.0 ); // #i58242# changed move direction in X
1149             break;
1150         }
1151         case KEY_UP:
1152         {
1153             move(  0.0,  4.0 );
1154             break;
1155         }
1156         case KEY_DOWN:
1157         {
1158             move(  0.0, -4.0 );
1159             break;
1160         }
1161         case KEY_PAGEUP:
1162         {
1163             sal_Int32 nLight(maLightControl.GetSelectedLight() - 1);
1164 
1165             while((nLight >= 0) && !maLightControl.GetLightOnOff(nLight))
1166             {
1167                 nLight--;
1168             }
1169 
1170             if(nLight < 0)
1171             {
1172                 nLight = 7;
1173 
1174                 while((nLight >= 0) && !maLightControl.GetLightOnOff(nLight))
1175                 {
1176                     nLight--;
1177                 }
1178             }
1179 
1180             if(nLight >= 0)
1181             {
1182                 maLightControl.SelectLight(nLight);
1183                 CheckSelection();
1184 
1185                 if(maUserSelectionChangeCallback.IsSet())
1186                 {
1187                     maUserSelectionChangeCallback.Call(this);
1188                 }
1189             }
1190 
1191             break;
1192         }
1193         case KEY_PAGEDOWN:
1194         {
1195             sal_Int32 nLight(maLightControl.GetSelectedLight() - 1);
1196 
1197             while(nLight <= 7 && !maLightControl.GetLightOnOff(nLight))
1198             {
1199                 nLight++;
1200             }
1201 
1202             if(nLight > 7)
1203             {
1204                 nLight = 0;
1205 
1206                 while(nLight <= 7 && !maLightControl.GetLightOnOff(nLight))
1207                 {
1208                     nLight++;
1209                 }
1210             }
1211 
1212             if(nLight <= 7)
1213             {
1214                 maLightControl.SelectLight(nLight);
1215                 CheckSelection();
1216 
1217                 if(maUserSelectionChangeCallback.IsSet())
1218                 {
1219                     maUserSelectionChangeCallback.Call(this);
1220                 }
1221             }
1222 
1223             break;
1224         }
1225         default:
1226         {
1227             Control::KeyInput( rKEvt );
1228             break;
1229         }
1230     }
1231 }
1232 
GetFocus()1233 void SvxLightCtl3D::GetFocus()
1234 {
1235     Control::GetFocus();
1236 
1237     if(HasFocus() && IsEnabled())
1238     {
1239         CheckSelection();
1240 
1241         Size aFocusSize = maLightControl.GetOutputSizePixel();
1242 
1243         aFocusSize.Width() -= 4;
1244         aFocusSize.Height() -= 4;
1245 
1246         Rectangle aFocusRect( Point( 2, 2 ), aFocusSize );
1247 
1248         aFocusRect = maLightControl.PixelToLogic( aFocusRect );
1249 
1250         maLightControl.ShowFocus( aFocusRect );
1251     }
1252 }
1253 
LoseFocus()1254 void SvxLightCtl3D::LoseFocus()
1255 {
1256     Control::LoseFocus();
1257 
1258     maLightControl.HideFocus();
1259 }
1260 
IMPL_LINK(SvxLightCtl3D,ScrollBarMove,void *,EMPTYARG)1261 IMPL_LINK( SvxLightCtl3D, ScrollBarMove, void*, EMPTYARG)
1262 {
1263     const sal_Int32 nHor(maHorScroller.GetThumbPos());
1264     const sal_Int32 nVer(maVerScroller.GetThumbPos());
1265 
1266     maLightControl.SetPosition(
1267         ((double)nHor) / 100.0,
1268         ((double)((18000 - nVer) - 9000)) / 100.0);
1269 
1270     if(maUserInteractiveChangeCallback.IsSet())
1271     {
1272         maUserInteractiveChangeCallback.Call(this);
1273     }
1274 
1275     return 0;
1276 }
1277 
IMPL_LINK(SvxLightCtl3D,ButtonPress,void *,EMPTYARG)1278 IMPL_LINK( SvxLightCtl3D, ButtonPress, void*, EMPTYARG)
1279 {
1280     if(PREVIEW_OBJECTTYPE_SPHERE == GetSvx3DLightControl().GetObjectType())
1281     {
1282         GetSvx3DLightControl().SetObjectType(PREVIEW_OBJECTTYPE_CUBE);
1283     }
1284     else
1285     {
1286         GetSvx3DLightControl().SetObjectType(PREVIEW_OBJECTTYPE_SPHERE);
1287     }
1288 
1289     return 0;
1290 }
1291 
IMPL_LINK(SvxLightCtl3D,InternalInteractiveChange,void *,EMPTYARG)1292 IMPL_LINK( SvxLightCtl3D, InternalInteractiveChange, void*, EMPTYARG)
1293 {
1294     double fHor, fVer;
1295 
1296     maLightControl.GetPosition(fHor, fVer);
1297     maHorScroller.SetThumbPos( sal_Int32(fHor * 100.0) );
1298     maVerScroller.SetThumbPos( 18000 - sal_Int32((fVer + 90.0) * 100.0) );
1299 
1300     if(maUserInteractiveChangeCallback.IsSet())
1301     {
1302         maUserInteractiveChangeCallback.Call(this);
1303     }
1304 
1305     return 0;
1306 }
1307 
IMPL_LINK(SvxLightCtl3D,InternalSelectionChange,void *,EMPTYARG)1308 IMPL_LINK( SvxLightCtl3D, InternalSelectionChange, void*, EMPTYARG)
1309 {
1310     CheckSelection();
1311 
1312     if(maUserSelectionChangeCallback.IsSet())
1313     {
1314         maUserSelectionChangeCallback.Call(this);
1315     }
1316 
1317     return 0;
1318 }
1319 
1320 //////////////////////////////////////////////////////////////////////////////
1321 // eof
1322