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