1
0
Fork 0
libreoffice/sw/source/uibase/docvw/AnchorOverlayObject.cxx
Daniel Baumann 8e63e14cf6
Adding upstream version 4:25.2.3.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
2025-06-22 16:20:04 +02:00

388 lines
13 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 "AnchorOverlayObject.hxx"
#include <SidebarWindowsConsts.hxx>
#include <swrect.hxx>
#include <utility>
#include <view.hxx>
#include <svx/sdrpaintwindow.hxx>
#include <svx/svdview.hxx>
#include <svx/sdr/overlay/overlaymanager.hxx>
#include <tools/long.hxx>
#include <sw_primitivetypes2d.hxx>
#include <drawinglayer/attribute/lineattribute.hxx>
#include <drawinglayer/attribute/strokeattribute.hxx>
#include <drawinglayer/primitive2d/primitivetools2d.hxx>
#include <drawinglayer/primitive2d/PolyPolygonColorPrimitive2D.hxx>
#include <drawinglayer/primitive2d/PolygonStrokePrimitive2D.hxx>
#include <drawinglayer/primitive2d/groupprimitive2d.hxx>
namespace sw::sidebarwindows {
namespace {
// helper class: Primitive for discrete visualisation
class AnchorPrimitive : public drawinglayer::primitive2d::DiscreteMetricDependentPrimitive2D
{
private:
basegfx::B2DPolygon maTriangle;
basegfx::B2DPolygon maLine;
basegfx::B2DPolygon maLineTop;
const AnchorState maAnchorState;
basegfx::BColor maColor;
// discrete line width
double mfDiscreteLineWidth;
bool mbLineSolid : 1;
protected:
virtual drawinglayer::primitive2d::Primitive2DReference create2DDecomposition(
const drawinglayer::geometry::ViewInformation2D& rViewInformation) const override;
public:
AnchorPrimitive( basegfx::B2DPolygon aTriangle,
basegfx::B2DPolygon aLine,
basegfx::B2DPolygon aLineTop,
AnchorState aAnchorState,
const basegfx::BColor& rColor,
double fDiscreteLineWidth,
bool bLineSolid )
: maTriangle(std::move(aTriangle)),
maLine(std::move(aLine)),
maLineTop(std::move(aLineTop)),
maAnchorState(aAnchorState),
maColor(rColor),
mfDiscreteLineWidth(fDiscreteLineWidth),
mbLineSolid(bLineSolid)
{}
// data access
const basegfx::B2DPolygon& getLine() const { return maLine; }
const basegfx::BColor& getColor() const { return maColor; }
bool getLineSolid() const { return mbLineSolid; }
virtual bool operator==( const drawinglayer::primitive2d::BasePrimitive2D& rPrimitive ) const override;
virtual sal_uInt32 getPrimitive2DID() const override;
};
}
drawinglayer::primitive2d::Primitive2DReference AnchorPrimitive::create2DDecomposition(
const drawinglayer::geometry::ViewInformation2D& /*rViewInformation*/) const
{
drawinglayer::primitive2d::Primitive2DContainer aContainer;
if ( AnchorState::Tri == maAnchorState ||
AnchorState::All == maAnchorState )
{
// create triangle
const drawinglayer::primitive2d::Primitive2DReference aTriangle(
new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D(
basegfx::B2DPolyPolygon(maTriangle),
getColor()));
aContainer.push_back(aTriangle);
}
// prepare view-independent LineWidth and color
const drawinglayer::attribute::LineAttribute aLineAttribute(
getColor(),
mfDiscreteLineWidth * getDiscreteUnit());
if ( AnchorState::All == maAnchorState )
{
// create line start
if(getLineSolid())
{
const drawinglayer::primitive2d::Primitive2DReference aSolidLine(
new drawinglayer::primitive2d::PolygonStrokePrimitive2D(
getLine(),
aLineAttribute));
aContainer.push_back(aSolidLine);
}
else
{
std::vector< double > aDotDashArray;
const double fDistance(3.0 * 15.0);
const double fDashLen(5.0 * 15.0);
aDotDashArray.push_back(fDashLen);
aDotDashArray.push_back(fDistance);
drawinglayer::attribute::StrokeAttribute aStrokeAttribute(
std::move(aDotDashArray),
fDistance + fDashLen);
const drawinglayer::primitive2d::Primitive2DReference aStrokedLine(
new drawinglayer::primitive2d::PolygonStrokePrimitive2D(
getLine(),
aLineAttribute,
std::move(aStrokeAttribute)));
aContainer.push_back(aStrokedLine);
}
}
if ( AnchorState::All == maAnchorState ||
AnchorState::End == maAnchorState )
{
// LineTop has to be created, too, but uses no shadow, so add after
// the other parts are created
const drawinglayer::primitive2d::Primitive2DReference aLineTop(
new drawinglayer::primitive2d::PolygonStrokePrimitive2D(
maLineTop,
aLineAttribute));
aContainer.push_back(aLineTop);
}
return new drawinglayer::primitive2d::GroupPrimitive2D(std::move(aContainer));
}
bool AnchorPrimitive::operator==( const drawinglayer::primitive2d::BasePrimitive2D& rPrimitive ) const
{
if(drawinglayer::primitive2d::DiscreteMetricDependentPrimitive2D::operator==(rPrimitive))
{
const AnchorPrimitive& rCompare = static_cast< const AnchorPrimitive& >(rPrimitive);
return (maTriangle == rCompare.maTriangle
&& getLine() == rCompare.getLine()
&& maLineTop == rCompare.maLineTop
&& maAnchorState == rCompare.maAnchorState
&& getColor() == rCompare.getColor()
&& mfDiscreteLineWidth == rCompare.mfDiscreteLineWidth
&& getLineSolid() == rCompare.getLineSolid());
}
return false;
}
sal_uInt32 AnchorPrimitive::getPrimitive2DID() const
{
return PRIMITIVE2D_ID_SWSIDEBARANCHORPRIMITIVE;
}
/*static*/ std::unique_ptr<AnchorOverlayObject> AnchorOverlayObject::CreateAnchorOverlayObject(
SwView const & rDocView,
const SwRect& aAnchorRect,
tools::Long aPageBorder,
const Point& aLineStart,
const Point& aLineEnd,
const Color& aColorAnchor )
{
std::unique_ptr<AnchorOverlayObject> pAnchorOverlayObject;
if ( rDocView.GetDrawView() )
{
SdrPaintWindow* pPaintWindow = rDocView.GetDrawView()->GetPaintWindow(0);
if( pPaintWindow )
{
const rtl::Reference< sdr::overlay::OverlayManager >& xOverlayManager = pPaintWindow->GetOverlayManager();
if ( xOverlayManager.is() )
{
pAnchorOverlayObject.reset(new AnchorOverlayObject(
basegfx::B2DPoint( aAnchorRect.Left() , aAnchorRect.Bottom()-5*15),
basegfx::B2DPoint( aAnchorRect.Left()-5*15 , aAnchorRect.Bottom()+5*15),
basegfx::B2DPoint( aAnchorRect.Left()+5*15 , aAnchorRect.Bottom()+5*15),
basegfx::B2DPoint( aAnchorRect.Left(), aAnchorRect.Bottom()+2*15),
basegfx::B2DPoint( aPageBorder ,aAnchorRect.Bottom()+2*15),
basegfx::B2DPoint( aLineStart.X(),aLineStart.Y()),
basegfx::B2DPoint( aLineEnd.X(),aLineEnd.Y()) ,
aColorAnchor));
xOverlayManager->add(*pAnchorOverlayObject);
}
}
}
return pAnchorOverlayObject;
}
AnchorOverlayObject::AnchorOverlayObject( const basegfx::B2DPoint& rBasePos,
const basegfx::B2DPoint& rSecondPos,
const basegfx::B2DPoint& rThirdPos,
const basegfx::B2DPoint& rFourthPos,
const basegfx::B2DPoint& rFifthPos,
const basegfx::B2DPoint& rSixthPos,
const basegfx::B2DPoint& rSeventhPos,
const Color& rBaseColor)
: OverlayObjectWithBasePosition(rBasePos, rBaseColor)
, maSecondPosition(rSecondPos)
, maThirdPosition(rThirdPos)
, maFourthPosition(rFourthPos)
, maFifthPosition(rFifthPos)
, maSixthPosition(rSixthPos)
, maSeventhPosition(rSeventhPos)
, mAnchorState(AnchorState::All)
, mbLineSolid(false)
{
}
AnchorOverlayObject::~AnchorOverlayObject()
{
if ( getOverlayManager() )
{
// remove this object from the chain
getOverlayManager()->remove(*this);
}
}
void AnchorOverlayObject::implEnsureGeometry()
{
if(!maTriangle.count())
{
maTriangle.append(getBasePosition());
maTriangle.append(GetSecondPosition());
maTriangle.append(GetThirdPosition());
maTriangle.setClosed(true);
}
if(!maLine.count())
{
maLine.append(GetFourthPosition());
maLine.append(GetFifthPosition());
maLine.append(GetSixthPosition());
}
if(!maLineTop.count())
{
maLineTop.append(GetSixthPosition());
maLineTop.append(GetSeventhPosition());
}
}
void AnchorOverlayObject::implResetGeometry()
{
maTriangle.clear();
maLine.clear();
maLineTop.clear();
}
drawinglayer::primitive2d::Primitive2DContainer AnchorOverlayObject::createOverlayObjectPrimitive2DSequence()
{
implEnsureGeometry();
static const double aDiscreteLineWidth(1.6);
const drawinglayer::primitive2d::Primitive2DReference aReference(
new AnchorPrimitive( maTriangle,
maLine,
maLineTop,
GetAnchorState(),
getBaseColor().getBColor(),
ANCHORLINE_WIDTH * aDiscreteLineWidth,
getLineSolid()) );
return drawinglayer::primitive2d::Primitive2DContainer { aReference };
}
void AnchorOverlayObject::SetAllPosition( const basegfx::B2DPoint& rPoint1,
const basegfx::B2DPoint& rPoint2,
const basegfx::B2DPoint& rPoint3,
const basegfx::B2DPoint& rPoint4,
const basegfx::B2DPoint& rPoint5,
const basegfx::B2DPoint& rPoint6,
const basegfx::B2DPoint& rPoint7)
{
if ( !(rPoint1 != getBasePosition() ||
rPoint2 != GetSecondPosition() ||
rPoint3 != GetThirdPosition() ||
rPoint4 != GetFourthPosition() ||
rPoint5 != GetFifthPosition() ||
rPoint6 != GetSixthPosition() ||
rPoint7 != GetSeventhPosition()) )
return;
maBasePosition = rPoint1;
maSecondPosition = rPoint2;
maThirdPosition = rPoint3;
maFourthPosition = rPoint4;
maFifthPosition = rPoint5;
maSixthPosition = rPoint6;
maSeventhPosition = rPoint7;
implResetGeometry();
objectChange();
}
void AnchorOverlayObject::SetSixthPosition(const basegfx::B2DPoint& rNew)
{
if(rNew != maSixthPosition)
{
maSixthPosition = rNew;
implResetGeometry();
objectChange();
}
}
void AnchorOverlayObject::SetSeventhPosition(const basegfx::B2DPoint& rNew)
{
if(rNew != maSeventhPosition)
{
maSeventhPosition = rNew;
implResetGeometry();
objectChange();
}
}
void AnchorOverlayObject::SetTriPosition(const basegfx::B2DPoint& rPoint1,const basegfx::B2DPoint& rPoint2,const basegfx::B2DPoint& rPoint3,
const basegfx::B2DPoint& rPoint4,const basegfx::B2DPoint& rPoint5)
{
if(rPoint1 != getBasePosition()
|| rPoint2 != GetSecondPosition()
|| rPoint3 != GetThirdPosition()
|| rPoint4 != GetFourthPosition()
|| rPoint5 != GetFifthPosition())
{
maBasePosition = rPoint1;
maSecondPosition = rPoint2;
maThirdPosition = rPoint3;
maFourthPosition = rPoint4;
maFifthPosition = rPoint5;
implResetGeometry();
objectChange();
}
}
void AnchorOverlayObject::setLineSolid( const bool bNew )
{
if ( bNew != getLineSolid() )
{
mbLineSolid = bNew;
objectChange();
}
}
void AnchorOverlayObject::SetAnchorState( const AnchorState aState)
{
if ( mAnchorState != aState)
{
mAnchorState = aState;
objectChange();
}
}
} // end of namespace sw::sidebarwindows
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */