diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 05:54:39 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 05:54:39 +0000 |
commit | 267c6f2ac71f92999e969232431ba04678e7437e (patch) | |
tree | 358c9467650e1d0a1d7227a21dac2e3d08b622b2 /svx/source/svdraw/svdotxdr.cxx | |
parent | Initial commit. (diff) | |
download | libreoffice-267c6f2ac71f92999e969232431ba04678e7437e.tar.xz libreoffice-267c6f2ac71f92999e969232431ba04678e7437e.zip |
Adding upstream version 4:24.2.0.upstream/4%24.2.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'svx/source/svdraw/svdotxdr.cxx')
-rw-r--r-- | svx/source/svdraw/svdotxdr.cxx | 253 |
1 files changed, 253 insertions, 0 deletions
diff --git a/svx/source/svdraw/svdotxdr.cxx b/svx/source/svdraw/svdotxdr.cxx new file mode 100644 index 0000000000..b758b75fe5 --- /dev/null +++ b/svx/source/svdraw/svdotxdr.cxx @@ -0,0 +1,253 @@ +/* -*- 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/svdotext.hxx> +#include <svx/svdhdl.hxx> +#include <svx/svddrag.hxx> +#include <svx/svdview.hxx> +#include <svx/svdorect.hxx> +#include <svx/strings.hrc> +#include <svx/svdoashp.hxx> +#include <tools/bigint.hxx> +#include <basegfx/polygon/b2dpolygon.hxx> +#include <basegfx/range/b2drange.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <vcl/canvastools.hxx> +#include <vcl/ptrstyle.hxx> + + +sal_uInt32 SdrTextObj::GetHdlCount() const +{ + return 8; +} + +void SdrTextObj::AddToHdlList(SdrHdlList& rHdlList) const +{ + for(sal_uInt32 nHdlNum=0; nHdlNum<8; ++nHdlNum) + { + Point aPnt; + SdrHdlKind eKind = SdrHdlKind::UpperLeft; + auto aRectangle = getRectangle(); + switch (nHdlNum) { + case 0: aPnt = aRectangle.TopLeft(); eKind=SdrHdlKind::UpperLeft; break; + case 1: aPnt = aRectangle.TopCenter(); eKind=SdrHdlKind::Upper; break; + case 2: aPnt = aRectangle.TopRight(); eKind=SdrHdlKind::UpperRight; break; + case 3: aPnt = aRectangle.LeftCenter(); eKind=SdrHdlKind::Left ; break; + case 4: aPnt = aRectangle.RightCenter(); eKind=SdrHdlKind::Right; break; + case 5: aPnt = aRectangle.BottomLeft(); eKind=SdrHdlKind::LowerLeft; break; + case 6: aPnt = aRectangle.BottomCenter(); eKind=SdrHdlKind::Lower; break; + case 7: aPnt = aRectangle.BottomRight(); eKind=SdrHdlKind::LowerRight; break; + } + if (maGeo.m_nShearAngle) + ShearPoint(aPnt, aRectangle.TopLeft(), maGeo.mfTanShearAngle); + if (maGeo.m_nRotationAngle) + RotatePoint(aPnt, aRectangle.TopLeft(), maGeo.mfSinRotationAngle, maGeo.mfCosRotationAngle); + std::unique_ptr<SdrHdl> pH(new SdrHdl(aPnt,eKind)); + pH->SetObj(const_cast<SdrTextObj*>(this)); + pH->SetRotationAngle(maGeo.m_nRotationAngle); + rHdlList.AddHdl(std::move(pH)); + } +} + + +bool SdrTextObj::hasSpecialDrag() const +{ + return true; +} + +tools::Rectangle SdrTextObj::ImpDragCalcRect(const SdrDragStat& rDrag) const +{ + tools::Rectangle aTmpRect(getRectangle()); + const SdrHdl* pHdl=rDrag.GetHdl(); + SdrHdlKind eHdl=pHdl==nullptr ? SdrHdlKind::Move : pHdl->GetKind(); + bool bEcke=(eHdl==SdrHdlKind::UpperLeft || eHdl==SdrHdlKind::UpperRight || eHdl==SdrHdlKind::LowerLeft || eHdl==SdrHdlKind::LowerRight); + bool bOrtho=rDrag.GetView()!=nullptr && rDrag.GetView()->IsOrtho(); + bool bBigOrtho=bEcke && bOrtho && rDrag.GetView()->IsBigOrtho(); + Point aPos(rDrag.GetNow()); + // Unrotate: + if (maGeo.m_nRotationAngle) RotatePoint(aPos,aTmpRect.TopLeft(),-maGeo.mfSinRotationAngle,maGeo.mfCosRotationAngle); + // Unshear: + if (maGeo.m_nShearAngle) ShearPoint(aPos,aTmpRect.TopLeft(),-maGeo.mfTanShearAngle); + + bool bLft=(eHdl==SdrHdlKind::UpperLeft || eHdl==SdrHdlKind::Left || eHdl==SdrHdlKind::LowerLeft); + bool bRgt=(eHdl==SdrHdlKind::UpperRight || eHdl==SdrHdlKind::Right || eHdl==SdrHdlKind::LowerRight); + bool bTop=(eHdl==SdrHdlKind::UpperRight || eHdl==SdrHdlKind::Upper || eHdl==SdrHdlKind::UpperLeft); + bool bBtm=(eHdl==SdrHdlKind::LowerRight || eHdl==SdrHdlKind::Lower || eHdl==SdrHdlKind::LowerLeft); + if (bLft) aTmpRect.SetLeft(aPos.X() ); + if (bRgt) aTmpRect.SetRight(aPos.X() ); + if (bTop) aTmpRect.SetTop(aPos.Y() ); + if (bBtm) aTmpRect.SetBottom(aPos.Y() ); + if (bOrtho) { // Ortho + tools::Long nWdt0=getRectangle().Right() - getRectangle().Left(); + tools::Long nHgt0=getRectangle().Bottom() - getRectangle().Top(); + tools::Long nXMul=aTmpRect.Right() -aTmpRect.Left(); + tools::Long nYMul=aTmpRect.Bottom()-aTmpRect.Top(); + tools::Long nXDiv=nWdt0; + tools::Long nYDiv=nHgt0; + bool bXNeg=(nXMul<0)!=(nXDiv<0); + bool bYNeg=(nYMul<0)!=(nYDiv<0); + nXMul=std::abs(nXMul); + nYMul=std::abs(nYMul); + nXDiv=std::abs(nXDiv); + nYDiv=std::abs(nYDiv); + Fraction aXFact(nXMul,nXDiv); // fractions for canceling + Fraction aYFact(nYMul,nYDiv); // and for comparing + nXMul=aXFact.GetNumerator(); + nYMul=aYFact.GetNumerator(); + nXDiv=aXFact.GetDenominator(); + nYDiv=aYFact.GetDenominator(); + if (bEcke) { // corner point handles + bool bUseX=(aXFact<aYFact) != bBigOrtho; + if (bUseX) { + tools::Long nNeed=tools::Long(BigInt(nHgt0)*BigInt(nXMul)/BigInt(nXDiv)); + if (bYNeg) nNeed=-nNeed; + if (bTop) aTmpRect.SetTop(aTmpRect.Bottom()-nNeed ); + if (bBtm) aTmpRect.SetBottom(aTmpRect.Top()+nNeed ); + } else { + tools::Long nNeed=tools::Long(BigInt(nWdt0)*BigInt(nYMul)/BigInt(nYDiv)); + if (bXNeg) nNeed=-nNeed; + if (bLft) aTmpRect.SetLeft(aTmpRect.Right()-nNeed ); + if (bRgt) aTmpRect.SetRight(aTmpRect.Left()+nNeed ); + } + } else { // apex handles + if ((bLft || bRgt) && nXDiv!=0) { + tools::Long nHgt0b=getRectangle().Bottom() - getRectangle().Top(); + tools::Long nNeed=tools::Long(BigInt(nHgt0b)*BigInt(nXMul)/BigInt(nXDiv)); + aTmpRect.AdjustTop( -((nNeed-nHgt0b)/2) ); + aTmpRect.SetBottom(aTmpRect.Top()+nNeed ); + } + if ((bTop || bBtm) && nYDiv!=0) { + tools::Long nWdt0b=getRectangle().Right() - getRectangle().Left(); + tools::Long nNeed=tools::Long(BigInt(nWdt0b)*BigInt(nYMul)/BigInt(nYDiv)); + aTmpRect.AdjustLeft( -((nNeed-nWdt0b)/2) ); + aTmpRect.SetRight(aTmpRect.Left()+nNeed ); + } + } + } + if (dynamic_cast<const SdrObjCustomShape*>(this) == nullptr) // not justifying when in CustomShapes, to be able to detect if a shape has to be mirrored + ImpJustifyRect(aTmpRect); + return aTmpRect; +} + + +// drag + +bool SdrTextObj::applySpecialDrag(SdrDragStat& rDrag) +{ + tools::Rectangle aNewRect(ImpDragCalcRect(rDrag)); + + if(aNewRect.TopLeft() != getRectangle().TopLeft() && (maGeo.m_nRotationAngle || maGeo.m_nShearAngle)) + { + Point aNewPos(aNewRect.TopLeft()); + + if (maGeo.m_nShearAngle) + ShearPoint(aNewPos, getRectangle().TopLeft(), maGeo.mfTanShearAngle); + + if (maGeo.m_nRotationAngle) + RotatePoint(aNewPos, getRectangle().TopLeft(), maGeo.mfSinRotationAngle, maGeo.mfCosRotationAngle); + + aNewRect.SetPos(aNewPos); + } + + if (aNewRect != getRectangle()) + { + NbcSetLogicRect(aNewRect); + } + + return true; +} + +OUString SdrTextObj::getSpecialDragComment(const SdrDragStat& /*rDrag*/) const +{ + return ImpGetDescriptionStr(STR_DragRectResize); +} + + +// Create + +bool SdrTextObj::BegCreate(SdrDragStat& rStat) +{ + rStat.SetOrtho4Possible(); + tools::Rectangle aRect1(rStat.GetStart(), rStat.GetNow()); + aRect1.Normalize(); + rStat.SetActionRect(aRect1); + setRectangle(aRect1); + return true; +} + +bool SdrTextObj::MovCreate(SdrDragStat& rStat) +{ + tools::Rectangle aRect1; + rStat.TakeCreateRect(aRect1); + ImpJustifyRect(aRect1); + rStat.SetActionRect(aRect1); + setRectangle(aRect1); // for ObjName + SetBoundRectDirty(); + m_bSnapRectDirty=true; + if (auto pRectObj = dynamic_cast<SdrRectObj *>(this)) { + pRectObj->SetXPolyDirty(); + } + return true; +} + +bool SdrTextObj::EndCreate(SdrDragStat& rStat, SdrCreateCmd eCmd) +{ + tools::Rectangle aRectangle(getRectangle()); + rStat.TakeCreateRect(aRectangle); + ImpJustifyRect(aRectangle); + setRectangle(aRectangle); + + AdaptTextMinSize(); + + SetBoundAndSnapRectsDirty(); + if (auto pRectObj = dynamic_cast<SdrRectObj *>(this)) { + pRectObj->SetXPolyDirty(); + } + return (eCmd==SdrCreateCmd::ForceEnd || rStat.GetPointCount()>=2); +} + +void SdrTextObj::BrkCreate(SdrDragStat& /*rStat*/) +{ +} + +bool SdrTextObj::BckCreate(SdrDragStat& /*rStat*/) +{ + return true; +} + +basegfx::B2DPolyPolygon SdrTextObj::TakeCreatePoly(const SdrDragStat& rDrag) const +{ + tools::Rectangle aRect1; + rDrag.TakeCreateRect(aRect1); + aRect1.Normalize(); + + basegfx::B2DPolyPolygon aRetval; + const basegfx::B2DRange aRange = vcl::unotools::b2DRectangleFromRectangle(aRect1); + aRetval.append(basegfx::utils::createPolygonFromRect(aRange)); + return aRetval; +} + +PointerStyle SdrTextObj::GetCreatePointer() const +{ + if (IsTextFrame()) return PointerStyle::DrawText; + return PointerStyle::Cross; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |