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