Coverage Report

Created: 2026-05-16 09:25

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