xref: /trunk/main/svx/source/dialog/dlgctl3d.cxx (revision f6e50924)
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