1169 lines
35 KiB
C++
1169 lines
35 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
|
/*
|
|
* This file is part of the LibreOffice project.
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*
|
|
* This file incorporates work covered by the following license notice:
|
|
*
|
|
* Licensed to the Apache Software Foundation (ASF) under one or more
|
|
* contributor license agreements. See the NOTICE file distributed
|
|
* with this work for additional information regarding copyright
|
|
* ownership. The ASF licenses this file to you under the Apache
|
|
* License, Version 2.0 (the "License"); you may not use this file
|
|
* except in compliance with the License. You may obtain a copy of
|
|
* the License at http://www.apache.org/licenses/LICENSE-2.0 .
|
|
*/
|
|
|
|
|
|
#include <svx/dlgctl3d.hxx>
|
|
#include <svx/strings.hrc>
|
|
#include <svx/view3d.hxx>
|
|
#include <svx/fmmodel.hxx>
|
|
#include <svl/itempool.hxx>
|
|
#include <svx/fmpage.hxx>
|
|
#include <svx/sphere3d.hxx>
|
|
#include <svx/cube3d.hxx>
|
|
#include <svx/scene3d.hxx>
|
|
#include <vcl/svapp.hxx>
|
|
#include <svx/helperhittest3d.hxx>
|
|
#include <basegfx/polygon/b2dpolygontools.hxx>
|
|
#include <polygn3d.hxx>
|
|
#include <svx/xfillit0.hxx>
|
|
#include <svx/xflclit.hxx>
|
|
#include <svx/xlineit0.hxx>
|
|
#include <svx/xlnclit.hxx>
|
|
#include <svx/xlnwtit.hxx>
|
|
#include <helpids.h>
|
|
#include <svx/dialmgr.hxx>
|
|
#include <tools/helpers.hxx>
|
|
#include <vcl/settings.hxx>
|
|
|
|
using namespace com::sun::star;
|
|
|
|
Svx3DPreviewControl::Svx3DPreviewControl()
|
|
: mnObjectType(SvxPreviewObjectType::SPHERE)
|
|
{
|
|
}
|
|
|
|
void Svx3DPreviewControl::SetDrawingArea(weld::DrawingArea* pDrawingArea)
|
|
{
|
|
Size aSize(pDrawingArea->get_ref_device().LogicToPixel(Size(80, 100), MapMode(MapUnit::MapAppFont)));
|
|
pDrawingArea->set_size_request(aSize.Width(), aSize.Height());
|
|
CustomWidgetController::SetDrawingArea(pDrawingArea);
|
|
SetOutputSizePixel(aSize);
|
|
|
|
Construct();
|
|
}
|
|
|
|
void Svx3DPreviewControl::ClearPageView()
|
|
{
|
|
mp3DView->ClearPageView();
|
|
}
|
|
|
|
Svx3DPreviewControl::~Svx3DPreviewControl()
|
|
{
|
|
mp3DObj.clear();
|
|
mxFmPage.clear();
|
|
mpScene.clear();
|
|
mp3DView.reset();
|
|
mpModel.reset();
|
|
}
|
|
|
|
void Svx3DPreviewControl::Construct()
|
|
{
|
|
// Do never mirror the preview window. This explicitly includes right
|
|
// to left writing environments.
|
|
EnableRTL (false);
|
|
OutputDevice& rDevice = GetDrawingArea()->get_ref_device();
|
|
rDevice.SetMapMode(MapMode(MapUnit::Map100thMM));
|
|
|
|
// Model
|
|
mpModel.reset(new FmFormModel());
|
|
|
|
// Page
|
|
mxFmPage = new FmFormPage( *mpModel );
|
|
mpModel->InsertPage( mxFmPage.get(), 0 );
|
|
|
|
// 3D View
|
|
mp3DView.reset(new E3dView(*mpModel, &rDevice));
|
|
mp3DView->SetBufferedOutputAllowed(true);
|
|
mp3DView->SetBufferedOverlayAllowed(true);
|
|
|
|
// 3D Scene
|
|
mpScene = new E3dScene(*mpModel);
|
|
|
|
// initially create object
|
|
SetObjectType(SvxPreviewObjectType::SPHERE);
|
|
|
|
// camera and perspective
|
|
Camera3D rCamera = mpScene->GetCamera();
|
|
const basegfx::B3DRange& rVolume = mpScene->GetBoundVolume();
|
|
double fW = rVolume.getWidth();
|
|
double fH = rVolume.getHeight();
|
|
double fCamZ = rVolume.getMaxZ() + ((fW + fH) / 2.0);
|
|
|
|
rCamera.SetAutoAdjustProjection(false);
|
|
rCamera.SetViewWindow(- fW / 2, - fH / 2, fW, fH);
|
|
basegfx::B3DPoint aLookAt;
|
|
double fDefaultCamPosZ = mp3DView->GetDefaultCamPosZ();
|
|
basegfx::B3DPoint aCamPos(0.0, 0.0, fCamZ < fDefaultCamPosZ ? fDefaultCamPosZ : fCamZ);
|
|
rCamera.SetPosAndLookAt(aCamPos, aLookAt);
|
|
double fDefaultCamFocal = mp3DView->GetDefaultCamFocal();
|
|
rCamera.SetFocalLength(fDefaultCamFocal);
|
|
|
|
mpScene->SetCamera( rCamera );
|
|
mxFmPage->InsertObject( mpScene.get() );
|
|
|
|
basegfx::B3DHomMatrix aRotation;
|
|
aRotation.rotate(basegfx::deg2rad( 25 ), 0.0, 0.0);
|
|
aRotation.rotate(0.0, basegfx::deg2rad( 40 ), 0.0);
|
|
mpScene->SetTransform(aRotation * mpScene->GetTransform());
|
|
|
|
// invalidate SnapRects of objects
|
|
mpScene->SetBoundAndSnapRectsDirty();
|
|
|
|
SfxItemSetFixed<XATTR_LINESTYLE, XATTR_LINESTYLE,
|
|
XATTR_FILL_FIRST, XATTR_FILLBITMAP> aSet( mpModel->GetItemPool() );
|
|
aSet.Put( XLineStyleItem( drawing::LineStyle_NONE ) );
|
|
aSet.Put( XFillStyleItem( drawing::FillStyle_SOLID ) );
|
|
aSet.Put( XFillColorItem( u""_ustr, COL_WHITE ) );
|
|
|
|
mpScene->SetMergedItemSet(aSet);
|
|
|
|
// PageView
|
|
SdrPageView* pPageView = mp3DView->ShowSdrPage( mxFmPage.get() );
|
|
mp3DView->hideMarkHandles();
|
|
|
|
// mark scene
|
|
mp3DView->MarkObj( mpScene.get(), pPageView );
|
|
}
|
|
|
|
void Svx3DPreviewControl::Resize()
|
|
{
|
|
// size of page
|
|
Size aSize(GetOutputSizePixel());
|
|
aSize = GetDrawingArea()->get_ref_device().PixelToLogic(aSize);
|
|
mxFmPage->SetSize(aSize);
|
|
|
|
// set size
|
|
Size aObjSize( aSize.Width()*5/6, aSize.Height()*5/6 );
|
|
Point aObjPoint( (aSize.Width() - aObjSize.Width()) / 2,
|
|
(aSize.Height() - aObjSize.Height()) / 2);
|
|
tools::Rectangle aRect( aObjPoint, aObjSize);
|
|
mpScene->SetSnapRect( aRect );
|
|
}
|
|
|
|
void Svx3DPreviewControl::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect)
|
|
{
|
|
mp3DView->CompleteRedraw(&rRenderContext, vcl::Region(rRect));
|
|
}
|
|
|
|
bool Svx3DPreviewControl::MouseButtonDown(const MouseEvent& rMEvt)
|
|
{
|
|
if (rMEvt.IsShift() && rMEvt.IsMod1())
|
|
{
|
|
if(SvxPreviewObjectType::SPHERE == GetObjectType())
|
|
{
|
|
SetObjectType(SvxPreviewObjectType::CUBE);
|
|
}
|
|
else
|
|
{
|
|
SetObjectType(SvxPreviewObjectType::SPHERE);
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
void Svx3DPreviewControl::SetObjectType(SvxPreviewObjectType nType)
|
|
{
|
|
if(mnObjectType == nType && mp3DObj)
|
|
return;
|
|
|
|
SfxItemSetFixed<SDRATTR_START, SDRATTR_END> aSet(mpModel->GetItemPool());
|
|
mnObjectType = nType;
|
|
|
|
if( mp3DObj )
|
|
{
|
|
aSet.Put(mp3DObj->GetMergedItemSet());
|
|
mpScene->RemoveObject( mp3DObj->GetOrdNum() );
|
|
mp3DObj.clear();
|
|
}
|
|
|
|
switch( nType )
|
|
{
|
|
case SvxPreviewObjectType::SPHERE:
|
|
{
|
|
mp3DObj = new E3dSphereObj(
|
|
*mpModel,
|
|
mp3DView->Get3DDefaultAttributes(),
|
|
basegfx::B3DPoint( 0, 0, 0 ),
|
|
basegfx::B3DVector( 5000, 5000, 5000 ));
|
|
}
|
|
break;
|
|
|
|
case SvxPreviewObjectType::CUBE:
|
|
{
|
|
mp3DObj = new E3dCubeObj(
|
|
*mpModel,
|
|
mp3DView->Get3DDefaultAttributes(),
|
|
basegfx::B3DPoint( -2500, -2500, -2500 ),
|
|
basegfx::B3DVector( 5000, 5000, 5000 ));
|
|
}
|
|
break;
|
|
}
|
|
|
|
if (mp3DObj)
|
|
{
|
|
mpScene->InsertObject( mp3DObj.get() );
|
|
mp3DObj->SetMergedItemSet(aSet);
|
|
}
|
|
|
|
Invalidate();
|
|
}
|
|
|
|
SfxItemSet const & Svx3DPreviewControl::Get3DAttributes() const
|
|
{
|
|
return mp3DObj->GetMergedItemSet();
|
|
}
|
|
|
|
void Svx3DPreviewControl::Set3DAttributes( const SfxItemSet& rAttr )
|
|
{
|
|
mp3DObj->SetMergedItemSet(rAttr, true);
|
|
Resize();
|
|
Invalidate();
|
|
}
|
|
|
|
#define RADIUS_LAMP_PREVIEW_SIZE (4500.0)
|
|
#define RADIUS_LAMP_SMALL (600.0)
|
|
#define RADIUS_LAMP_BIG (1000.0)
|
|
#define NO_LIGHT_SELECTED (0xffffffff)
|
|
#define MAX_NUMBER_LIGHTS (8)
|
|
|
|
const sal_Int32 g_nInteractionStartDistance = 5 * 5 * 2;
|
|
|
|
Svx3DLightControl::Svx3DLightControl()
|
|
: maSelectedLight(NO_LIGHT_SELECTED),
|
|
maLightObjects(MAX_NUMBER_LIGHTS, nullptr),
|
|
mfRotateX(-20.0),
|
|
mfRotateY(45.0),
|
|
mfRotateZ(0.0),
|
|
mfSaveActionStartHor(0.0),
|
|
mfSaveActionStartVer(0.0),
|
|
mfSaveActionStartRotZ(0.0),
|
|
mbMouseMoved(false),
|
|
mbMouseCaptured(false),
|
|
mbGeometrySelected(false)
|
|
{
|
|
}
|
|
|
|
void Svx3DLightControl::SetDrawingArea(weld::DrawingArea* pDrawingArea)
|
|
{
|
|
Svx3DPreviewControl::SetDrawingArea(pDrawingArea);
|
|
Construct2();
|
|
}
|
|
|
|
void Svx3DLightControl::Construct2()
|
|
{
|
|
{
|
|
// hide all page stuff, use control background (normally gray)
|
|
const Color aDialogColor(Application::GetSettings().GetStyleSettings().GetDialogColor());
|
|
mp3DView->SetPageVisible(false);
|
|
mp3DView->SetApplicationBackgroundColor(aDialogColor);
|
|
mp3DView->SetApplicationDocumentColor(aDialogColor);
|
|
}
|
|
|
|
{
|
|
// create invisible expansion object
|
|
const double fMaxExpansion(RADIUS_LAMP_BIG + RADIUS_LAMP_PREVIEW_SIZE);
|
|
mpExpansionObject = new E3dCubeObj(
|
|
*mpModel,
|
|
mp3DView->Get3DDefaultAttributes(),
|
|
basegfx::B3DPoint(-fMaxExpansion, -fMaxExpansion, -fMaxExpansion),
|
|
basegfx::B3DVector(2.0 * fMaxExpansion, 2.0 * fMaxExpansion, 2.0 * fMaxExpansion));
|
|
mpScene->InsertObject( mpExpansionObject.get() );
|
|
SfxItemSet aSet(mpModel->GetItemPool());
|
|
aSet.Put( XLineStyleItem( drawing::LineStyle_NONE ) );
|
|
aSet.Put( XFillStyleItem( drawing::FillStyle_NONE ) );
|
|
mpExpansionObject->SetMergedItemSet(aSet);
|
|
}
|
|
|
|
{
|
|
// create lamp control object (Yellow lined object)
|
|
// base circle
|
|
const basegfx::B2DPolygon a2DCircle(basegfx::utils::createPolygonFromCircle(basegfx::B2DPoint(0.0, 0.0), RADIUS_LAMP_PREVIEW_SIZE));
|
|
basegfx::B3DPolygon a3DCircle(basegfx::utils::createB3DPolygonFromB2DPolygon(a2DCircle));
|
|
basegfx::B3DHomMatrix aTransform;
|
|
|
|
aTransform.rotate(M_PI_2, 0.0, 0.0);
|
|
aTransform.translate(0.0, -RADIUS_LAMP_PREVIEW_SIZE, 0.0);
|
|
a3DCircle.transform(aTransform);
|
|
|
|
// create object for it
|
|
mpLampBottomObject = new E3dPolygonObj(
|
|
*mpModel,
|
|
basegfx::B3DPolyPolygon(a3DCircle));
|
|
mpScene->InsertObject( mpLampBottomObject.get() );
|
|
|
|
// half circle with stand
|
|
basegfx::B2DPolygon a2DHalfCircle;
|
|
a2DHalfCircle.append(basegfx::B2DPoint(RADIUS_LAMP_PREVIEW_SIZE, 0.0));
|
|
a2DHalfCircle.append(basegfx::B2DPoint(RADIUS_LAMP_PREVIEW_SIZE, -RADIUS_LAMP_PREVIEW_SIZE));
|
|
a2DHalfCircle.append(basegfx::utils::createPolygonFromEllipseSegment(
|
|
basegfx::B2DPoint(0.0, 0.0), RADIUS_LAMP_PREVIEW_SIZE, RADIUS_LAMP_PREVIEW_SIZE, 2 * M_PI - M_PI_2, M_PI_2));
|
|
basegfx::B3DPolygon a3DHalfCircle(basegfx::utils::createB3DPolygonFromB2DPolygon(a2DHalfCircle));
|
|
|
|
// create object for it
|
|
mpLampShaftObject = new E3dPolygonObj(
|
|
*mpModel,
|
|
basegfx::B3DPolyPolygon(a3DHalfCircle));
|
|
mpScene->InsertObject( mpLampShaftObject.get() );
|
|
|
|
// initially invisible
|
|
SfxItemSet aSet(mpModel->GetItemPool());
|
|
aSet.Put( XLineStyleItem( drawing::LineStyle_NONE ) );
|
|
aSet.Put( XFillStyleItem( drawing::FillStyle_NONE ) );
|
|
|
|
mpLampBottomObject->SetMergedItemSet(aSet);
|
|
mpLampShaftObject->SetMergedItemSet(aSet);
|
|
}
|
|
|
|
{
|
|
// change camera settings
|
|
Camera3D rCamera = mpScene->GetCamera();
|
|
const basegfx::B3DRange& rVolume = mpScene->GetBoundVolume();
|
|
double fW = rVolume.getWidth();
|
|
double fH = rVolume.getHeight();
|
|
double fCamZ = rVolume.getMaxZ() + ((fW + fH) / 2.0);
|
|
|
|
rCamera.SetAutoAdjustProjection(false);
|
|
rCamera.SetViewWindow(- fW / 2, - fH / 2, fW, fH);
|
|
basegfx::B3DPoint aLookAt;
|
|
double fDefaultCamPosZ = mp3DView->GetDefaultCamPosZ();
|
|
basegfx::B3DPoint aCamPos(0.0, 0.0, fCamZ < fDefaultCamPosZ ? fDefaultCamPosZ : fCamZ);
|
|
rCamera.SetPosAndLookAt(aCamPos, aLookAt);
|
|
double fDefaultCamFocal = mp3DView->GetDefaultCamFocal();
|
|
rCamera.SetFocalLength(fDefaultCamFocal);
|
|
|
|
mpScene->SetCamera( rCamera );
|
|
|
|
basegfx::B3DHomMatrix aNeutral;
|
|
mpScene->SetTransform(aNeutral);
|
|
}
|
|
|
|
// invalidate SnapRects of objects
|
|
mpScene->SetBoundAndSnapRectsDirty();
|
|
}
|
|
|
|
void Svx3DLightControl::ConstructLightObjects()
|
|
{
|
|
for(sal_uInt32 a(0); a < MAX_NUMBER_LIGHTS; a++)
|
|
{
|
|
// get rid of possible existing light object
|
|
if(maLightObjects[a])
|
|
{
|
|
mpScene->RemoveObject(maLightObjects[a]->GetOrdNum());
|
|
maLightObjects[a] = nullptr;
|
|
}
|
|
|
|
if(GetLightOnOff(a))
|
|
{
|
|
const bool bIsSelectedLight(a == maSelectedLight);
|
|
basegfx::B3DVector aDirection(GetLightDirection(a));
|
|
aDirection.normalize();
|
|
aDirection *= RADIUS_LAMP_PREVIEW_SIZE;
|
|
|
|
const double fLampSize(bIsSelectedLight ? RADIUS_LAMP_BIG : RADIUS_LAMP_SMALL);
|
|
rtl::Reference<E3dObject> pNewLight = new E3dSphereObj(
|
|
*mpModel,
|
|
mp3DView->Get3DDefaultAttributes(),
|
|
basegfx::B3DPoint( 0, 0, 0 ),
|
|
basegfx::B3DVector( fLampSize, fLampSize, fLampSize));
|
|
mpScene->InsertObject(pNewLight.get());
|
|
|
|
basegfx::B3DHomMatrix aTransform;
|
|
aTransform.translate(aDirection.getX(), aDirection.getY(), aDirection.getZ());
|
|
pNewLight->SetTransform(aTransform);
|
|
|
|
SfxItemSet aSet(mpModel->GetItemPool());
|
|
aSet.Put( XLineStyleItem( drawing::LineStyle_NONE ) );
|
|
aSet.Put( XFillStyleItem( drawing::FillStyle_SOLID ) );
|
|
aSet.Put( XFillColorItem(OUString(), GetLightColor(a)));
|
|
pNewLight->SetMergedItemSet(aSet);
|
|
|
|
maLightObjects[a] = pNewLight.get();
|
|
}
|
|
}
|
|
}
|
|
|
|
void Svx3DLightControl::AdaptToSelectedLight()
|
|
{
|
|
if(NO_LIGHT_SELECTED == maSelectedLight)
|
|
{
|
|
// make mpLampBottomObject/mpLampShaftObject invisible
|
|
SfxItemSet aSet(mpModel->GetItemPool());
|
|
aSet.Put( XLineStyleItem( drawing::LineStyle_NONE ) );
|
|
aSet.Put( XFillStyleItem( drawing::FillStyle_NONE ) );
|
|
mpLampBottomObject->SetMergedItemSet(aSet);
|
|
mpLampShaftObject->SetMergedItemSet(aSet);
|
|
}
|
|
else
|
|
{
|
|
basegfx::B3DVector aDirection(GetLightDirection(maSelectedLight));
|
|
aDirection.normalize();
|
|
|
|
// make mpLampBottomObject/mpLampShaftObject visible (yellow hairline)
|
|
SfxItemSet aSet(mpModel->GetItemPool());
|
|
aSet.Put( XLineStyleItem( drawing::LineStyle_SOLID ) );
|
|
aSet.Put( XLineColorItem(OUString(), COL_YELLOW));
|
|
aSet.Put( XLineWidthItem(0));
|
|
aSet.Put( XFillStyleItem( drawing::FillStyle_NONE ) );
|
|
mpLampBottomObject->SetMergedItemSet(aSet);
|
|
mpLampShaftObject->SetMergedItemSet(aSet);
|
|
|
|
// adapt transformation of mpLampShaftObject
|
|
basegfx::B3DHomMatrix aTransform;
|
|
double fRotateY(0.0);
|
|
|
|
if(!basegfx::fTools::equalZero(aDirection.getZ()) || !basegfx::fTools::equalZero(aDirection.getX()))
|
|
{
|
|
fRotateY = atan2(-aDirection.getZ(), aDirection.getX());
|
|
}
|
|
|
|
aTransform.rotate(0.0, fRotateY, 0.0);
|
|
mpLampShaftObject->SetTransform(aTransform);
|
|
|
|
// adapt transformation of selected light
|
|
E3dObject* pSelectedLight = maLightObjects[sal_Int32(maSelectedLight)];
|
|
|
|
if(pSelectedLight)
|
|
{
|
|
aTransform.identity();
|
|
aTransform.translate(
|
|
aDirection.getX() * RADIUS_LAMP_PREVIEW_SIZE,
|
|
aDirection.getY() * RADIUS_LAMP_PREVIEW_SIZE,
|
|
aDirection.getZ() * RADIUS_LAMP_PREVIEW_SIZE);
|
|
pSelectedLight->SetTransform(aTransform);
|
|
}
|
|
}
|
|
}
|
|
|
|
void Svx3DLightControl::TrySelection(Point aPosPixel)
|
|
{
|
|
if(!mpScene)
|
|
return;
|
|
|
|
const Point aPosLogic(GetDrawingArea()->get_ref_device().PixelToLogic(aPosPixel));
|
|
const basegfx::B2DPoint aPoint(aPosLogic.X(), aPosLogic.Y());
|
|
std::vector< const E3dCompoundObject* > aResult;
|
|
getAllHit3DObjectsSortedFrontToBack(aPoint, *mpScene, aResult);
|
|
|
|
if(aResult.empty())
|
|
return;
|
|
|
|
// exclude expansion object which will be part of
|
|
// the hits. It's invisible, but for HitTest, it's included
|
|
const E3dCompoundObject* pResult = nullptr;
|
|
|
|
for(auto const & b: aResult)
|
|
{
|
|
if(b && b != mpExpansionObject.get())
|
|
{
|
|
pResult = b;
|
|
break;
|
|
}
|
|
}
|
|
|
|
if(pResult == mp3DObj.get())
|
|
{
|
|
if(!mbGeometrySelected)
|
|
{
|
|
mbGeometrySelected = true;
|
|
maSelectedLight = NO_LIGHT_SELECTED;
|
|
ConstructLightObjects();
|
|
AdaptToSelectedLight();
|
|
Invalidate();
|
|
|
|
if(maSelectionChangeCallback.IsSet())
|
|
{
|
|
maSelectionChangeCallback.Call(this);
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
sal_uInt32 aNewSelectedLight(NO_LIGHT_SELECTED);
|
|
|
|
for(sal_uInt32 a(0); a < MAX_NUMBER_LIGHTS; a++)
|
|
{
|
|
if(maLightObjects[a] && maLightObjects[a] == pResult)
|
|
{
|
|
aNewSelectedLight = a;
|
|
}
|
|
}
|
|
|
|
if(aNewSelectedLight != maSelectedLight)
|
|
{
|
|
SelectLight(aNewSelectedLight);
|
|
|
|
if(maSelectionChangeCallback.IsSet())
|
|
{
|
|
maSelectionChangeCallback.Call(this);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void Svx3DLightControl::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle& rRect)
|
|
{
|
|
Svx3DPreviewControl::Paint(rRenderContext, rRect);
|
|
}
|
|
|
|
tools::Rectangle Svx3DLightControl::GetFocusRect()
|
|
{
|
|
if (!HasFocus())
|
|
return tools::Rectangle();
|
|
Size aFocusSize = GetOutputSizePixel();
|
|
aFocusSize.AdjustWidth( -4 );
|
|
aFocusSize.AdjustHeight( -4 );
|
|
return tools::Rectangle(Point(2, 2), aFocusSize);
|
|
}
|
|
|
|
bool Svx3DLightControl::MouseButtonDown( const MouseEvent& rMEvt )
|
|
{
|
|
bool bCallParent(true);
|
|
|
|
// switch state
|
|
if(rMEvt.IsLeft())
|
|
{
|
|
if(IsSelectionValid() || mbGeometrySelected)
|
|
{
|
|
mbMouseMoved = false;
|
|
bCallParent = false;
|
|
maActionStartPoint = rMEvt.GetPosPixel();
|
|
CaptureMouse();
|
|
mbMouseCaptured = true;
|
|
}
|
|
else
|
|
{
|
|
// Single click without moving much trying to do a selection
|
|
TrySelection(rMEvt.GetPosPixel());
|
|
bCallParent = false;
|
|
}
|
|
}
|
|
|
|
// call parent
|
|
if (bCallParent)
|
|
return Svx3DPreviewControl::MouseButtonDown(rMEvt);
|
|
return true;
|
|
}
|
|
|
|
bool Svx3DLightControl::MouseMove(const MouseEvent& rMEvt)
|
|
{
|
|
if (!mbMouseCaptured)
|
|
return false;
|
|
|
|
Point aDeltaPos = rMEvt.GetPosPixel() - maActionStartPoint;
|
|
|
|
if(!mbMouseMoved)
|
|
{
|
|
if(sal_Int32(aDeltaPos.X() * aDeltaPos.X() + aDeltaPos.Y() * aDeltaPos.Y()) > g_nInteractionStartDistance)
|
|
{
|
|
if(mbGeometrySelected)
|
|
{
|
|
GetRotation(mfSaveActionStartVer, mfSaveActionStartHor, mfSaveActionStartRotZ);
|
|
}
|
|
else
|
|
{
|
|
// interaction start, save values
|
|
GetPosition(mfSaveActionStartHor, mfSaveActionStartVer);
|
|
}
|
|
|
|
mbMouseMoved = true;
|
|
}
|
|
}
|
|
|
|
if(mbMouseMoved)
|
|
{
|
|
if(mbGeometrySelected)
|
|
{
|
|
double fNewRotX = mfSaveActionStartVer - basegfx::deg2rad(aDeltaPos.Y());
|
|
double fNewRotY = mfSaveActionStartHor + basegfx::deg2rad(aDeltaPos.X());
|
|
|
|
// cut horizontal
|
|
while(fNewRotY < 0.0)
|
|
{
|
|
fNewRotY += 2 * M_PI;
|
|
}
|
|
|
|
while(fNewRotY >= 2 * M_PI)
|
|
{
|
|
fNewRotY -= 2 * M_PI;
|
|
}
|
|
|
|
// cut vertical
|
|
if(fNewRotX < -M_PI_2)
|
|
{
|
|
fNewRotX = -M_PI_2;
|
|
}
|
|
|
|
if(fNewRotX > M_PI_2)
|
|
{
|
|
fNewRotX = M_PI_2;
|
|
}
|
|
|
|
SetRotation(fNewRotX, fNewRotY, mfSaveActionStartRotZ);
|
|
|
|
if(maChangeCallback.IsSet())
|
|
{
|
|
maChangeCallback.Call(this);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// interaction in progress
|
|
double fNewPosHor = mfSaveActionStartHor + static_cast<double>(aDeltaPos.X());
|
|
double fNewPosVer = mfSaveActionStartVer - static_cast<double>(aDeltaPos.Y());
|
|
|
|
// cut horizontal
|
|
fNewPosHor = NormAngle360(fNewPosHor);
|
|
|
|
// cut vertical
|
|
if(fNewPosVer < -90.0)
|
|
{
|
|
fNewPosVer = -90.0;
|
|
}
|
|
|
|
if(fNewPosVer > 90.0)
|
|
{
|
|
fNewPosVer = 90.0;
|
|
}
|
|
|
|
SetPosition(fNewPosHor, fNewPosVer);
|
|
|
|
if(maChangeCallback.IsSet())
|
|
{
|
|
maChangeCallback.Call(this);
|
|
}
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
bool Svx3DLightControl::MouseButtonUp(const MouseEvent& rMEvt)
|
|
{
|
|
if (!mbMouseCaptured)
|
|
return false;
|
|
ReleaseMouse();
|
|
mbMouseCaptured = false;
|
|
|
|
if (mbMouseMoved)
|
|
{
|
|
// was change interactively
|
|
}
|
|
else
|
|
{
|
|
// simple click without much movement, try selection
|
|
TrySelection(rMEvt.GetPosPixel());
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void Svx3DLightControl::Resize()
|
|
{
|
|
// set size of page
|
|
const Size aSize(GetDrawingArea()->get_ref_device().PixelToLogic(GetOutputSizePixel()));
|
|
mxFmPage->SetSize(aSize);
|
|
|
|
// set position and size of scene
|
|
mpScene->SetSnapRect(tools::Rectangle(Point(0, 0), aSize));
|
|
}
|
|
|
|
void Svx3DLightControl::SetObjectType(SvxPreviewObjectType nType)
|
|
{
|
|
// call parent
|
|
Svx3DPreviewControl::SetObjectType(nType);
|
|
|
|
// apply object rotation
|
|
if(mp3DObj)
|
|
{
|
|
basegfx::B3DHomMatrix aObjectRotation;
|
|
aObjectRotation.rotate(mfRotateX, mfRotateY, mfRotateZ);
|
|
mp3DObj->SetTransform(aObjectRotation);
|
|
}
|
|
}
|
|
|
|
bool Svx3DLightControl::IsSelectionValid()
|
|
{
|
|
return (NO_LIGHT_SELECTED != maSelectedLight) && GetLightOnOff(maSelectedLight);
|
|
}
|
|
|
|
void Svx3DLightControl::GetPosition(double& rHor, double& rVer)
|
|
{
|
|
if(IsSelectionValid())
|
|
{
|
|
basegfx::B3DVector aDirection(GetLightDirection(maSelectedLight));
|
|
aDirection.normalize();
|
|
rHor = basegfx::rad2deg(atan2(-aDirection.getX(), -aDirection.getZ()) + M_PI); // 0..360.0
|
|
rVer = basegfx::rad2deg(atan2(aDirection.getY(), aDirection.getXZLength())); // -90.0..90.0
|
|
}
|
|
if(IsGeometrySelected())
|
|
{
|
|
rHor = basegfx::rad2deg(mfRotateY); // 0..360.0
|
|
rVer = basegfx::rad2deg(mfRotateX); // -90.0..90.0
|
|
}
|
|
}
|
|
|
|
void Svx3DLightControl::SetPosition(double fHor, double fVer)
|
|
{
|
|
if(IsSelectionValid())
|
|
{
|
|
// set selected light's direction
|
|
fHor = basegfx::deg2rad(fHor) - M_PI; // -PI..PI
|
|
fVer = basegfx::deg2rad(fVer); // -PI2..PI2
|
|
basegfx::B3DVector aDirection(cos(fVer) * -sin(fHor), sin(fVer), cos(fVer) * -cos(fHor));
|
|
aDirection.normalize();
|
|
|
|
if(!aDirection.equal(GetLightDirection(maSelectedLight)))
|
|
{
|
|
// set changed light direction at SdrScene
|
|
SfxItemSet aSet(mpModel->GetItemPool());
|
|
|
|
switch(maSelectedLight)
|
|
{
|
|
case 0: aSet.Put(makeSvx3DLightDirection1Item(aDirection)); break;
|
|
case 1: aSet.Put(makeSvx3DLightDirection2Item(aDirection)); break;
|
|
case 2: aSet.Put(makeSvx3DLightDirection3Item(aDirection)); break;
|
|
case 3: aSet.Put(makeSvx3DLightDirection4Item(aDirection)); break;
|
|
case 4: aSet.Put(makeSvx3DLightDirection5Item(aDirection)); break;
|
|
case 5: aSet.Put(makeSvx3DLightDirection6Item(aDirection)); break;
|
|
case 6: aSet.Put(makeSvx3DLightDirection7Item(aDirection)); break;
|
|
default:
|
|
case 7: aSet.Put(makeSvx3DLightDirection8Item(aDirection)); break;
|
|
}
|
|
|
|
mpScene->SetMergedItemSet(aSet);
|
|
|
|
// correct 3D light's and LampFrame's geometries
|
|
AdaptToSelectedLight();
|
|
Invalidate();
|
|
}
|
|
}
|
|
if(!IsGeometrySelected())
|
|
return;
|
|
|
|
if(mfRotateX == fVer && mfRotateY == fHor)
|
|
return;
|
|
|
|
mfRotateX = basegfx::deg2rad(fVer);
|
|
mfRotateY = basegfx::deg2rad(fHor);
|
|
|
|
if(mp3DObj)
|
|
{
|
|
basegfx::B3DHomMatrix aObjectRotation;
|
|
aObjectRotation.rotate(mfRotateX, mfRotateY, mfRotateZ);
|
|
mp3DObj->SetTransform(aObjectRotation);
|
|
|
|
Invalidate();
|
|
}
|
|
}
|
|
|
|
void Svx3DLightControl::SetRotation(double fRotX, double fRotY, double fRotZ)
|
|
{
|
|
if(!IsGeometrySelected())
|
|
return;
|
|
|
|
if(fRotX == mfRotateX && fRotY == mfRotateY && fRotZ == mfRotateZ)
|
|
return;
|
|
|
|
mfRotateX = fRotX;
|
|
mfRotateY = fRotY;
|
|
mfRotateZ = fRotZ;
|
|
|
|
if(mp3DObj)
|
|
{
|
|
basegfx::B3DHomMatrix aObjectRotation;
|
|
aObjectRotation.rotate(mfRotateX, mfRotateY, mfRotateZ);
|
|
mp3DObj->SetTransform(aObjectRotation);
|
|
|
|
Invalidate();
|
|
}
|
|
}
|
|
|
|
void Svx3DLightControl::GetRotation(double& rRotX, double& rRotY, double& rRotZ)
|
|
{
|
|
rRotX = mfRotateX;
|
|
rRotY = mfRotateY;
|
|
rRotZ = mfRotateZ;
|
|
}
|
|
|
|
void Svx3DLightControl::Set3DAttributes( const SfxItemSet& rAttr )
|
|
{
|
|
// call parent
|
|
Svx3DPreviewControl::Set3DAttributes(rAttr);
|
|
|
|
if(maSelectedLight != NO_LIGHT_SELECTED && !GetLightOnOff(maSelectedLight))
|
|
{
|
|
// selected light is no more active, select new one
|
|
maSelectedLight = NO_LIGHT_SELECTED;
|
|
}
|
|
|
|
// local updates
|
|
ConstructLightObjects();
|
|
AdaptToSelectedLight();
|
|
Invalidate();
|
|
}
|
|
|
|
void Svx3DLightControl::SelectLight(sal_uInt32 nLightNumber)
|
|
{
|
|
if(nLightNumber > 7)
|
|
{
|
|
nLightNumber = NO_LIGHT_SELECTED;
|
|
}
|
|
|
|
if(NO_LIGHT_SELECTED != nLightNumber)
|
|
{
|
|
if(!GetLightOnOff(nLightNumber))
|
|
{
|
|
nLightNumber = NO_LIGHT_SELECTED;
|
|
}
|
|
}
|
|
|
|
if(nLightNumber != maSelectedLight)
|
|
{
|
|
maSelectedLight = nLightNumber;
|
|
mbGeometrySelected = false;
|
|
ConstructLightObjects();
|
|
AdaptToSelectedLight();
|
|
Invalidate();
|
|
}
|
|
}
|
|
|
|
bool Svx3DLightControl::GetLightOnOff(sal_uInt32 nNum) const
|
|
{
|
|
if(nNum <= 7)
|
|
{
|
|
const SfxItemSet aLightItemSet(Get3DAttributes());
|
|
|
|
switch(nNum)
|
|
{
|
|
case 0 : return aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTON_1).GetValue();
|
|
case 1 : return aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTON_2).GetValue();
|
|
case 2 : return aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTON_3).GetValue();
|
|
case 3 : return aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTON_4).GetValue();
|
|
case 4 : return aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTON_5).GetValue();
|
|
case 5 : return aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTON_6).GetValue();
|
|
case 6 : return aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTON_7).GetValue();
|
|
case 7 : return aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTON_8).GetValue();
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
Color Svx3DLightControl::GetLightColor(sal_uInt32 nNum) const
|
|
{
|
|
if(nNum <= 7)
|
|
{
|
|
const SfxItemSet aLightItemSet(Get3DAttributes());
|
|
|
|
switch(nNum)
|
|
{
|
|
case 0 : return aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTCOLOR_1).GetValue();
|
|
case 1 : return aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTCOLOR_2).GetValue();
|
|
case 2 : return aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTCOLOR_3).GetValue();
|
|
case 3 : return aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTCOLOR_4).GetValue();
|
|
case 4 : return aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTCOLOR_5).GetValue();
|
|
case 5 : return aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTCOLOR_6).GetValue();
|
|
case 6 : return aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTCOLOR_7).GetValue();
|
|
case 7 : return aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTCOLOR_8).GetValue();
|
|
}
|
|
}
|
|
|
|
return COL_BLACK;
|
|
}
|
|
|
|
basegfx::B3DVector Svx3DLightControl::GetLightDirection(sal_uInt32 nNum) const
|
|
{
|
|
if(nNum <= 7)
|
|
{
|
|
const SfxItemSet aLightItemSet(Get3DAttributes());
|
|
|
|
switch(nNum)
|
|
{
|
|
case 0 : return aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_1).GetValue();
|
|
case 1 : return aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_2).GetValue();
|
|
case 2 : return aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_3).GetValue();
|
|
case 3 : return aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_4).GetValue();
|
|
case 4 : return aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_5).GetValue();
|
|
case 5 : return aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_6).GetValue();
|
|
case 6 : return aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_7).GetValue();
|
|
case 7 : return aLightItemSet.Get(SDRATTR_3DSCENE_LIGHTDIRECTION_8).GetValue();
|
|
}
|
|
}
|
|
|
|
return basegfx::B3DVector();
|
|
}
|
|
|
|
SvxLightCtl3D::SvxLightCtl3D(Svx3DLightControl& rLightControl, weld::Scale& rHori,
|
|
weld::Scale& rVert, weld::Button& rSwitcher)
|
|
: mrLightControl(rLightControl)
|
|
, mrHorScroller(rHori)
|
|
, mrVerScroller(rVert)
|
|
, mrSwitcher(rSwitcher)
|
|
{
|
|
// init members
|
|
Init();
|
|
}
|
|
|
|
void SvxLightCtl3D::Init()
|
|
{
|
|
Size aSize(mrLightControl.GetDrawingArea()->get_ref_device().LogicToPixel(Size(80, 100), MapMode(MapUnit::MapAppFont)));
|
|
mrLightControl.set_size_request(aSize.Width(), aSize.Height());
|
|
|
|
// #i58240# set HelpIDs for scrollbars and switcher
|
|
mrHorScroller.set_help_id(HID_CTRL3D_HSCROLL);
|
|
mrVerScroller.set_help_id(HID_CTRL3D_VSCROLL);
|
|
mrSwitcher.set_help_id(HID_CTRL3D_SWITCHER);
|
|
mrSwitcher.set_accessible_name(SvxResId(STR_SWITCH));
|
|
|
|
// Light preview
|
|
mrLightControl.Show();
|
|
mrLightControl.SetChangeCallback( LINK(this, SvxLightCtl3D, InternalInteractiveChange) );
|
|
mrLightControl.SetSelectionChangeCallback( LINK(this, SvxLightCtl3D, InternalSelectionChange) );
|
|
|
|
// Horiz Scrollbar
|
|
mrHorScroller.show();
|
|
mrHorScroller.set_range(0, 36000);
|
|
mrHorScroller.connect_value_changed( LINK(this, SvxLightCtl3D, ScrollBarMove) );
|
|
|
|
// Vert Scrollbar
|
|
mrVerScroller.show();
|
|
mrVerScroller.set_range(0, 18000);
|
|
mrVerScroller.connect_value_changed( LINK(this, SvxLightCtl3D, ScrollBarMove) );
|
|
|
|
// Switch Button
|
|
mrSwitcher.show();
|
|
mrSwitcher.connect_clicked( LINK(this, SvxLightCtl3D, ButtonPress) );
|
|
|
|
weld::DrawingArea* pArea = mrLightControl.GetDrawingArea();
|
|
pArea->connect_key_press(Link<const KeyEvent&, bool>()); //acknowledge we first remove the old one
|
|
pArea->connect_key_press(LINK(this, SvxLightCtl3D, KeyInput));
|
|
|
|
pArea->connect_focus_in(Link<weld::Widget&, void>()); //acknowledge we first remove the old one
|
|
pArea->connect_focus_in(LINK(this, SvxLightCtl3D, FocusIn));
|
|
|
|
// check selection
|
|
CheckSelection();
|
|
}
|
|
|
|
void SvxLightCtl3D::CheckSelection()
|
|
{
|
|
const bool bSelectionValid(mrLightControl.IsSelectionValid() || mrLightControl.IsGeometrySelected());
|
|
mrHorScroller.set_sensitive(bSelectionValid);
|
|
mrVerScroller.set_sensitive(bSelectionValid);
|
|
|
|
if (bSelectionValid)
|
|
{
|
|
double fHor(0.0), fVer(0.0);
|
|
mrLightControl.GetPosition(fHor, fVer);
|
|
mrHorScroller.set_value( sal_Int32(fHor * 100.0) );
|
|
mrVerScroller.set_value( 18000 - sal_Int32((fVer + 90.0) * 100.0) );
|
|
}
|
|
}
|
|
|
|
void SvxLightCtl3D::move( double fDeltaHor, double fDeltaVer )
|
|
{
|
|
double fHor(0.0), fVer(0.0);
|
|
|
|
mrLightControl.GetPosition(fHor, fVer);
|
|
fHor += fDeltaHor;
|
|
fVer += fDeltaVer;
|
|
|
|
if( fVer > 90.0 )
|
|
return;
|
|
|
|
if ( fVer < -90.0 )
|
|
return;
|
|
|
|
mrLightControl.SetPosition(fHor, fVer);
|
|
mrHorScroller.set_value( sal_Int32(fHor * 100.0) );
|
|
mrVerScroller.set_value( 18000 - sal_Int32((fVer + 90.0) * 100.0) );
|
|
|
|
if(maUserInteractiveChangeCallback.IsSet())
|
|
{
|
|
maUserInteractiveChangeCallback.Call(this);
|
|
}
|
|
}
|
|
|
|
IMPL_LINK(SvxLightCtl3D, KeyInput, const KeyEvent&, rKEvt, bool)
|
|
{
|
|
const vcl::KeyCode aCode(rKEvt.GetKeyCode());
|
|
|
|
if (aCode.GetModifier())
|
|
return false;
|
|
|
|
bool bHandled = true;
|
|
|
|
switch ( aCode.GetCode() )
|
|
{
|
|
case KEY_SPACE:
|
|
{
|
|
break;
|
|
}
|
|
case KEY_LEFT:
|
|
{
|
|
move( -4.0, 0.0 ); // #i58242# changed move direction in X
|
|
break;
|
|
}
|
|
case KEY_RIGHT:
|
|
{
|
|
move( 4.0, 0.0 ); // #i58242# changed move direction in X
|
|
break;
|
|
}
|
|
case KEY_UP:
|
|
{
|
|
move( 0.0, 4.0 );
|
|
break;
|
|
}
|
|
case KEY_DOWN:
|
|
{
|
|
move( 0.0, -4.0 );
|
|
break;
|
|
}
|
|
case KEY_PAGEUP:
|
|
{
|
|
sal_Int32 nLight(mrLightControl.GetSelectedLight() - 1);
|
|
|
|
while((nLight >= 0) && !mrLightControl.GetLightOnOff(nLight))
|
|
{
|
|
nLight--;
|
|
}
|
|
|
|
if(nLight < 0)
|
|
{
|
|
nLight = 7;
|
|
|
|
while((nLight >= 0) && !mrLightControl.GetLightOnOff(nLight))
|
|
{
|
|
nLight--;
|
|
}
|
|
}
|
|
|
|
if(nLight >= 0)
|
|
{
|
|
mrLightControl.SelectLight(nLight);
|
|
CheckSelection();
|
|
|
|
if(maUserSelectionChangeCallback.IsSet())
|
|
{
|
|
maUserSelectionChangeCallback.Call(this);
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
case KEY_PAGEDOWN:
|
|
{
|
|
sal_Int32 nLight(mrLightControl.GetSelectedLight() - 1);
|
|
|
|
while(nLight <= 7 && !mrLightControl.GetLightOnOff(nLight))
|
|
{
|
|
nLight++;
|
|
}
|
|
|
|
if(nLight > 7)
|
|
{
|
|
nLight = 0;
|
|
|
|
while(nLight <= 7 && !mrLightControl.GetLightOnOff(nLight))
|
|
{
|
|
nLight++;
|
|
}
|
|
}
|
|
|
|
if(nLight <= 7)
|
|
{
|
|
mrLightControl.SelectLight(nLight);
|
|
CheckSelection();
|
|
|
|
if(maUserSelectionChangeCallback.IsSet())
|
|
{
|
|
maUserSelectionChangeCallback.Call(this);
|
|
}
|
|
}
|
|
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
bHandled = false;
|
|
break;
|
|
}
|
|
}
|
|
return bHandled;
|
|
}
|
|
|
|
IMPL_LINK_NOARG(SvxLightCtl3D, FocusIn, weld::Widget&, void)
|
|
{
|
|
if (mrLightControl.IsEnabled())
|
|
{
|
|
CheckSelection();
|
|
}
|
|
}
|
|
|
|
IMPL_LINK_NOARG(SvxLightCtl3D, ScrollBarMove, weld::Scale&, void)
|
|
{
|
|
const sal_Int32 nHor(mrHorScroller.get_value());
|
|
const sal_Int32 nVer(mrVerScroller.get_value());
|
|
|
|
mrLightControl.SetPosition(
|
|
static_cast<double>(nHor) / 100.0,
|
|
static_cast<double>((18000 - nVer) - 9000) / 100.0);
|
|
|
|
if (maUserInteractiveChangeCallback.IsSet())
|
|
{
|
|
maUserInteractiveChangeCallback.Call(this);
|
|
}
|
|
}
|
|
|
|
IMPL_LINK_NOARG(SvxLightCtl3D, ButtonPress, weld::Button&, void)
|
|
{
|
|
if(SvxPreviewObjectType::SPHERE == GetSvx3DLightControl().GetObjectType())
|
|
{
|
|
GetSvx3DLightControl().SetObjectType(SvxPreviewObjectType::CUBE);
|
|
}
|
|
else
|
|
{
|
|
GetSvx3DLightControl().SetObjectType(SvxPreviewObjectType::SPHERE);
|
|
}
|
|
}
|
|
|
|
IMPL_LINK_NOARG(SvxLightCtl3D, InternalInteractiveChange, Svx3DLightControl*, void)
|
|
{
|
|
double fHor(0.0), fVer(0.0);
|
|
|
|
mrLightControl.GetPosition(fHor, fVer);
|
|
mrHorScroller.set_value( sal_Int32(fHor * 100.0) );
|
|
mrVerScroller.set_value( 18000 - sal_Int32((fVer + 90.0) * 100.0) );
|
|
|
|
if(maUserInteractiveChangeCallback.IsSet())
|
|
{
|
|
maUserInteractiveChangeCallback.Call(this);
|
|
}
|
|
}
|
|
|
|
IMPL_LINK_NOARG(SvxLightCtl3D, InternalSelectionChange, Svx3DLightControl*, void)
|
|
{
|
|
CheckSelection();
|
|
|
|
if(maUserSelectionChangeCallback.IsSet())
|
|
{
|
|
maUserSelectionChangeCallback.Call(this);
|
|
}
|
|
}
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|