drawinglayer/source/processor2d/hittestprocessor2d.cxx | 49 ++++++++-------- include/basegfx/range/Range2D.hxx | 7 ++ include/drawinglayer/processor2d/hittestprocessor2d.hxx | 10 +-- include/svx/sdrhittesthelper.hxx | 12 ++- sc/source/ui/drawfunc/fupoor.cxx | 5 - sc/source/ui/drawfunc/fusel2.cxx | 5 - sc/source/ui/unoobj/viewuno.cxx | 5 - sd/source/ui/func/fudraw.cxx | 12 +-- sd/source/ui/func/fusel.cxx | 12 +-- sd/source/ui/view/sdview3.cxx | 13 +--- svx/source/accessibility/GraphCtlAccessibleContext.cxx | 2 svx/source/sdr/overlay/overlayobjectlist.cxx | 2 svx/source/svdraw/sdrhittesthelper.cxx | 19 ++---- svx/source/svdraw/svdetc.cxx | 2 svx/source/svdraw/svdmrkv.cxx | 4 - svx/source/svdraw/svdobj.cxx | 2 svx/source/svdraw/svdocapt.cxx | 2 svx/source/svdraw/svdoedge.cxx | 12 +-- svx/source/svdraw/svdview.cxx | 25 +++++--- 19 files changed, 108 insertions(+), 92 deletions(-)
New commits: commit 2c8c436c4a8546276e285dd18f3f7ded091a2c4e Author: Sarper Akdemir <sarper.akdemir.ext...@allotropia.de> AuthorDate: Tue Jul 18 16:57:59 2023 +0300 Commit: Thorsten Behrens <thorsten.behr...@allotropia.de> CommitDate: Fri Jul 21 01:37:18 2023 +0200 tdf#152992: for Impress/Draw add horizontal hit tolerance for quick text edit Implements horizontal hit tolerance for quick text edit in Impress & Draw making it more forgiving. Previously it was required to click exactly on the glyph to get a direct text cursor. Refactors hittestprocessor2d so that it now supports pseudo per axis hit tolerance. i.e. underlying isInEpsilonRange hit check is still the same utilizing the larger tolerance of the two per axis tolerance, but the preliminary check that uses aPolygonRange.grow() and later aPolygonRange.isInside() now filters hit misses out with respect to the per axis hit tolerance. Utilizes hittestprocessor2d's new per axis tolerance to introduce hit tolerance for quick text edit, making it similar to TextEdit mode hit tolerance which only has horizontal tolerance. Fixes wrong use of BoundRect hit to determine text frame border hits. Which previously only made sense for TextFrame borders, and was mostly useless for shapes with text inside. Change-Id: I749e63752da05b01270bfcab2632c41879a848ec Reviewed-on: https://gerrit.libreoffice.org/c/core/+/154640 Reviewed-by: Heiko Tietze <heiko.tie...@documentfoundation.org> Tested-by: Jenkins Reviewed-by: Thorsten Behrens <thorsten.behr...@allotropia.de> diff --git a/drawinglayer/source/processor2d/hittestprocessor2d.cxx b/drawinglayer/source/processor2d/hittestprocessor2d.cxx index 9af3504a5113..6e624fa4ef97 100644 --- a/drawinglayer/source/processor2d/hittestprocessor2d.cxx +++ b/drawinglayer/source/processor2d/hittestprocessor2d.cxx @@ -41,27 +41,25 @@ namespace drawinglayer::processor2d { HitTestProcessor2D::HitTestProcessor2D(const geometry::ViewInformation2D& rViewInformation, const basegfx::B2DPoint& rLogicHitPosition, - double fLogicHitTolerance, + const basegfx::B2DVector& rLogicHitTolerance, bool bHitTextOnly) : BaseProcessor2D(rViewInformation), - mfDiscreteHitTolerance(0.0), + maDiscreteHitTolerance(rLogicHitTolerance), mbCollectHitStack(false), mbHit(false), mbHitTextOnly(bHitTextOnly) { - // init hit tolerance - mfDiscreteHitTolerance = fLogicHitTolerance; + // ensure input parameters for hit tolerance is >= 0.0 + if (maDiscreteHitTolerance.getX() < 0.0) + maDiscreteHitTolerance.setX(0.0); + if (maDiscreteHitTolerance.getY() < 0.0) + maDiscreteHitTolerance.setY(0.0); - if(basegfx::fTools::less(mfDiscreteHitTolerance, 0.0)) - { - // ensure input parameter for hit tolerance is >= 0.0 - mfDiscreteHitTolerance = 0.0; - } - else if(basegfx::fTools::more(mfDiscreteHitTolerance, 0.0)) + if (!maDiscreteHitTolerance.equalZero()) { // generate discrete hit tolerance - mfDiscreteHitTolerance = (getViewInformation2D().getObjectToViewTransformation() - * basegfx::B2DVector(mfDiscreteHitTolerance, 0.0)).getLength(); + maDiscreteHitTolerance + = getViewInformation2D().getObjectToViewTransformation() * rLogicHitTolerance; } // generate discrete hit position @@ -74,7 +72,7 @@ namespace drawinglayer::processor2d bool HitTestProcessor2D::checkHairlineHitWithTolerance( const basegfx::B2DPolygon& rPolygon, - double fDiscreteHitTolerance) const + const basegfx::B2DVector& rDiscreteHitTolerance) const { basegfx::B2DPolygon aLocalPolygon(rPolygon); aLocalPolygon.transform(getViewInformation2D().getObjectToViewTransformation()); @@ -82,9 +80,9 @@ namespace drawinglayer::processor2d // get discrete range basegfx::B2DRange aPolygonRange(aLocalPolygon.getB2DRange()); - if(basegfx::fTools::more(fDiscreteHitTolerance, 0.0)) + if(rDiscreteHitTolerance.getX() > 0 || rDiscreteHitTolerance.getY() > 0) { - aPolygonRange.grow(fDiscreteHitTolerance); + aPolygonRange.grow(rDiscreteHitTolerance); } // do rough range test first @@ -94,7 +92,7 @@ namespace drawinglayer::processor2d return basegfx::utils::isInEpsilonRange( aLocalPolygon, getDiscreteHitPosition(), - fDiscreteHitTolerance); + std::max(rDiscreteHitTolerance.getX(), rDiscreteHitTolerance.getY())); } return false; @@ -102,7 +100,7 @@ namespace drawinglayer::processor2d bool HitTestProcessor2D::checkFillHitWithTolerance( const basegfx::B2DPolyPolygon& rPolyPolygon, - double fDiscreteHitTolerance) const + const basegfx::B2DVector& rDiscreteHitTolerance) const { bool bRetval(false); basegfx::B2DPolyPolygon aLocalPolyPolygon(rPolyPolygon); @@ -110,11 +108,13 @@ namespace drawinglayer::processor2d // get discrete range basegfx::B2DRange aPolygonRange(aLocalPolyPolygon.getB2DRange()); - const bool bDiscreteHitToleranceUsed(basegfx::fTools::more(fDiscreteHitTolerance, 0.0)); - if(bDiscreteHitToleranceUsed) + const bool bDiscreteHitToleranceUsed(rDiscreteHitTolerance.getX() > 0 + || rDiscreteHitTolerance.getY() > 0); + + if (bDiscreteHitToleranceUsed) { - aPolygonRange.grow(fDiscreteHitTolerance); + aPolygonRange.grow(rDiscreteHitTolerance); } // do rough range test first @@ -125,7 +125,7 @@ namespace drawinglayer::processor2d basegfx::utils::isInEpsilonRange( aLocalPolyPolygon, getDiscreteHitPosition(), - fDiscreteHitTolerance)) + std::max(rDiscreteHitTolerance.getX(), rDiscreteHitTolerance.getY()))) { bRetval = true; } @@ -294,7 +294,7 @@ namespace drawinglayer::processor2d * basegfx::B2DVector(rLineAttribute.getWidth() * 0.5, 0.0)); mbHit = checkHairlineHitWithTolerance( rPolygonCandidate.getB2DPolygon(), - getDiscreteHitTolerance() + aDiscreteHalfLineVector.getLength()); + getDiscreteHitTolerance() + aDiscreteHalfLineVector); } } else @@ -332,7 +332,7 @@ namespace drawinglayer::processor2d mbHit = checkHairlineHitWithTolerance( rPolygonCandidate.getB2DPolygon(), - getDiscreteHitTolerance() + aDiscreteHalfLineVector.getLength()); + getDiscreteHitTolerance() + aDiscreteHalfLineVector); } break; @@ -516,7 +516,8 @@ namespace drawinglayer::processor2d const basegfx::B2DPoint aPosition(getViewInformation2D().getObjectToViewTransformation() * rPositions[a]); const basegfx::B2DVector aDistance(aPosition - getDiscreteHitPosition()); - if(aDistance.getLength() <= getDiscreteHitTolerance()) + if (aDistance.getLength() <= std::max(getDiscreteHitTolerance().getX(), + getDiscreteHitTolerance().getY())) { mbHit = true; } diff --git a/include/basegfx/range/Range2D.hxx b/include/basegfx/range/Range2D.hxx index 664887529d35..c93ca1664151 100644 --- a/include/basegfx/range/Range2D.hxx +++ b/include/basegfx/range/Range2D.hxx @@ -166,6 +166,13 @@ public: maRangeY.grow(fValue); } + /// grow set by axis aware values from rTuple + void grow(const Tuple2D<TYPE>& rTuple) + { + maRangeX.grow(rTuple.getX()); + maRangeY.grow(rTuple.getY()); + } + /// clamp value on range Tuple2D<TYPE> clamp(const Tuple2D<TYPE>& rTuple) const { diff --git a/include/drawinglayer/processor2d/hittestprocessor2d.hxx b/include/drawinglayer/processor2d/hittestprocessor2d.hxx index 5638f688964e..5755cf77f5e0 100644 --- a/include/drawinglayer/processor2d/hittestprocessor2d.hxx +++ b/include/drawinglayer/processor2d/hittestprocessor2d.hxx @@ -42,7 +42,7 @@ namespace drawinglayer::processor2d basegfx::B2DPoint maDiscreteHitPosition; /// discrete HitTolerance - double mfDiscreteHitTolerance; + basegfx::B2DVector maDiscreteHitTolerance; /// stack of HitPrimitives, taken care of during HitTest run primitive2d::Primitive2DContainer maHitStack; @@ -60,17 +60,17 @@ namespace drawinglayer::processor2d void processBasePrimitive2D(const primitive2d::BasePrimitive2D& rCandidate) override; bool checkHairlineHitWithTolerance( const basegfx::B2DPolygon& rPolygon, - double fDiscreteHitTolerance) const; + const basegfx::B2DVector& rDiscreteHitTolerance) const; bool checkFillHitWithTolerance( const basegfx::B2DPolyPolygon& rPolyPolygon, - double fDiscreteHitTolerance) const; + const basegfx::B2DVector& rDiscreteHitTolerance) const; void check3DHit(const primitive2d::ScenePrimitive2D& rCandidate); public: HitTestProcessor2D( const geometry::ViewInformation2D& rViewInformation, const basegfx::B2DPoint& rLogicHitPosition, - double fLogicHitTolerance, + const basegfx::B2DVector& rLogicHitTolerance, bool bHitTextOnly); virtual ~HitTestProcessor2D() override; @@ -83,7 +83,7 @@ namespace drawinglayer::processor2d /// data read access const basegfx::B2DPoint& getDiscreteHitPosition() const { return maDiscreteHitPosition; } - double getDiscreteHitTolerance() const { return mfDiscreteHitTolerance; } + const basegfx::B2DVector& getDiscreteHitTolerance() const { return maDiscreteHitTolerance; } bool getCollectHitStack() const { return mbCollectHitStack; } bool getHit() const { return mbHit; } bool getHitTextOnly() const { return mbHitTextOnly; } diff --git a/include/svx/sdrhittesthelper.hxx b/include/svx/sdrhittesthelper.hxx index 87cf1afbea10..5df35c7df28a 100644 --- a/include/svx/sdrhittesthelper.hxx +++ b/include/svx/sdrhittesthelper.hxx @@ -32,7 +32,11 @@ class SdrPageView; class SdrLayerIDSet; class SdrObjList; namespace sdr::contact { class ViewObjectContact; } -namespace basegfx { class B2DPoint; } +namespace basegfx +{ +class B2DPoint; +class B2DVector; +} namespace drawinglayer::primitive2d { class Primitive2DContainer; } @@ -41,7 +45,7 @@ namespace drawinglayer::primitive2d { class Primitive2DContainer; } SVXCORE_DLLPUBLIC SdrObject* SdrObjectPrimitiveHit( const SdrObject& rObject, const Point& rPnt, - sal_uInt16 nTol, + const basegfx::B2DVector& rHitTolerance, const SdrPageView& rSdrPageView, const SdrLayerIDSet* pVisiLayer, bool bTextOnly, @@ -51,7 +55,7 @@ SVXCORE_DLLPUBLIC SdrObject* SdrObjectPrimitiveHit( SVXCORE_DLLPUBLIC SdrObject* SdrObjListPrimitiveHit( const SdrObjList& rList, const Point& rPnt, - sal_uInt16 nTol, + const basegfx::B2DVector& rHitTolerance, const SdrPageView& rSdrPageView, const SdrLayerIDSet* pVisiLayer, bool bTextOnly); @@ -62,7 +66,7 @@ SVXCORE_DLLPUBLIC SdrObject* SdrObjListPrimitiveHit( bool ViewObjectContactPrimitiveHit( const sdr::contact::ViewObjectContact& rVOC, const basegfx::B2DPoint& rHitPosition, - double fLogicHitTolerance, + const basegfx::B2DVector& rLogicHitTolerance, bool bTextOnly, /// allow to get back the stack of primitives that lead to the hit drawinglayer::primitive2d::Primitive2DContainer* pHitContainer); diff --git a/sc/source/ui/drawfunc/fupoor.cxx b/sc/source/ui/drawfunc/fupoor.cxx index a10aa185b54f..4299e02512d8 100644 --- a/sc/source/ui/drawfunc/fupoor.cxx +++ b/sc/source/ui/drawfunc/fupoor.cxx @@ -196,9 +196,8 @@ bool FuPoor::IsDetectiveHit( const Point& rLogicPos ) { if (ScDetectiveFunc::IsNonAlienArrow( pObject )) { - sal_uInt16 nHitLog = static_cast<sal_uInt16>(pWindow->PixelToLogic( - Size(pView->GetHitTolerancePixel(),0)).Width()); - if(SdrObjectPrimitiveHit(*pObject, rLogicPos, nHitLog, *pPV, nullptr, false)) + double fHitLog = pWindow->PixelToLogic(Size(pView->GetHitTolerancePixel(),0)).Width(); + if(SdrObjectPrimitiveHit(*pObject, rLogicPos, {fHitLog, fHitLog}, *pPV, nullptr, false)) { bFound = true; } diff --git a/sc/source/ui/drawfunc/fusel2.cxx b/sc/source/ui/drawfunc/fusel2.cxx index 4ce7c2be290d..cc9a1478ceb4 100644 --- a/sc/source/ui/drawfunc/fusel2.cxx +++ b/sc/source/ui/drawfunc/fusel2.cxx @@ -53,9 +53,8 @@ bool FuSelection::TestDetective( const SdrPageView* pPV, const Point& rPos ) { if (ScDetectiveFunc::IsNonAlienArrow( pObject )) { - sal_uInt16 nHitLog = static_cast<sal_uInt16>(pWindow->PixelToLogic( - Size(pView->GetHitTolerancePixel(),0)).Width()); - if (SdrObjectPrimitiveHit(*pObject, rPos, nHitLog, *pPV, nullptr, false)) + double fHitLog = pWindow->PixelToLogic(Size(pView->GetHitTolerancePixel(),0)).Width(); + if (SdrObjectPrimitiveHit(*pObject, rPos, {fHitLog, fHitLog}, *pPV, nullptr, false)) { ScViewData& rViewData = rViewShell.GetViewData(); ScSplitPos ePos = rViewShell.FindWindow( pWindow ); diff --git a/sc/source/ui/unoobj/viewuno.cxx b/sc/source/ui/unoobj/viewuno.cxx index e92c45deec39..80b1e4afdac7 100644 --- a/sc/source/ui/unoobj/viewuno.cxx +++ b/sc/source/ui/unoobj/viewuno.cxx @@ -1110,15 +1110,14 @@ uno::Reference< uno::XInterface > ScTabViewObj::GetClickedObject(const Point& rP vcl::Window* pActiveWin = rData.GetActiveWin(); Point aPos = pActiveWin->PixelToLogic(rPoint); - sal_uInt16 nHitLog = static_cast<sal_uInt16>(pActiveWin->PixelToLogic( - Size(pDrawView->GetHitTolerancePixel(),0)).Width()); + double fHitLog = pActiveWin->PixelToLogic(Size(pDrawView->GetHitTolerancePixel(),0)).Width(); const size_t nCount(pDrawPage->GetObjCount()); bool bFound(false); for (size_t i = 0; i < nCount && !bFound; ++i) { SdrObject* pObj = pDrawPage->GetObj(i); - if (pObj && SdrObjectPrimitiveHit(*pObj, aPos, nHitLog, *pDrawView->GetSdrPageView(), nullptr, false)) + if (pObj && SdrObjectPrimitiveHit(*pObj, aPos, {fHitLog, fHitLog}, *pDrawView->GetSdrPageView(), nullptr, false)) { xTarget.set(pObj->getUnoShape(), uno::UNO_QUERY); bFound = true; diff --git a/sd/source/ui/func/fudraw.cxx b/sd/source/ui/func/fudraw.cxx index ed4478747e8c..fca4f65fa54e 100644 --- a/sd/source/ui/func/fudraw.cxx +++ b/sd/source/ui/func/fudraw.cxx @@ -588,8 +588,8 @@ bool FuDraw::SetPointer(const SdrObject* pObj, const Point& rPos) return false; const SdrLayerIDSet* pVisiLayer = &mpView->GetSdrPageView()->GetVisibleLayers(); - sal_uInt16 nHitLog(sal_uInt16(mpWindow->PixelToLogic(Size(HITPIX, 0)).Width())); - ::tools::Long n2HitLog(nHitLog * 2); + double fHitLog(mpWindow->PixelToLogic(Size(HITPIX, 0)).Width()); + ::tools::Long n2HitLog(fHitLog * 2); Point aHitPosR(rPos); Point aHitPosL(rPos); Point aHitPosT(rPos); @@ -601,13 +601,13 @@ bool FuDraw::SetPointer(const SdrObject* pObj, const Point& rPos) aHitPosB.AdjustY(-n2HitLog); if (!pObj->IsClosedObj() - || (SdrObjectPrimitiveHit(*pObj, aHitPosR, nHitLog, *mpView->GetSdrPageView(), pVisiLayer, + || (SdrObjectPrimitiveHit(*pObj, aHitPosR, {fHitLog, fHitLog}, *mpView->GetSdrPageView(), pVisiLayer, false) - && SdrObjectPrimitiveHit(*pObj, aHitPosL, nHitLog, *mpView->GetSdrPageView(), + && SdrObjectPrimitiveHit(*pObj, aHitPosL, {fHitLog, fHitLog}, *mpView->GetSdrPageView(), pVisiLayer, false) - && SdrObjectPrimitiveHit(*pObj, aHitPosT, nHitLog, *mpView->GetSdrPageView(), + && SdrObjectPrimitiveHit(*pObj, aHitPosT, {fHitLog, fHitLog}, *mpView->GetSdrPageView(), pVisiLayer, false) - && SdrObjectPrimitiveHit(*pObj, aHitPosB, nHitLog, *mpView->GetSdrPageView(), + && SdrObjectPrimitiveHit(*pObj, aHitPosB, {fHitLog, fHitLog}, *mpView->GetSdrPageView(), pVisiLayer, false))) { // hit inside the object (without margin) or open object diff --git a/sd/source/ui/func/fusel.cxx b/sd/source/ui/func/fusel.cxx index 4a897e7df7f2..4d7fec5f8d43 100644 --- a/sd/source/ui/func/fusel.cxx +++ b/sd/source/ui/func/fusel.cxx @@ -1237,8 +1237,8 @@ bool FuSelection::HandleImageMapClick(const SdrObject* pObj, const Point& rPos) } const SdrLayerIDSet* pVisiLayer = &mpView->GetSdrPageView()->GetVisibleLayers(); - sal_uInt16 nHitLog = sal_uInt16(mpWindow->PixelToLogic(Size(HITPIX, 0)).Width()); - const ::tools::Long n2HitLog = nHitLog * 2; + double fHitLog = mpWindow->PixelToLogic(Size(HITPIX, 0)).Width(); + const ::tools::Long n2HitLog = fHitLog * 2; Point aHitPosR(rPos); Point aHitPosL(rPos); Point aHitPosT(rPos); @@ -1250,13 +1250,13 @@ bool FuSelection::HandleImageMapClick(const SdrObject* pObj, const Point& rPos) aHitPosB.AdjustY(-n2HitLog); if (!bClosed || !bFilled - || (SdrObjectPrimitiveHit(*pObj, aHitPosR, nHitLog, *mpView->GetSdrPageView(), pVisiLayer, + || (SdrObjectPrimitiveHit(*pObj, aHitPosR, {fHitLog, fHitLog}, *mpView->GetSdrPageView(), pVisiLayer, false) - && SdrObjectPrimitiveHit(*pObj, aHitPosL, nHitLog, *mpView->GetSdrPageView(), + && SdrObjectPrimitiveHit(*pObj, aHitPosL, {fHitLog, fHitLog}, *mpView->GetSdrPageView(), pVisiLayer, false) - && SdrObjectPrimitiveHit(*pObj, aHitPosT, nHitLog, *mpView->GetSdrPageView(), + && SdrObjectPrimitiveHit(*pObj, aHitPosT, {fHitLog, fHitLog}, *mpView->GetSdrPageView(), pVisiLayer, false) - && SdrObjectPrimitiveHit(*pObj, aHitPosB, nHitLog, *mpView->GetSdrPageView(), + && SdrObjectPrimitiveHit(*pObj, aHitPosB, {fHitLog, fHitLog}, *mpView->GetSdrPageView(), pVisiLayer, false))) { if (SvxIMapInfo::GetIMapInfo(pObj)) diff --git a/sd/source/ui/view/sdview3.cxx b/sd/source/ui/view/sdview3.cxx index 06f07048455e..7065c677246b 100644 --- a/sd/source/ui/view/sdview3.cxx +++ b/sd/source/ui/view/sdview3.cxx @@ -1378,9 +1378,8 @@ bool View::InsertData( const TransferableDataHelper& rDataHelper, SfxItemSet aSet( mrDoc.GetPool() ); bool bClosed = pPickObj->IsClosedObj(); ::sd::Window* pWin = mpViewSh->GetActiveWindow(); - sal_uInt16 nHitLog = static_cast<sal_uInt16>(pWin->PixelToLogic( - Size(FuPoor::HITPIX, 0 ) ).Width()); - const ::tools::Long n2HitLog = nHitLog << 1; + double fHitLog = pWin->PixelToLogic(Size(FuPoor::HITPIX, 0 ) ).Width(); + const ::tools::Long n2HitLog = fHitLog * 2; Point aHitPosR( rPos ); Point aHitPosL( rPos ); Point aHitPosT( rPos ); @@ -1393,10 +1392,10 @@ bool View::InsertData( const TransferableDataHelper& rDataHelper, aHitPosB.AdjustY( -n2HitLog ); if( bClosed && - SdrObjectPrimitiveHit(*pPickObj, aHitPosR, nHitLog, *GetSdrPageView(), pVisiLayer, false) && - SdrObjectPrimitiveHit(*pPickObj, aHitPosL, nHitLog, *GetSdrPageView(), pVisiLayer, false) && - SdrObjectPrimitiveHit(*pPickObj, aHitPosT, nHitLog, *GetSdrPageView(), pVisiLayer, false) && - SdrObjectPrimitiveHit(*pPickObj, aHitPosB, nHitLog, *GetSdrPageView(), pVisiLayer, false) ) + SdrObjectPrimitiveHit(*pPickObj, aHitPosR, {fHitLog, fHitLog}, *GetSdrPageView(), pVisiLayer, false) && + SdrObjectPrimitiveHit(*pPickObj, aHitPosL, {fHitLog, fHitLog}, *GetSdrPageView(), pVisiLayer, false) && + SdrObjectPrimitiveHit(*pPickObj, aHitPosT, {fHitLog, fHitLog}, *GetSdrPageView(), pVisiLayer, false) && + SdrObjectPrimitiveHit(*pPickObj, aHitPosB, {fHitLog, fHitLog}, *GetSdrPageView(), pVisiLayer, false) ) { // area fill if(eFill == drawing::FillStyle_SOLID ) diff --git a/svx/source/accessibility/GraphCtlAccessibleContext.cxx b/svx/source/accessibility/GraphCtlAccessibleContext.cxx index c30756804b49..1287f7e9ea2f 100644 --- a/svx/source/accessibility/GraphCtlAccessibleContext.cxx +++ b/svx/source/accessibility/GraphCtlAccessibleContext.cxx @@ -181,7 +181,7 @@ Reference< XAccessible > SAL_CALL SvxGraphCtrlAccessibleContext::getAccessibleAt if(mpView && mpView->GetSdrPageView()) { - pObj = SdrObjListPrimitiveHit(*mpPage, aPnt, 1, *mpView->GetSdrPageView(), nullptr, false); + pObj = SdrObjListPrimitiveHit(*mpPage, aPnt, {1, 1}, *mpView->GetSdrPageView(), nullptr, false); } if( pObj ) diff --git a/svx/source/sdr/overlay/overlayobjectlist.cxx b/svx/source/sdr/overlay/overlayobjectlist.cxx index d71f6c2783b9..32e785d4011a 100644 --- a/svx/source/sdr/overlay/overlayobjectlist.cxx +++ b/svx/source/sdr/overlay/overlayobjectlist.cxx @@ -80,7 +80,7 @@ namespace sdr::overlay drawinglayer::processor2d::HitTestProcessor2D aHitTestProcessor2D( aViewInformation2D, rLogicPosition, - fLogicTolerance, + {fLogicTolerance, fLogicTolerance}, false); for(auto & pCandidate : maVector) diff --git a/svx/source/svdraw/sdrhittesthelper.cxx b/svx/source/svdraw/sdrhittesthelper.cxx index 62ebde956c73..9dc3b9118f07 100644 --- a/svx/source/svdraw/sdrhittesthelper.cxx +++ b/svx/source/svdraw/sdrhittesthelper.cxx @@ -36,7 +36,7 @@ SdrObject* SdrObjectPrimitiveHit( const SdrObject& rObject, const Point& rPnt, - sal_uInt16 nTol, + const basegfx::B2DVector& rHitTolerance, const SdrPageView& rSdrPageView, const SdrLayerIDSet* pVisiLayer, bool bTextOnly, @@ -48,7 +48,7 @@ SdrObject* SdrObjectPrimitiveHit( { // group or scene with content. Single 3D objects also have a // true == rObject.GetSubList(), but no content - pResult = SdrObjListPrimitiveHit(*rObject.GetSubList(), rPnt, nTol, rSdrPageView, pVisiLayer, bTextOnly); + pResult = SdrObjListPrimitiveHit(*rObject.GetSubList(), rPnt, rHitTolerance, rSdrPageView, pVisiLayer, bTextOnly); } else { @@ -73,12 +73,11 @@ SdrObject* SdrObjectPrimitiveHit( // with split views uses multiple PageWindows nowadays) if(rSdrPageView.PageWindowCount()) { - const double fLogicTolerance(nTol); const basegfx::B2DPoint aHitPosition(rPnt.X(), rPnt.Y()); const sdr::contact::ViewObjectContact& rVOC = rObject.GetViewContact().GetViewObjectContact( rSdrPageView.GetPageWindow(0)->GetObjectContact()); - if(ViewObjectContactPrimitiveHit(rVOC, aHitPosition, fLogicTolerance, bTextOnly, pHitContainer)) + if(ViewObjectContactPrimitiveHit(rVOC, aHitPosition, rHitTolerance, bTextOnly, pHitContainer)) { pResult = const_cast< SdrObject* >(&rObject); } @@ -94,7 +93,7 @@ SdrObject* SdrObjectPrimitiveHit( SdrObject* SdrObjListPrimitiveHit( const SdrObjList& rList, const Point& rPnt, - sal_uInt16 nTol, + const basegfx::B2DVector& rHitTolerance, const SdrPageView& rSdrPageView, const SdrLayerIDSet* pVisiLayer, bool bTextOnly) @@ -107,7 +106,7 @@ SdrObject* SdrObjListPrimitiveHit( nObjNum--; SdrObject* pObj = rList.GetObj(nObjNum); - pRetval = SdrObjectPrimitiveHit(*pObj, rPnt, nTol, rSdrPageView, pVisiLayer, bTextOnly); + pRetval = SdrObjectPrimitiveHit(*pObj, rPnt, rHitTolerance, rSdrPageView, pVisiLayer, bTextOnly); } return pRetval; @@ -117,7 +116,7 @@ SdrObject* SdrObjListPrimitiveHit( bool ViewObjectContactPrimitiveHit( const sdr::contact::ViewObjectContact& rVOC, const basegfx::B2DPoint& rHitPosition, - double fLogicHitTolerance, + const basegfx::B2DVector& rLogicHitTolerance, bool bTextOnly, drawinglayer::primitive2d::Primitive2DContainer* pHitContainer) { @@ -127,9 +126,9 @@ bool ViewObjectContactPrimitiveHit( { // first do a rough B2DRange based HitTest; do not forget to // include the HitTolerance if given - if(basegfx::fTools::more(fLogicHitTolerance, 0.0)) + if(rLogicHitTolerance.getX() > 0 || rLogicHitTolerance.getY() > 0) { - aObjectRange.grow(fLogicHitTolerance); + aObjectRange.grow(rLogicHitTolerance); } if(aObjectRange.isInside(rHitPosition)) @@ -146,7 +145,7 @@ bool ViewObjectContactPrimitiveHit( drawinglayer::processor2d::HitTestProcessor2D aHitTestProcessor2D( rViewInformation2D, rHitPosition, - fLogicHitTolerance, + rLogicHitTolerance, bTextOnly); // ask for HitStack diff --git a/svx/source/svdraw/svdetc.cxx b/svx/source/svdraw/svdetc.cxx index acd15f7cc265..feb879f27c5d 100644 --- a/svx/source/svdraw/svdetc.cxx +++ b/svx/source/svdraw/svdetc.cxx @@ -504,7 +504,7 @@ namespace && (!bMaster || (!pObj->IsNotVisibleAsMaster() && 0 != no)) && pObj->GetCurrentBoundRect().Contains(rPnt) && !pText->IsHideContour() - && SdrObjectPrimitiveHit(*pObj, rPnt, 0, rTextEditPV, &rVisLayers, false)) + && SdrObjectPrimitiveHit(*pObj, rPnt, {0, 0}, rTextEditPV, &rVisLayers, false)) { bRet = GetDraftFillColor(pObj->GetMergedItemSet(), rCol); } diff --git a/svx/source/svdraw/svdmrkv.cxx b/svx/source/svdraw/svdmrkv.cxx index 7a623dca9c92..5b8a86a9526d 100644 --- a/svx/source/svdraw/svdmrkv.cxx +++ b/svx/source/svdraw/svdmrkv.cxx @@ -2323,7 +2323,7 @@ SdrObject* SdrMarkView::CheckSingleSdrObjectHit(const Point& rPnt, sal_uInt16 nT basegfx::fround(aGridOffset.getY())); } - sal_uInt16 nTol2(nTol); + double nTol2(nTol); // double tolerance for OLE, text frames and objects in // active text edit @@ -2361,7 +2361,7 @@ SdrObject* SdrMarkView::CheckSingleSdrObjectHit(const Point& rPnt, sal_uInt16 nT { if(!pMVisLay || pMVisLay->IsSet(pObj->GetLayer())) { - pRet = SdrObjectPrimitiveHit(*pObj, rPnt, nTol2, *pPV, &pPV->GetVisibleLayers(), false); + pRet = SdrObjectPrimitiveHit(*pObj, rPnt, {nTol2, nTol2}, *pPV, &pPV->GetVisibleLayers(), false); } } } diff --git a/svx/source/svdraw/svdobj.cxx b/svx/source/svdraw/svdobj.cxx index 77a78035cdda..5c7789ee7ed0 100644 --- a/svx/source/svdraw/svdobj.cxx +++ b/svx/source/svdraw/svdobj.cxx @@ -1853,7 +1853,7 @@ SdrObject* SdrObject::CheckMacroHit(const SdrObjMacroHitRec& rRec) const { if(rRec.pPageView) { - return SdrObjectPrimitiveHit(*this, rRec.aPos, rRec.nTol, *rRec.pPageView, rRec.pVisiLayer, false); + return SdrObjectPrimitiveHit(*this, rRec.aPos, {static_cast<double>(rRec.nTol), static_cast<double>(rRec.nTol)}, *rRec.pPageView, rRec.pVisiLayer, false); } return nullptr; diff --git a/svx/source/svdraw/svdocapt.cxx b/svx/source/svdraw/svdocapt.cxx index 14e7678499c7..98c86664c28a 100644 --- a/svx/source/svdraw/svdocapt.cxx +++ b/svx/source/svdraw/svdocapt.cxx @@ -312,7 +312,7 @@ bool SdrCaptionObj::beginSpecialDrag(SdrDragStat& rDrag) const Point aHit(rDrag.GetStart()); - if(rDrag.GetPageView() && SdrObjectPrimitiveHit(*this, aHit, 0, *rDrag.GetPageView(), nullptr, false)) + if(rDrag.GetPageView() && SdrObjectPrimitiveHit(*this, aHit, {0, 0}, *rDrag.GetPageView(), nullptr, false)) { return true; } diff --git a/svx/source/svdraw/svdoedge.cxx b/svx/source/svdraw/svdoedge.cxx index d63c837f6e90..be203714bddd 100644 --- a/svx/source/svdraw/svdoedge.cxx +++ b/svx/source/svdraw/svdoedge.cxx @@ -2155,7 +2155,7 @@ bool SdrEdgeObj::ImpFindConnector(const Point& rPt, const SdrPageView& rPV, SdrO aMouseRect.AdjustTop( -(aHalfConSiz.Height()) ); aMouseRect.AdjustRight(aHalfConSiz.Width() ); aMouseRect.AdjustBottom(aHalfConSiz.Height() ); - sal_uInt16 nBoundHitTol=static_cast<sal_uInt16>(aHalfConSiz.Width())/2; if (nBoundHitTol==0) nBoundHitTol=1; + double fBoundHitTol=static_cast<double>(aHalfConSiz.Width())/2; if (fBoundHitTol==0.0) fBoundHitTol=1.0; size_t no=pOL->GetObjCount(); bool bFnd = false; SdrObjConnection aTestCon; @@ -2249,7 +2249,7 @@ bool SdrEdgeObj::ImpFindConnector(const Point& rPt, const SdrPageView& rPV, SdrO // if no connector is hit, try HitTest again, for BestConnector (=bCenter) if(!bFnd && !bEdge && - SdrObjectPrimitiveHit(*pObj, rPt, nBoundHitTol, rPV, &rVisLayer, false)) + SdrObjectPrimitiveHit(*pObj, rPt, {fBoundHitTol, fBoundHitTol}, rPV, &rVisLayer, false)) { // Suppress default connect at object inside bound if(!pThis || !pThis->GetSuppressDefaultConnect()) @@ -2260,10 +2260,10 @@ bool SdrEdgeObj::ImpFindConnector(const Point& rPt, const SdrPageView& rPV, SdrO } } if (bFnd) { - aMouseRect.AdjustLeft( -nBoundHitTol ); - aMouseRect.AdjustTop( -nBoundHitTol ); - aMouseRect.AdjustRight(nBoundHitTol ); - aMouseRect.AdjustBottom(nBoundHitTol ); + aMouseRect.AdjustLeft( -fBoundHitTol ); + aMouseRect.AdjustTop( -fBoundHitTol ); + aMouseRect.AdjustRight(fBoundHitTol ); + aMouseRect.AdjustBottom(fBoundHitTol ); } } diff --git a/svx/source/svdraw/svdview.cxx b/svx/source/svdraw/svdview.cxx index 06680bd5eecc..d6a203ae3ccb 100644 --- a/svx/source/svdraw/svdview.cxx +++ b/svx/source/svdraw/svdview.cxx @@ -449,7 +449,7 @@ SdrHitKind SdrView::PickAnything(const Point& rLogicPos, SdrViewEvent& rVEvt) co // includes grouping primitives (like TextHierarchyPrimitives we deed here) // but also all decomposed ones which lead to the creation of that primitive drawinglayer::primitive2d::Primitive2DContainer aHitContainer; - const bool bTEHit(pPV && SdrObjectPrimitiveHit(*pTextObj, aLocalLogicPosition, 0, *pPV, &pPV->GetVisibleLayers(), true, &aHitContainer)); + const bool bTEHit(pPV && SdrObjectPrimitiveHit(*pTextObj, aLocalLogicPosition, {0, 0}, *pPV, &pPV->GetVisibleLayers(), true, &aHitContainer)); if (bTEHit && !aHitContainer.empty()) { @@ -514,13 +514,21 @@ SdrHitKind SdrView::PickAnything(const Point& rLogicPos, SdrViewEvent& rVEvt) co (eHit==SdrHitKind::MarkedObject || eHit==SdrHitKind::UnmarkedObject) && (IsTextTool() || (IsEditMode() && IsQuickTextEditMode())) && pHitObj->HasTextEdit()) { + auto pTextObj = DynCastSdrTextObj(pHitObj); + // Around the TextEditArea there's a border to select without going into text edit mode. - tools::Rectangle aBoundRect(pHitObj->GetCurrentBoundRect()); + tools::Rectangle aBoundRect; + const GeoStat& rGeo = pTextObj->GetGeoStat(); + if (pTextObj && !rGeo.m_nRotationAngle && !rGeo.m_nShearAngle) + { + pTextObj->TakeTextEditArea(nullptr, nullptr, &aBoundRect, nullptr); + } + else + aBoundRect = pHitObj->GetCurrentBoundRect(); // Force to SnapRect when Fontwork - if( auto pTextObj = DynCastSdrTextObj(pHitObj) ) - if( pTextObj->IsFontwork() ) - aBoundRect = pHitObj->GetSnapRect(); + if( pTextObj && pTextObj->IsFontwork() ) + aBoundRect = pHitObj->GetSnapRect(); sal_Int32 nTolerance(mnHitTolLog); bool bBoundRectHit(false); @@ -538,10 +546,11 @@ SdrHitKind SdrView::PickAnything(const Point& rLogicPos, SdrViewEvent& rVEvt) co bBoundRectHit = true; } - if(!bBoundRectHit) + if(!bBoundRectHit && aBoundRect.Contains(aLocalLogicPosition)) { - bool bTEHit(pPV && - SdrObjectPrimitiveHit(*pHitObj, aLocalLogicPosition, 0, *pPV, &pPV->GetVisibleLayers(), true)); + bool bTEHit(pPV + && SdrObjectPrimitiveHit(*pHitObj, aLocalLogicPosition, { 2000.0, 0.0 }, + *pPV, &pPV->GetVisibleLayers(), true)); // TextEdit attached to an object in a locked layer if (bTEHit && pPV->GetLockedLayers().IsSet(pHitObj->GetLayer()))