| /************************************************************** |
| * |
| * 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 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_svx.hxx" |
| |
| #include <algorithm> |
| |
| #include <svx/svdhdl.hxx> |
| #include <svx/svdpagv.hxx> |
| #include <svx/svdetc.hxx> |
| #include <svx/svdmrkv.hxx> |
| #include <vcl/window.hxx> |
| |
| #include <vcl/virdev.hxx> |
| #include <tools/poly.hxx> |
| #include <vcl/bmpacc.hxx> |
| |
| #include <svx/sxekitm.hxx> |
| #include "svx/svdstr.hrc" |
| #include "svx/svdglob.hxx" |
| |
| #include <svx/svdmodel.hxx> |
| #include "gradtrns.hxx" |
| #include <svx/xflgrit.hxx> |
| #include <svx/svdundo.hxx> |
| #include <svx/dialmgr.hxx> |
| #include <svx/xflftrit.hxx> |
| |
| // #105678# |
| #include <svx/svdopath.hxx> |
| #include <basegfx/vector/b2dvector.hxx> |
| #include <basegfx/polygon/b2dpolygon.hxx> |
| #include <svx/sdr/overlay/overlaymanager.hxx> |
| #include <svx/sdr/overlay/overlayanimatedbitmapex.hxx> |
| #include <svx/sdr/overlay/overlaybitmapex.hxx> |
| #include <svx/sdr/overlay/overlayline.hxx> |
| #include <svx/sdr/overlay/overlaytriangle.hxx> |
| #include <svx/sdr/overlay/overlayrectangle.hxx> |
| #include <svx/sdrpagewindow.hxx> |
| #include <svx/sdrpaintwindow.hxx> |
| #include <vcl/svapp.hxx> |
| #include <svx/sdr/overlay/overlaypolypolygon.hxx> |
| #include <vcl/lazydelete.hxx> |
| |
| #include <basegfx/polygon/b2dpolygontools.hxx> |
| #include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx> |
| #include <svx/sdr/overlay/overlayprimitive2dsequenceobject.hxx> |
| #include <drawinglayer/primitive2d/graphicprimitive2d.hxx> |
| #include <drawinglayer/primitive2d/maskprimitive2d.hxx> |
| #include <drawinglayer/primitive2d/unifiedtransparenceprimitive2d.hxx> |
| #include <drawinglayer/primitive2d/polygonprimitive2d.hxx> |
| |
| //////////////////////////////////////////////////////////////////////////////////////////////////// |
| // #i15222# |
| // Due to the ressource problems in Win95/98 with bitmap ressources i |
| // will change this handle bitmap provinging class. Old version was splitting |
| // and preparing all small handle bitmaps in device bitmap format, now this will |
| // be done on the fly. Thus, tehre is only the one big bitmap remembered. With |
| // three source bitmaps, this will be 3 system bitmap ressources instead of hundreds. |
| // The price for that needs to be evaluated. Maybe we will need another change here |
| // if this is too expensive. |
| class SdrHdlBitmapSet |
| { |
| // the bitmap holding all infos |
| BitmapEx maMarkersBitmap; |
| |
| // the cropped Bitmaps for reusage |
| ::std::vector< BitmapEx > maRealMarkers; |
| |
| // elpers |
| BitmapEx& impGetOrCreateTargetBitmap(sal_uInt16 nIndex, const Rectangle& rRectangle); |
| |
| public: |
| SdrHdlBitmapSet(sal_uInt16 nResId); |
| ~SdrHdlBitmapSet(); |
| |
| const BitmapEx& GetBitmapEx(BitmapMarkerKind eKindOfMarker, sal_uInt16 nInd=0); |
| }; |
| |
| //////////////////////////////////////////////////////////////////////////////////////////////////// |
| #define KIND_COUNT (14) |
| #define INDEX_COUNT (6) |
| #define INDIVIDUAL_COUNT (4) |
| |
| SdrHdlBitmapSet::SdrHdlBitmapSet(sal_uInt16 nResId) |
| : maMarkersBitmap(ResId(nResId, *ImpGetResMgr())), // just use ressource with alpha channel |
| // 14 kinds (BitmapMarkerKind) use index [0..5], 4 extra |
| maRealMarkers((KIND_COUNT * INDEX_COUNT) + INDIVIDUAL_COUNT) |
| { |
| } |
| |
| SdrHdlBitmapSet::~SdrHdlBitmapSet() |
| { |
| } |
| |
| BitmapEx& SdrHdlBitmapSet::impGetOrCreateTargetBitmap(sal_uInt16 nIndex, const Rectangle& rRectangle) |
| { |
| BitmapEx& rTargetBitmap = maRealMarkers[nIndex]; |
| |
| if(rTargetBitmap.IsEmpty()) |
| { |
| rTargetBitmap = maMarkersBitmap; |
| rTargetBitmap.Crop(rRectangle); |
| } |
| |
| return rTargetBitmap; |
| } |
| |
| // change getting of bitmap to use the big ressource bitmap |
| const BitmapEx& SdrHdlBitmapSet::GetBitmapEx(BitmapMarkerKind eKindOfMarker, sal_uInt16 nInd) |
| { |
| // fill in size and source position in maMarkersBitmap |
| const sal_uInt16 nYPos(nInd * 11); |
| |
| switch(eKindOfMarker) |
| { |
| default: |
| { |
| DBG_ERROR( "unknown kind of marker" ); |
| // no break here, return Rect_7x7 as default |
| } |
| case Rect_7x7: |
| { |
| return impGetOrCreateTargetBitmap((0 * INDEX_COUNT) + nInd, Rectangle(Point(0, nYPos), Size(7, 7))); |
| } |
| |
| case Rect_9x9: |
| { |
| return impGetOrCreateTargetBitmap((1 * INDEX_COUNT) + nInd, Rectangle(Point(7, nYPos), Size(9, 9))); |
| } |
| |
| case Rect_11x11: |
| { |
| return impGetOrCreateTargetBitmap((2 * INDEX_COUNT) + nInd, Rectangle(Point(16, nYPos), Size(11, 11))); |
| } |
| |
| case Rect_13x13: |
| { |
| const sal_uInt16 nIndex((3 * INDEX_COUNT) + nInd); |
| |
| switch(nInd) |
| { |
| case 0: |
| { |
| return impGetOrCreateTargetBitmap(nIndex, Rectangle(Point(72, 66), Size(13, 13))); |
| } |
| case 1: |
| { |
| return impGetOrCreateTargetBitmap(nIndex, Rectangle(Point(85, 66), Size(13, 13))); |
| } |
| case 2: |
| { |
| return impGetOrCreateTargetBitmap(nIndex, Rectangle(Point(72, 79), Size(13, 13))); |
| } |
| case 3: |
| { |
| return impGetOrCreateTargetBitmap(nIndex, Rectangle(Point(85, 79), Size(13, 13))); |
| } |
| case 4: |
| { |
| return impGetOrCreateTargetBitmap(nIndex, Rectangle(Point(98, 79), Size(13, 13))); |
| } |
| default: // case 5: |
| { |
| return impGetOrCreateTargetBitmap(nIndex, Rectangle(Point(98, 66), Size(13, 13))); |
| } |
| } |
| } |
| |
| case Circ_7x7: |
| case Customshape_7x7: |
| { |
| return impGetOrCreateTargetBitmap((4 * INDEX_COUNT) + nInd, Rectangle(Point(27, nYPos), Size(7, 7))); |
| } |
| |
| case Circ_9x9: |
| case Customshape_9x9: |
| { |
| return impGetOrCreateTargetBitmap((5 * INDEX_COUNT) + nInd, Rectangle(Point(34, nYPos), Size(9, 9))); |
| } |
| |
| case Circ_11x11: |
| case Customshape_11x11: |
| { |
| return impGetOrCreateTargetBitmap((6 * INDEX_COUNT) + nInd, Rectangle(Point(43, nYPos), Size(11, 11))); |
| } |
| |
| case Elli_7x9: |
| { |
| return impGetOrCreateTargetBitmap((7 * INDEX_COUNT) + nInd, Rectangle(Point(54, nYPos), Size(7, 9))); |
| } |
| |
| case Elli_9x11: |
| { |
| return impGetOrCreateTargetBitmap((8 * INDEX_COUNT) + nInd, Rectangle(Point(61, nYPos), Size(9, 11))); |
| } |
| |
| case Elli_9x7: |
| { |
| return impGetOrCreateTargetBitmap((9 * INDEX_COUNT) + nInd, Rectangle(Point(70, nYPos), Size(9, 7))); |
| } |
| |
| case Elli_11x9: |
| { |
| return impGetOrCreateTargetBitmap((10 * INDEX_COUNT) + nInd, Rectangle(Point(79, nYPos), Size(11, 9))); |
| } |
| |
| case RectPlus_7x7: |
| { |
| return impGetOrCreateTargetBitmap((11 * INDEX_COUNT) + nInd, Rectangle(Point(90, nYPos), Size(7, 7))); |
| } |
| |
| case RectPlus_9x9: |
| { |
| return impGetOrCreateTargetBitmap((12 * INDEX_COUNT) + nInd, Rectangle(Point(97, nYPos), Size(9, 9))); |
| } |
| |
| case RectPlus_11x11: |
| { |
| return impGetOrCreateTargetBitmap((13 * INDEX_COUNT) + nInd, Rectangle(Point(106, nYPos), Size(11, 11))); |
| } |
| |
| case Crosshair: |
| { |
| return impGetOrCreateTargetBitmap((KIND_COUNT * INDEX_COUNT) + 0, Rectangle(Point(0, 68), Size(15, 15))); |
| } |
| |
| case Glue: |
| { |
| return impGetOrCreateTargetBitmap((KIND_COUNT * INDEX_COUNT) + 1, Rectangle(Point(15, 74), Size(9, 9))); |
| } |
| |
| case Anchor: // #101688# AnchorTR for SW |
| case AnchorTR: |
| { |
| return impGetOrCreateTargetBitmap((KIND_COUNT * INDEX_COUNT) + 2, Rectangle(Point(24, 68), Size(24, 24))); |
| } |
| |
| // #98388# add AnchorPressed to be able to aninate anchor control |
| case AnchorPressed: |
| case AnchorPressedTR: |
| { |
| return impGetOrCreateTargetBitmap((KIND_COUNT * INDEX_COUNT) + 3, Rectangle(Point(48, 68), Size(24, 24))); |
| } |
| } |
| |
| // cannot happen since all pathes return something; return Rect_7x7 as default (see switch) |
| return maRealMarkers[0]; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////////////////////////// |
| |
| SdrHdlBitmapSet& getSimpleSet() |
| { |
| static vcl::DeleteOnDeinit< SdrHdlBitmapSet > aSimpleSet(new SdrHdlBitmapSet(SIP_SA_MARKERS)); |
| return *aSimpleSet.get(); |
| } |
| |
| SdrHdlBitmapSet& getModernSet() |
| { |
| static vcl::DeleteOnDeinit< SdrHdlBitmapSet > aModernSet(new SdrHdlBitmapSet(SIP_SA_FINE_MARKERS)); |
| return *aModernSet.get(); |
| } |
| |
| SdrHdlBitmapSet& getHighContrastSet() |
| { |
| static vcl::DeleteOnDeinit< SdrHdlBitmapSet > aHighContrastSet(new SdrHdlBitmapSet(SIP_SA_ACCESSIBILITY_MARKERS)); |
| return *aHighContrastSet.get(); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////////////////////////// |
| |
| SdrHdl::SdrHdl(): |
| pObj(NULL), |
| pPV(NULL), |
| pHdlList(NULL), |
| eKind(HDL_MOVE), |
| nDrehWink(0), |
| nObjHdlNum(0), |
| nPolyNum(0), |
| nPPntNum(0), |
| nSourceHdlNum(0), |
| bSelect(sal_False), |
| b1PixMore(sal_False), |
| bPlusHdl(sal_False), |
| mbMoveOutside(false), |
| mbMouseOver(false) |
| { |
| } |
| |
| SdrHdl::SdrHdl(const Point& rPnt, SdrHdlKind eNewKind): |
| pObj(NULL), |
| pPV(NULL), |
| pHdlList(NULL), |
| aPos(rPnt), |
| eKind(eNewKind), |
| nDrehWink(0), |
| nObjHdlNum(0), |
| nPolyNum(0), |
| nPPntNum(0), |
| nSourceHdlNum(0), |
| bSelect(sal_False), |
| b1PixMore(sal_False), |
| bPlusHdl(sal_False), |
| mbMoveOutside(false), |
| mbMouseOver(false) |
| { |
| } |
| |
| SdrHdl::~SdrHdl() |
| { |
| GetRidOfIAObject(); |
| } |
| |
| void SdrHdl::Set1PixMore(sal_Bool bJa) |
| { |
| if(b1PixMore != bJa) |
| { |
| b1PixMore = bJa; |
| |
| // create new display |
| Touch(); |
| } |
| } |
| |
| void SdrHdl::SetMoveOutside( bool bMoveOutside ) |
| { |
| if(mbMoveOutside != bMoveOutside) |
| { |
| mbMoveOutside = bMoveOutside; |
| |
| // create new display |
| Touch(); |
| } |
| } |
| |
| void SdrHdl::SetDrehWink(long n) |
| { |
| if(nDrehWink != n) |
| { |
| nDrehWink = n; |
| |
| // create new display |
| Touch(); |
| } |
| } |
| |
| void SdrHdl::SetPos(const Point& rPnt) |
| { |
| if(aPos != rPnt) |
| { |
| // remember new position |
| aPos = rPnt; |
| |
| // create new display |
| Touch(); |
| } |
| } |
| |
| void SdrHdl::SetSelected(sal_Bool bJa) |
| { |
| if(bSelect != bJa) |
| { |
| // remember new value |
| bSelect = bJa; |
| |
| // create new display |
| Touch(); |
| } |
| } |
| |
| void SdrHdl::SetHdlList(SdrHdlList* pList) |
| { |
| if(pHdlList != pList) |
| { |
| // rememver list |
| pHdlList = pList; |
| |
| // now its possible to create graphic representation |
| Touch(); |
| } |
| } |
| |
| void SdrHdl::SetObj(SdrObject* pNewObj) |
| { |
| if(pObj != pNewObj) |
| { |
| // remember new object |
| pObj = pNewObj; |
| |
| // graphic representation may have changed |
| Touch(); |
| } |
| } |
| |
| void SdrHdl::Touch() |
| { |
| // force update of graphic representation |
| CreateB2dIAObject(); |
| } |
| |
| void SdrHdl::GetRidOfIAObject() |
| { |
| //OLMaIAOGroup.Delete(); |
| |
| // OVERLAYMANAGER |
| maOverlayGroup.clear(); |
| } |
| |
| void SdrHdl::CreateB2dIAObject() |
| { |
| // first throw away old one |
| GetRidOfIAObject(); |
| |
| if(pHdlList && pHdlList->GetView() && !pHdlList->GetView()->areMarkHandlesHidden()) |
| { |
| BitmapColorIndex eColIndex = LightGreen; |
| BitmapMarkerKind eKindOfMarker = Rect_7x7; |
| |
| sal_Bool bRot = pHdlList->IsRotateShear(); |
| if(pObj) |
| eColIndex = (bSelect) ? Cyan : LightCyan; |
| if(bRot) |
| { |
| // Drehhandles in Rot |
| if(pObj && bSelect) |
| eColIndex = Red; |
| else |
| eColIndex = LightRed; |
| } |
| |
| switch(eKind) |
| { |
| case HDL_MOVE: |
| { |
| eKindOfMarker = (b1PixMore) ? Rect_9x9 : Rect_7x7; |
| break; |
| } |
| case HDL_UPLFT: |
| case HDL_UPRGT: |
| case HDL_LWLFT: |
| case HDL_LWRGT: |
| { |
| // corner handles |
| if(bRot) |
| { |
| eKindOfMarker = Circ_7x7; |
| } |
| else |
| { |
| eKindOfMarker = Rect_7x7; |
| } |
| break; |
| } |
| case HDL_UPPER: |
| case HDL_LOWER: |
| { |
| // Upper/Lower handles |
| if(bRot) |
| { |
| eKindOfMarker = Elli_9x7; |
| } |
| else |
| { |
| eKindOfMarker = Rect_7x7; |
| } |
| break; |
| } |
| case HDL_LEFT: |
| case HDL_RIGHT: |
| { |
| // Left/Right handles |
| if(bRot) |
| { |
| eKindOfMarker = Elli_7x9; |
| } |
| else |
| { |
| eKindOfMarker = Rect_7x7; |
| } |
| break; |
| } |
| case HDL_POLY: |
| { |
| if(bRot) |
| { |
| eKindOfMarker = (b1PixMore) ? Circ_9x9 : Circ_7x7; |
| } |
| else |
| { |
| eKindOfMarker = (b1PixMore) ? Rect_9x9 : Rect_7x7; |
| } |
| break; |
| } |
| case HDL_BWGT: // weight at poly |
| { |
| eKindOfMarker = Circ_7x7; |
| break; |
| } |
| case HDL_CIRC: |
| { |
| eKindOfMarker = Rect_11x11; |
| break; |
| } |
| case HDL_REF1: |
| case HDL_REF2: |
| { |
| eKindOfMarker = Crosshair; |
| break; |
| } |
| case HDL_GLUE: |
| { |
| eKindOfMarker = Glue; |
| break; |
| } |
| case HDL_ANCHOR: |
| { |
| eKindOfMarker = Anchor; |
| break; |
| } |
| case HDL_USER: |
| { |
| break; |
| } |
| // #101688# top right anchor for SW |
| case HDL_ANCHOR_TR: |
| { |
| eKindOfMarker = AnchorTR; |
| break; |
| } |
| |
| // for SJ and the CustomShapeHandles: |
| case HDL_CUSTOMSHAPE1: |
| { |
| eKindOfMarker = (b1PixMore) ? Customshape_9x9 : Customshape_7x7; |
| eColIndex = Yellow; |
| break; |
| } |
| default: |
| break; |
| } |
| |
| SdrMarkView* pView = pHdlList->GetView(); |
| SdrPageView* pPageView = pView->GetSdrPageView(); |
| |
| if(pPageView) |
| { |
| for(sal_uInt32 b(0L); b < pPageView->PageWindowCount(); b++) |
| { |
| // const SdrPageViewWinRec& rPageViewWinRec = rPageViewWinList[b]; |
| const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b); |
| |
| if(rPageWindow.GetPaintWindow().OutputToWindow()) |
| { |
| Point aMoveOutsideOffset(0, 0); |
| |
| // add offset if necessary |
| if(pHdlList->IsMoveOutside() || mbMoveOutside) |
| { |
| OutputDevice& rOutDev = rPageWindow.GetPaintWindow().GetOutputDevice(); |
| Size aOffset = rOutDev.PixelToLogic(Size(4, 4)); |
| |
| if(eKind == HDL_UPLFT || eKind == HDL_UPPER || eKind == HDL_UPRGT) |
| aMoveOutsideOffset.Y() -= aOffset.Width(); |
| if(eKind == HDL_LWLFT || eKind == HDL_LOWER || eKind == HDL_LWRGT) |
| aMoveOutsideOffset.Y() += aOffset.Height(); |
| if(eKind == HDL_UPLFT || eKind == HDL_LEFT || eKind == HDL_LWLFT) |
| aMoveOutsideOffset.X() -= aOffset.Width(); |
| if(eKind == HDL_UPRGT || eKind == HDL_RIGHT || eKind == HDL_LWRGT) |
| aMoveOutsideOffset.X() += aOffset.Height(); |
| } |
| |
| if(rPageWindow.GetOverlayManager()) |
| { |
| basegfx::B2DPoint aPosition(aPos.X(), aPos.Y()); |
| ::sdr::overlay::OverlayObject* pNewOverlayObject = CreateOverlayObject( |
| aPosition, |
| eColIndex, |
| eKindOfMarker, |
| aMoveOutsideOffset); |
| |
| // OVERLAYMANAGER |
| if(pNewOverlayObject) |
| { |
| rPageWindow.GetOverlayManager()->add(*pNewOverlayObject); |
| maOverlayGroup.append(*pNewOverlayObject); |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| BitmapMarkerKind SdrHdl::GetNextBigger(BitmapMarkerKind eKnd) const |
| { |
| BitmapMarkerKind eRetval(eKnd); |
| |
| switch(eKnd) |
| { |
| case Rect_7x7: eRetval = Rect_9x9; break; |
| case Rect_9x9: eRetval = Rect_11x11; break; |
| case Rect_11x11: eRetval = Rect_13x13; break; |
| //case Rect_13x13: eRetval = ; break; |
| |
| case Circ_7x7: eRetval = Circ_9x9; break; |
| case Circ_9x9: eRetval = Circ_11x11; break; |
| //case Circ_11x11: eRetval = ; break; |
| |
| case Customshape_7x7: eRetval = Customshape_9x9; break; |
| case Customshape_9x9: eRetval = Customshape_11x11; break; |
| //case Customshape_11x11: eRetval = ; break; |
| |
| case Elli_7x9: eRetval = Elli_9x11; break; |
| //case Elli_9x11: eRetval = ; break; |
| |
| case Elli_9x7: eRetval = Elli_11x9; break; |
| //case Elli_11x9: eRetval = ; break; |
| |
| case RectPlus_7x7: eRetval = RectPlus_9x9; break; |
| case RectPlus_9x9: eRetval = RectPlus_11x11; break; |
| //case RectPlus_11x11: eRetval = ; break; |
| |
| //case Crosshair: eRetval = ; break; |
| //case Glue: eRetval = ; break; |
| |
| // #98388# let anchor blink with it's pressed state |
| case Anchor: eRetval = AnchorPressed; break; |
| |
| // #101688# same for AnchorTR |
| case AnchorTR: eRetval = AnchorPressedTR; break; |
| default: |
| break; |
| } |
| |
| return eRetval; |
| } |
| |
| // #101928# |
| BitmapEx SdrHdl::ImpGetBitmapEx(BitmapMarkerKind eKindOfMarker, sal_uInt16 nInd, sal_Bool bFine, sal_Bool bIsHighContrast) |
| { |
| if(bIsHighContrast) |
| { |
| return getHighContrastSet().GetBitmapEx(eKindOfMarker, nInd); |
| } |
| else |
| { |
| if(bFine) |
| { |
| return getModernSet().GetBitmapEx(eKindOfMarker, nInd); |
| } |
| else |
| { |
| return getSimpleSet().GetBitmapEx(eKindOfMarker, nInd); |
| } |
| } |
| } |
| |
| ::sdr::overlay::OverlayObject* SdrHdl::CreateOverlayObject( |
| const basegfx::B2DPoint& rPos, |
| BitmapColorIndex eColIndex, BitmapMarkerKind eKindOfMarker, Point aMoveOutsideOffset) |
| { |
| ::sdr::overlay::OverlayObject* pRetval = 0L; |
| sal_Bool bIsFineHdl(pHdlList->IsFineHdl()); |
| const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings(); |
| sal_Bool bIsHighContrast(rStyleSettings.GetHighContrastMode()); |
| |
| // support bigger sizes |
| sal_Bool bForceBiggerSize(sal_False); |
| |
| if(pHdlList->GetHdlSize() > 3) |
| { |
| switch(eKindOfMarker) |
| { |
| case Anchor: |
| case AnchorPressed: |
| case AnchorTR: |
| case AnchorPressedTR: |
| { |
| // #121463# For anchor, do not simply make bigger because of HdlSize, |
| // do it dependent of IsSelected() which Writer can set in drag mode |
| if(IsSelected()) |
| { |
| bForceBiggerSize = sal_True; |
| } |
| break; |
| } |
| default: |
| { |
| bForceBiggerSize = sal_True; |
| break; |
| } |
| } |
| } |
| |
| // #101928# ...for high contrast, too. |
| if(!bForceBiggerSize && bIsHighContrast) |
| { |
| // #107925# |
| // ...but not for anchors, else they will not blink when activated |
| if(Anchor != eKindOfMarker && AnchorTR != eKindOfMarker) |
| { |
| bForceBiggerSize = sal_True; |
| } |
| } |
| |
| if(bForceBiggerSize) |
| { |
| eKindOfMarker = GetNextBigger(eKindOfMarker); |
| } |
| |
| // #97016# II This handle has the focus, visualize it |
| if(IsFocusHdl() && pHdlList && pHdlList->GetFocusHdl() == this) |
| { |
| // create animated handle |
| BitmapMarkerKind eNextBigger = GetNextBigger(eKindOfMarker); |
| |
| if(eNextBigger == eKindOfMarker) |
| { |
| // this may happen for the not supported getting-bigger types. |
| // Choose an alternative here |
| switch(eKindOfMarker) |
| { |
| case Rect_13x13: eNextBigger = Rect_11x11; break; |
| case Circ_11x11: eNextBigger = Elli_11x9; break; |
| case Elli_9x11: eNextBigger = Elli_11x9; break; |
| case Elli_11x9: eNextBigger = Elli_9x11; break; |
| case RectPlus_11x11: eNextBigger = Rect_13x13; break; |
| |
| case Crosshair: |
| eNextBigger = Glue; |
| break; |
| |
| case Glue: |
| eNextBigger = Crosshair; |
| break; |
| default: |
| break; |
| } |
| } |
| |
| // create animated hdl |
| // #101928# use ImpGetBitmapEx(...) now |
| BitmapEx aBmpEx1 = ImpGetBitmapEx(eKindOfMarker, (sal_uInt16)eColIndex, bIsFineHdl, bIsHighContrast); |
| BitmapEx aBmpEx2 = ImpGetBitmapEx(eNextBigger, (sal_uInt16)eColIndex, bIsFineHdl, bIsHighContrast); |
| |
| // #i53216# Use system cursor blink time. Use the unsigned value. |
| const sal_uInt32 nBlinkTime((sal_uInt32)Application::GetSettings().GetStyleSettings().GetCursorBlinkTime()); |
| |
| if(eKindOfMarker == Anchor || eKindOfMarker == AnchorPressed) |
| { |
| // #98388# when anchor is used take upper left as reference point inside the handle |
| pRetval = new ::sdr::overlay::OverlayAnimatedBitmapEx(rPos, aBmpEx1, aBmpEx2, nBlinkTime); |
| } |
| else if(eKindOfMarker == AnchorTR || eKindOfMarker == AnchorPressedTR) |
| { |
| // #101688# AnchorTR for SW, take top right as (0,0) |
| pRetval = new ::sdr::overlay::OverlayAnimatedBitmapEx(rPos, aBmpEx1, aBmpEx2, nBlinkTime, |
| (sal_uInt16)(aBmpEx1.GetSizePixel().Width() - 1), 0, |
| (sal_uInt16)(aBmpEx2.GetSizePixel().Width() - 1), 0); |
| } |
| else |
| { |
| // create centered handle as default |
| pRetval = new ::sdr::overlay::OverlayAnimatedBitmapEx(rPos, aBmpEx1, aBmpEx2, nBlinkTime, |
| (sal_uInt16)(aBmpEx1.GetSizePixel().Width() - 1) >> 1, |
| (sal_uInt16)(aBmpEx1.GetSizePixel().Height() - 1) >> 1, |
| (sal_uInt16)(aBmpEx2.GetSizePixel().Width() - 1) >> 1, |
| (sal_uInt16)(aBmpEx2.GetSizePixel().Height() - 1) >> 1); |
| } |
| } |
| else |
| { |
| // create normal handle |
| // #101928# use ImpGetBitmapEx(...) now |
| BitmapEx aBmpEx = ImpGetBitmapEx(eKindOfMarker, (sal_uInt16)eColIndex, bIsFineHdl, bIsHighContrast); |
| |
| if(eKindOfMarker == Anchor || eKindOfMarker == AnchorPressed) |
| { |
| // #98388# upper left as reference point inside the handle for AnchorPressed, too |
| pRetval = new ::sdr::overlay::OverlayBitmapEx(rPos, aBmpEx); |
| } |
| else if(eKindOfMarker == AnchorTR || eKindOfMarker == AnchorPressedTR) |
| { |
| // #101688# AnchorTR for SW, take top right as (0,0) |
| pRetval = new ::sdr::overlay::OverlayBitmapEx(rPos, aBmpEx, |
| (sal_uInt16)(aBmpEx.GetSizePixel().Width() - 1), 0); |
| } |
| else |
| { |
| sal_uInt16 nCenX((sal_uInt16)(aBmpEx.GetSizePixel().Width() - 1L) >> 1); |
| sal_uInt16 nCenY((sal_uInt16)(aBmpEx.GetSizePixel().Height() - 1L) >> 1); |
| |
| if(aMoveOutsideOffset.X() > 0) |
| { |
| nCenX = 0; |
| } |
| else if(aMoveOutsideOffset.X() < 0) |
| { |
| nCenX = (sal_uInt16)(aBmpEx.GetSizePixel().Width() - 1); |
| } |
| |
| if(aMoveOutsideOffset.Y() > 0) |
| { |
| nCenY = 0; |
| } |
| else if(aMoveOutsideOffset.Y() < 0) |
| { |
| nCenY = (sal_uInt16)(aBmpEx.GetSizePixel().Height() - 1); |
| } |
| |
| // create centered handle as default |
| pRetval = new ::sdr::overlay::OverlayBitmapEx(rPos, aBmpEx, nCenX, nCenY); |
| } |
| } |
| |
| return pRetval; |
| } |
| |
| bool SdrHdl::IsHdlHit(const Point& rPnt) const |
| { |
| // OVERLAYMANAGER |
| basegfx::B2DPoint aPosition(rPnt.X(), rPnt.Y()); |
| return maOverlayGroup.isHitLogic(aPosition); |
| } |
| |
| Pointer SdrHdl::GetPointer() const |
| { |
| PointerStyle ePtr=POINTER_MOVE; |
| const sal_Bool bSize=eKind>=HDL_UPLFT && eKind<=HDL_LWRGT; |
| const sal_Bool bRot=pHdlList!=NULL && pHdlList->IsRotateShear(); |
| const sal_Bool bDis=pHdlList!=NULL && pHdlList->IsDistortShear(); |
| if (bSize && pHdlList!=NULL && (bRot || bDis)) { |
| switch (eKind) { |
| case HDL_UPLFT: case HDL_UPRGT: |
| case HDL_LWLFT: case HDL_LWRGT: ePtr=bRot ? POINTER_ROTATE : POINTER_REFHAND; break; |
| case HDL_LEFT : case HDL_RIGHT: ePtr=POINTER_VSHEAR; break; |
| case HDL_UPPER: case HDL_LOWER: ePtr=POINTER_HSHEAR; break; |
| default: |
| break; |
| } |
| } else { |
| // Fuer Resize von gedrehten Rechtecken die Mauszeiger etwas mitdrehen |
| if (bSize && nDrehWink!=0) { |
| long nHdlWink=0; |
| switch (eKind) { |
| case HDL_LWRGT: nHdlWink=31500; break; |
| case HDL_LOWER: nHdlWink=27000; break; |
| case HDL_LWLFT: nHdlWink=22500; break; |
| case HDL_LEFT : nHdlWink=18000; break; |
| case HDL_UPLFT: nHdlWink=13500; break; |
| case HDL_UPPER: nHdlWink=9000; break; |
| case HDL_UPRGT: nHdlWink=4500; break; |
| case HDL_RIGHT: nHdlWink=0; break; |
| default: |
| break; |
| } |
| nHdlWink+=nDrehWink+2249; // und etwas drauf (zum runden) |
| while (nHdlWink<0) nHdlWink+=36000; |
| while (nHdlWink>=36000) nHdlWink-=36000; |
| nHdlWink/=4500; |
| switch ((sal_uInt8)nHdlWink) { |
| case 0: ePtr=POINTER_ESIZE; break; |
| case 1: ePtr=POINTER_NESIZE; break; |
| case 2: ePtr=POINTER_NSIZE; break; |
| case 3: ePtr=POINTER_NWSIZE; break; |
| case 4: ePtr=POINTER_WSIZE; break; |
| case 5: ePtr=POINTER_SWSIZE; break; |
| case 6: ePtr=POINTER_SSIZE; break; |
| case 7: ePtr=POINTER_SESIZE; break; |
| } // switch |
| } else { |
| switch (eKind) { |
| case HDL_UPLFT: ePtr=POINTER_NWSIZE; break; |
| case HDL_UPPER: ePtr=POINTER_NSIZE; break; |
| case HDL_UPRGT: ePtr=POINTER_NESIZE; break; |
| case HDL_LEFT : ePtr=POINTER_WSIZE; break; |
| case HDL_RIGHT: ePtr=POINTER_ESIZE; break; |
| case HDL_LWLFT: ePtr=POINTER_SWSIZE; break; |
| case HDL_LOWER: ePtr=POINTER_SSIZE; break; |
| case HDL_LWRGT: ePtr=POINTER_SESIZE; break; |
| case HDL_POLY : ePtr=POINTER_MOVEPOINT; break; |
| case HDL_CIRC : ePtr=POINTER_HAND; break; |
| case HDL_REF1 : ePtr=POINTER_REFHAND; break; |
| case HDL_REF2 : ePtr=POINTER_REFHAND; break; |
| case HDL_BWGT : ePtr=POINTER_MOVEBEZIERWEIGHT; break; |
| case HDL_GLUE : ePtr=POINTER_MOVEPOINT; break; |
| case HDL_CUSTOMSHAPE1 : ePtr=POINTER_HAND; break; |
| default: |
| break; |
| } |
| } |
| } |
| return Pointer(ePtr); |
| } |
| |
| // #97016# II |
| sal_Bool SdrHdl::IsFocusHdl() const |
| { |
| switch(eKind) |
| { |
| case HDL_UPLFT: // Oben links |
| case HDL_UPPER: // Oben |
| case HDL_UPRGT: // Oben rechts |
| case HDL_LEFT: // Links |
| case HDL_RIGHT: // Rechts |
| case HDL_LWLFT: // Unten links |
| case HDL_LOWER: // Unten |
| case HDL_LWRGT: // Unten rechts |
| { |
| // if it's a activated TextEdit, it's moved to extended points |
| if(pHdlList && pHdlList->IsMoveOutside()) |
| return sal_False; |
| else |
| return sal_True; |
| } |
| |
| case HDL_MOVE: // Handle zum Verschieben des Objekts |
| case HDL_POLY: // Punktselektion an Polygon oder Bezierkurve |
| case HDL_BWGT: // Gewicht an einer Bezierkurve |
| case HDL_CIRC: // Winkel an Kreissegmenten, Eckenradius am Rect |
| case HDL_REF1: // Referenzpunkt 1, z.B. Rotationsmitte |
| case HDL_REF2: // Referenzpunkt 2, z.B. Endpunkt der Spiegelachse |
| //case HDL_MIRX: // Die Spiegelachse selbst |
| case HDL_GLUE: // GluePoint |
| |
| // #98388# do NOT activate here, let SW implement their own SdrHdl and |
| // overload IsFocusHdl() there to make the anchor accessible |
| //case HDL_ANCHOR: // anchor symbol (SD, SW) |
| // #101688# same for AnchorTR |
| //case HDL_ANCHOR_TR: // anchor symbol (SD, SW) |
| |
| //case HDL_TRNS: // interactive transparence |
| //case HDL_GRAD: // interactive gradient |
| //case HDL_COLR: // interactive color |
| |
| // for SJ and the CustomShapeHandles: |
| case HDL_CUSTOMSHAPE1: |
| |
| case HDL_USER: |
| { |
| return sal_True; |
| } |
| |
| default: |
| { |
| return sal_False; |
| } |
| } |
| } |
| |
| void SdrHdl::onMouseEnter(const MouseEvent& /*rMEvt*/) |
| { |
| } |
| |
| void SdrHdl::onMouseLeave() |
| { |
| } |
| |
| bool SdrHdl::isMouseOver() const |
| { |
| return mbMouseOver; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////////////////////////// |
| // class SdrHdlColor |
| |
| SdrHdlColor::SdrHdlColor(const Point& rRef, Color aCol, const Size& rSize, sal_Bool bLum) |
| : SdrHdl(rRef, HDL_COLR), |
| aMarkerSize(rSize), |
| bUseLuminance(bLum) |
| { |
| if(IsUseLuminance()) |
| aCol = GetLuminance(aCol); |
| |
| // remember color |
| aMarkerColor = aCol; |
| } |
| |
| SdrHdlColor::~SdrHdlColor() |
| { |
| } |
| |
| void SdrHdlColor::CreateB2dIAObject() |
| { |
| // first throw away old one |
| GetRidOfIAObject(); |
| |
| if(pHdlList) |
| { |
| SdrMarkView* pView = pHdlList->GetView(); |
| |
| if(pView && !pView->areMarkHandlesHidden()) |
| { |
| SdrPageView* pPageView = pView->GetSdrPageView(); |
| |
| if(pPageView) |
| { |
| for(sal_uInt32 b(0L); b < pPageView->PageWindowCount(); b++) |
| { |
| // const SdrPageViewWinRec& rPageViewWinRec = rPageViewWinList[b]; |
| const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b); |
| |
| if(rPageWindow.GetPaintWindow().OutputToWindow()) |
| { |
| if(rPageWindow.GetOverlayManager()) |
| { |
| Bitmap aBmpCol(CreateColorDropper(aMarkerColor)); |
| basegfx::B2DPoint aPosition(aPos.X(), aPos.Y()); |
| ::sdr::overlay::OverlayObject* pNewOverlayObject = new |
| ::sdr::overlay::OverlayBitmapEx( |
| aPosition, |
| BitmapEx(aBmpCol), |
| (sal_uInt16)(aBmpCol.GetSizePixel().Width() - 1) >> 1, |
| (sal_uInt16)(aBmpCol.GetSizePixel().Height() - 1) >> 1 |
| ); |
| DBG_ASSERT(pNewOverlayObject, "Got NO new IAO!"); |
| |
| // OVERLAYMANAGER |
| if(pNewOverlayObject) |
| { |
| rPageWindow.GetOverlayManager()->add(*pNewOverlayObject); |
| maOverlayGroup.append(*pNewOverlayObject); |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| Bitmap SdrHdlColor::CreateColorDropper(Color aCol) |
| { |
| // get the Bitmap |
| Bitmap aRetval(aMarkerSize, 24); |
| aRetval.Erase(aCol); |
| |
| // get write access |
| BitmapWriteAccess* pWrite = aRetval.AcquireWriteAccess(); |
| DBG_ASSERT(pWrite, "Got NO write access to a new Bitmap !!!"); |
| |
| if(pWrite) |
| { |
| // draw outer border |
| sal_Int32 nWidth = aMarkerSize.Width(); |
| sal_Int32 nHeight = aMarkerSize.Height(); |
| |
| pWrite->SetLineColor(Color(COL_LIGHTGRAY)); |
| pWrite->DrawLine(Point(0, 0), Point(0, nHeight - 1)); |
| pWrite->DrawLine(Point(1, 0), Point(nWidth - 1, 0)); |
| pWrite->SetLineColor(Color(COL_GRAY)); |
| pWrite->DrawLine(Point(1, nHeight - 1), Point(nWidth - 1, nHeight - 1)); |
| pWrite->DrawLine(Point(nWidth - 1, 1), Point(nWidth - 1, nHeight - 2)); |
| |
| // draw lighter UpperLeft |
| const Color aLightColor( |
| (sal_uInt8)(::std::min((sal_Int16)((sal_Int16)aCol.GetRed() + (sal_Int16)0x0040), (sal_Int16)0x00ff)), |
| (sal_uInt8)(::std::min((sal_Int16)((sal_Int16)aCol.GetGreen() + (sal_Int16)0x0040), (sal_Int16)0x00ff)), |
| (sal_uInt8)(::std::min((sal_Int16)((sal_Int16)aCol.GetBlue() + (sal_Int16)0x0040), (sal_Int16)0x00ff))); |
| pWrite->SetLineColor(aLightColor); |
| pWrite->DrawLine(Point(1, 1), Point(1, nHeight - 2)); |
| pWrite->DrawLine(Point(2, 1), Point(nWidth - 2, 1)); |
| |
| // draw darker LowerRight |
| const Color aDarkColor( |
| (sal_uInt8)(::std::max((sal_Int16)((sal_Int16)aCol.GetRed() - (sal_Int16)0x0040), (sal_Int16)0x0000)), |
| (sal_uInt8)(::std::max((sal_Int16)((sal_Int16)aCol.GetGreen() - (sal_Int16)0x0040), (sal_Int16)0x0000)), |
| (sal_uInt8)(::std::max((sal_Int16)((sal_Int16)aCol.GetBlue() - (sal_Int16)0x0040), (sal_Int16)0x0000))); |
| pWrite->SetLineColor(aDarkColor); |
| pWrite->DrawLine(Point(2, nHeight - 2), Point(nWidth - 2, nHeight - 2)); |
| pWrite->DrawLine(Point(nWidth - 2, 2), Point(nWidth - 2, nHeight - 3)); |
| |
| // get rid of write access |
| delete pWrite; |
| } |
| |
| return aRetval; |
| } |
| |
| Color SdrHdlColor::GetLuminance(const Color& rCol) |
| { |
| sal_uInt8 aLum = rCol.GetLuminance(); |
| Color aRetval(aLum, aLum, aLum); |
| return aRetval; |
| } |
| |
| void SdrHdlColor::CallColorChangeLink() |
| { |
| aColorChangeHdl.Call(this); |
| } |
| |
| void SdrHdlColor::SetColor(Color aNew, sal_Bool bCallLink) |
| { |
| if(IsUseLuminance()) |
| aNew = GetLuminance(aNew); |
| |
| if(aMarkerColor != aNew) |
| { |
| // remember new color |
| aMarkerColor = aNew; |
| |
| // create new display |
| Touch(); |
| |
| // tell about change |
| if(bCallLink) |
| CallColorChangeLink(); |
| } |
| } |
| |
| void SdrHdlColor::SetSize(const Size& rNew) |
| { |
| if(rNew != aMarkerSize) |
| { |
| // remember new size |
| aMarkerSize = rNew; |
| |
| // create new display |
| Touch(); |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////////////////////////// |
| // class SdrHdlGradient |
| |
| SdrHdlGradient::SdrHdlGradient(const Point& rRef1, const Point& rRef2, sal_Bool bGrad) |
| : SdrHdl(rRef1, bGrad ? HDL_GRAD : HDL_TRNS), |
| pColHdl1(NULL), |
| pColHdl2(NULL), |
| a2ndPos(rRef2), |
| bGradient(bGrad) |
| { |
| } |
| |
| SdrHdlGradient::~SdrHdlGradient() |
| { |
| } |
| |
| void SdrHdlGradient::Set2ndPos(const Point& rPnt) |
| { |
| if(a2ndPos != rPnt) |
| { |
| // remember new position |
| a2ndPos = rPnt; |
| |
| // create new display |
| Touch(); |
| } |
| } |
| |
| void SdrHdlGradient::CreateB2dIAObject() |
| { |
| // first throw away old one |
| GetRidOfIAObject(); |
| |
| if(pHdlList) |
| { |
| SdrMarkView* pView = pHdlList->GetView(); |
| |
| if(pView && !pView->areMarkHandlesHidden()) |
| { |
| SdrPageView* pPageView = pView->GetSdrPageView(); |
| |
| if(pPageView) |
| { |
| for(sal_uInt32 b(0L); b < pPageView->PageWindowCount(); b++) |
| { |
| const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b); |
| |
| if(rPageWindow.GetPaintWindow().OutputToWindow()) |
| { |
| if(rPageWindow.GetOverlayManager()) |
| { |
| // striped line in between |
| basegfx::B2DVector aVec(a2ndPos.X() - aPos.X(), a2ndPos.Y() - aPos.Y()); |
| double fVecLen = aVec.getLength(); |
| double fLongPercentArrow = (1.0 - 0.05) * fVecLen; |
| double fHalfArrowWidth = (0.05 * 0.5) * fVecLen; |
| aVec.normalize(); |
| basegfx::B2DVector aPerpend(-aVec.getY(), aVec.getX()); |
| sal_Int32 nMidX = (sal_Int32)(aPos.X() + aVec.getX() * fLongPercentArrow); |
| sal_Int32 nMidY = (sal_Int32)(aPos.Y() + aVec.getY() * fLongPercentArrow); |
| Point aMidPoint(nMidX, nMidY); |
| |
| basegfx::B2DPoint aPosition(aPos.X(), aPos.Y()); |
| basegfx::B2DPoint aMidPos(aMidPoint.X(), aMidPoint.Y()); |
| |
| ::sdr::overlay::OverlayObject* pNewOverlayObject = new |
| ::sdr::overlay::OverlayLineStriped( |
| aPosition, aMidPos |
| ); |
| DBG_ASSERT(pNewOverlayObject, "Got NO new IAO!"); |
| |
| pNewOverlayObject->setBaseColor(IsGradient() ? Color(COL_BLACK) : Color(COL_BLUE)); |
| rPageWindow.GetOverlayManager()->add(*pNewOverlayObject); |
| maOverlayGroup.append(*pNewOverlayObject); |
| |
| // arrowhead |
| Point aLeft(aMidPoint.X() + (sal_Int32)(aPerpend.getX() * fHalfArrowWidth), |
| aMidPoint.Y() + (sal_Int32)(aPerpend.getY() * fHalfArrowWidth)); |
| Point aRight(aMidPoint.X() - (sal_Int32)(aPerpend.getX() * fHalfArrowWidth), |
| aMidPoint.Y() - (sal_Int32)(aPerpend.getY() * fHalfArrowWidth)); |
| |
| basegfx::B2DPoint aPositionLeft(aLeft.X(), aLeft.Y()); |
| basegfx::B2DPoint aPositionRight(aRight.X(), aRight.Y()); |
| basegfx::B2DPoint aPosition2(a2ndPos.X(), a2ndPos.Y()); |
| |
| pNewOverlayObject = new |
| ::sdr::overlay::OverlayTriangle( |
| aPositionLeft, |
| aPosition2, |
| aPositionRight, |
| IsGradient() ? Color(COL_BLACK) : Color(COL_BLUE) |
| ); |
| DBG_ASSERT(pNewOverlayObject, "Got NO new IAO!"); |
| |
| rPageWindow.GetOverlayManager()->add(*pNewOverlayObject); |
| maOverlayGroup.append(*pNewOverlayObject); |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| IMPL_LINK(SdrHdlGradient, ColorChangeHdl, SdrHdl*, /*pHdl*/) |
| { |
| if(GetObj()) |
| FromIAOToItem(GetObj(), sal_True, sal_True); |
| return 0; |
| } |
| |
| void SdrHdlGradient::FromIAOToItem(SdrObject* _pObj, sal_Bool bSetItemOnObject, sal_Bool bUndo) |
| { |
| // from IAO positions and colors to gradient |
| const SfxItemSet& rSet = _pObj->GetMergedItemSet(); |
| |
| GradTransformer aGradTransformer; |
| GradTransGradient aOldGradTransGradient; |
| GradTransGradient aGradTransGradient; |
| GradTransVector aGradTransVector; |
| |
| String aString; |
| |
| aGradTransVector.maPositionA = basegfx::B2DPoint(GetPos().X(), GetPos().Y()); |
| aGradTransVector.maPositionB = basegfx::B2DPoint(Get2ndPos().X(), Get2ndPos().Y()); |
| if(pColHdl1) |
| aGradTransVector.aCol1 = pColHdl1->GetColor(); |
| if(pColHdl2) |
| aGradTransVector.aCol2 = pColHdl2->GetColor(); |
| |
| if(IsGradient()) |
| aOldGradTransGradient.aGradient = ((XFillGradientItem&)rSet.Get(XATTR_FILLGRADIENT)).GetGradientValue(); |
| else |
| aOldGradTransGradient.aGradient = ((XFillFloatTransparenceItem&)rSet.Get(XATTR_FILLFLOATTRANSPARENCE)).GetGradientValue(); |
| |
| // transform vector data to gradient |
| aGradTransformer.VecToGrad(aGradTransVector, aGradTransGradient, aOldGradTransGradient, _pObj, bMoveSingleHandle, bMoveFirstHandle); |
| |
| if(bSetItemOnObject) |
| { |
| SdrModel* pModel = _pObj->GetModel(); |
| SfxItemSet aNewSet(pModel->GetItemPool()); |
| |
| if(IsGradient()) |
| { |
| aString = String(); |
| XFillGradientItem aNewGradItem(aString, aGradTransGradient.aGradient); |
| aNewSet.Put(aNewGradItem); |
| } |
| else |
| { |
| aString = String(); |
| XFillFloatTransparenceItem aNewTransItem(aString, aGradTransGradient.aGradient); |
| aNewSet.Put(aNewTransItem); |
| } |
| |
| if(bUndo && pModel->IsUndoEnabled()) |
| { |
| pModel->BegUndo(SVX_RESSTR(IsGradient() ? SIP_XA_FILLGRADIENT : SIP_XA_FILLTRANSPARENCE)); |
| pModel->AddUndo(pModel->GetSdrUndoFactory().CreateUndoAttrObject(*_pObj)); |
| pModel->EndUndo(); |
| } |
| |
| pObj->SetMergedItemSetAndBroadcast(aNewSet); |
| } |
| |
| // back transformation, set values on pIAOHandle |
| aGradTransformer.GradToVec(aGradTransGradient, aGradTransVector, _pObj); |
| |
| SetPos(Point(FRound(aGradTransVector.maPositionA.getX()), FRound(aGradTransVector.maPositionA.getY()))); |
| Set2ndPos(Point(FRound(aGradTransVector.maPositionB.getX()), FRound(aGradTransVector.maPositionB.getY()))); |
| if(pColHdl1) |
| { |
| pColHdl1->SetPos(Point(FRound(aGradTransVector.maPositionA.getX()), FRound(aGradTransVector.maPositionA.getY()))); |
| pColHdl1->SetColor(aGradTransVector.aCol1); |
| } |
| if(pColHdl2) |
| { |
| pColHdl2->SetPos(Point(FRound(aGradTransVector.maPositionB.getX()), FRound(aGradTransVector.maPositionB.getY()))); |
| pColHdl2->SetColor(aGradTransVector.aCol2); |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////////////////////////// |
| |
| SdrHdlLine::~SdrHdlLine() {} |
| |
| void SdrHdlLine::CreateB2dIAObject() |
| { |
| // first throw away old one |
| GetRidOfIAObject(); |
| |
| if(pHdlList) |
| { |
| SdrMarkView* pView = pHdlList->GetView(); |
| |
| if(pView && !pView->areMarkHandlesHidden() && pHdl1 && pHdl2) |
| { |
| SdrPageView* pPageView = pView->GetSdrPageView(); |
| |
| if(pPageView) |
| { |
| for(sal_uInt32 b(0L); b < pPageView->PageWindowCount(); b++) |
| { |
| const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b); |
| |
| if(rPageWindow.GetPaintWindow().OutputToWindow()) |
| { |
| if(rPageWindow.GetOverlayManager()) |
| { |
| basegfx::B2DPoint aPosition1(pHdl1->GetPos().X(), pHdl1->GetPos().Y()); |
| basegfx::B2DPoint aPosition2(pHdl2->GetPos().X(), pHdl2->GetPos().Y()); |
| |
| ::sdr::overlay::OverlayObject* pNewOverlayObject = new |
| ::sdr::overlay::OverlayLineStriped( |
| aPosition1, |
| aPosition2 |
| ); |
| DBG_ASSERT(pNewOverlayObject, "Got NO new IAO!"); |
| |
| // OVERLAYMANAGER |
| if(pNewOverlayObject) |
| { |
| // color(?) |
| pNewOverlayObject->setBaseColor(Color(COL_LIGHTRED)); |
| |
| rPageWindow.GetOverlayManager()->add(*pNewOverlayObject); |
| maOverlayGroup.append(*pNewOverlayObject); |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| Pointer SdrHdlLine::GetPointer() const |
| { |
| return Pointer(POINTER_REFHAND); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////////////////////////// |
| |
| SdrHdlBezWgt::~SdrHdlBezWgt() {} |
| |
| void SdrHdlBezWgt::CreateB2dIAObject() |
| { |
| // call parent |
| SdrHdl::CreateB2dIAObject(); |
| |
| // create lines |
| if(pHdlList) |
| { |
| SdrMarkView* pView = pHdlList->GetView(); |
| |
| if(pView && !pView->areMarkHandlesHidden()) |
| { |
| SdrPageView* pPageView = pView->GetSdrPageView(); |
| |
| if(pPageView) |
| { |
| for(sal_uInt32 b(0L); b < pPageView->PageWindowCount(); b++) |
| { |
| const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b); |
| |
| if(rPageWindow.GetPaintWindow().OutputToWindow()) |
| { |
| if(rPageWindow.GetOverlayManager()) |
| { |
| basegfx::B2DPoint aPosition1(pHdl1->GetPos().X(), pHdl1->GetPos().Y()); |
| basegfx::B2DPoint aPosition2(aPos.X(), aPos.Y()); |
| |
| if(!aPosition1.equal(aPosition2)) |
| { |
| ::sdr::overlay::OverlayObject* pNewOverlayObject = new |
| ::sdr::overlay::OverlayLineStriped( |
| aPosition1, |
| aPosition2 |
| ); |
| DBG_ASSERT(pNewOverlayObject, "Got NO new IAO!"); |
| |
| // OVERLAYMANAGER |
| if(pNewOverlayObject) |
| { |
| // line part is not hittable |
| pNewOverlayObject->setHittable(sal_False); |
| |
| // color(?) |
| pNewOverlayObject->setBaseColor(Color(COL_LIGHTBLUE)); |
| |
| rPageWindow.GetOverlayManager()->add(*pNewOverlayObject); |
| maOverlayGroup.append(*pNewOverlayObject); |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////////////////////////// |
| |
| E3dVolumeMarker::E3dVolumeMarker(const basegfx::B2DPolyPolygon& rWireframePoly) |
| { |
| aWireframePoly = rWireframePoly; |
| } |
| |
| void E3dVolumeMarker::CreateB2dIAObject() |
| { |
| // create lines |
| if(pHdlList) |
| { |
| SdrMarkView* pView = pHdlList->GetView(); |
| |
| if(pView && !pView->areMarkHandlesHidden()) |
| { |
| SdrPageView* pPageView = pView->GetSdrPageView(); |
| |
| if(pPageView) |
| { |
| for(sal_uInt32 b(0L); b < pPageView->PageWindowCount(); b++) |
| { |
| const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b); |
| |
| if(rPageWindow.GetPaintWindow().OutputToWindow()) |
| { |
| if(rPageWindow.GetOverlayManager() && aWireframePoly.count()) |
| { |
| ::sdr::overlay::OverlayObject* pNewOverlayObject = new |
| ::sdr::overlay::OverlayPolyPolygonStripedAndFilled( |
| aWireframePoly); |
| DBG_ASSERT(pNewOverlayObject, "Got NO new IAO!"); |
| |
| // OVERLAYMANAGER |
| if(pNewOverlayObject) |
| { |
| pNewOverlayObject->setBaseColor(Color(COL_BLACK)); |
| |
| rPageWindow.GetOverlayManager()->add(*pNewOverlayObject); |
| maOverlayGroup.append(*pNewOverlayObject); |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////////////////////////// |
| |
| ImpEdgeHdl::~ImpEdgeHdl() |
| { |
| } |
| |
| void ImpEdgeHdl::CreateB2dIAObject() |
| { |
| if(nObjHdlNum <= 1 && pObj) |
| { |
| // first throw away old one |
| GetRidOfIAObject(); |
| |
| BitmapColorIndex eColIndex = LightCyan; |
| BitmapMarkerKind eKindOfMarker = Rect_7x7; |
| |
| if(pHdlList) |
| { |
| SdrMarkView* pView = pHdlList->GetView(); |
| |
| if(pView && !pView->areMarkHandlesHidden()) |
| { |
| const SdrEdgeObj* pEdge = (SdrEdgeObj*)pObj; |
| |
| if(pEdge->GetConnectedNode(nObjHdlNum == 0) != NULL) |
| eColIndex = LightRed; |
| |
| if(nPPntNum < 2) |
| { |
| // Handle with plus sign inside |
| eKindOfMarker = Circ_7x7; |
| } |
| |
| SdrPageView* pPageView = pView->GetSdrPageView(); |
| |
| if(pPageView) |
| { |
| for(sal_uInt32 b(0); b < pPageView->PageWindowCount(); b++) |
| { |
| const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b); |
| |
| if(rPageWindow.GetPaintWindow().OutputToWindow()) |
| { |
| if(rPageWindow.GetOverlayManager()) |
| { |
| basegfx::B2DPoint aPosition(aPos.X(), aPos.Y()); |
| |
| ::sdr::overlay::OverlayObject* pNewOverlayObject = CreateOverlayObject( |
| aPosition, |
| eColIndex, |
| eKindOfMarker); |
| |
| // OVERLAYMANAGER |
| if(pNewOverlayObject) |
| { |
| rPageWindow.GetOverlayManager()->add(*pNewOverlayObject); |
| maOverlayGroup.append(*pNewOverlayObject); |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| else |
| { |
| // call parent |
| SdrHdl::CreateB2dIAObject(); |
| } |
| } |
| |
| void ImpEdgeHdl::SetLineCode(SdrEdgeLineCode eCode) |
| { |
| if(eLineCode != eCode) |
| { |
| // remember new value |
| eLineCode = eCode; |
| |
| // create new display |
| Touch(); |
| } |
| } |
| |
| Pointer ImpEdgeHdl::GetPointer() const |
| { |
| SdrEdgeObj* pEdge=PTR_CAST(SdrEdgeObj,pObj); |
| if (pEdge==NULL) |
| return SdrHdl::GetPointer(); |
| if (nObjHdlNum<=1) |
| return Pointer(POINTER_MOVEPOINT); //Pointer(POINTER_DRAW_CONNECT); |
| if (IsHorzDrag()) |
| return Pointer(POINTER_ESIZE); |
| else |
| return Pointer(POINTER_SSIZE); |
| } |
| |
| sal_Bool ImpEdgeHdl::IsHorzDrag() const |
| { |
| SdrEdgeObj* pEdge=PTR_CAST(SdrEdgeObj,pObj); |
| if (pEdge==NULL) |
| return sal_False; |
| if (nObjHdlNum<=1) |
| return sal_False; |
| |
| SdrEdgeKind eEdgeKind = ((SdrEdgeKindItem&)(pEdge->GetObjectItem(SDRATTR_EDGEKIND))).GetValue(); |
| |
| const SdrEdgeInfoRec& rInfo=pEdge->aEdgeInfo; |
| if (eEdgeKind==SDREDGE_ORTHOLINES || eEdgeKind==SDREDGE_BEZIER) |
| { |
| return !rInfo.ImpIsHorzLine(eLineCode,*pEdge->pEdgeTrack); |
| } |
| else if (eEdgeKind==SDREDGE_THREELINES) |
| { |
| long nWink=nObjHdlNum==2 ? rInfo.nAngle1 : rInfo.nAngle2; |
| if (nWink==0 || nWink==18000) |
| return sal_True; |
| else |
| return sal_False; |
| } |
| return sal_False; |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////////////////////////// |
| |
| ImpMeasureHdl::~ImpMeasureHdl() |
| { |
| } |
| |
| void ImpMeasureHdl::CreateB2dIAObject() |
| { |
| // first throw away old one |
| GetRidOfIAObject(); |
| |
| if(pHdlList) |
| { |
| SdrMarkView* pView = pHdlList->GetView(); |
| |
| if(pView && !pView->areMarkHandlesHidden()) |
| { |
| BitmapColorIndex eColIndex = LightCyan; |
| BitmapMarkerKind eKindOfMarker = Rect_9x9; |
| |
| if(nObjHdlNum > 1) |
| { |
| eKindOfMarker = Rect_7x7; |
| } |
| |
| if(bSelect) |
| { |
| eColIndex = Cyan; |
| } |
| |
| SdrPageView* pPageView = pView->GetSdrPageView(); |
| |
| if(pPageView) |
| { |
| for(sal_uInt32 b(0L); b < pPageView->PageWindowCount(); b++) |
| { |
| const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b); |
| |
| if(rPageWindow.GetPaintWindow().OutputToWindow()) |
| { |
| if(rPageWindow.GetOverlayManager()) |
| { |
| basegfx::B2DPoint aPosition(aPos.X(), aPos.Y()); |
| |
| ::sdr::overlay::OverlayObject* pNewOverlayObject = CreateOverlayObject( |
| aPosition, |
| eColIndex, |
| eKindOfMarker); |
| |
| // OVERLAYMANAGER |
| if(pNewOverlayObject) |
| { |
| rPageWindow.GetOverlayManager()->add(*pNewOverlayObject); |
| maOverlayGroup.append(*pNewOverlayObject); |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| Pointer ImpMeasureHdl::GetPointer() const |
| { |
| switch (nObjHdlNum) |
| { |
| case 0: case 1: return Pointer(POINTER_HAND); |
| case 2: case 3: return Pointer(POINTER_MOVEPOINT); |
| case 4: case 5: return SdrHdl::GetPointer(); // wird dann entsprechend gedreht |
| } // switch |
| return Pointer(POINTER_NOTALLOWED); |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////////////////////////// |
| |
| ImpTextframeHdl::ImpTextframeHdl(const Rectangle& rRect) : |
| SdrHdl(rRect.TopLeft(),HDL_MOVE), |
| maRect(rRect) |
| { |
| } |
| |
| void ImpTextframeHdl::CreateB2dIAObject() |
| { |
| // first throw away old one |
| GetRidOfIAObject(); |
| |
| if(pHdlList) |
| { |
| SdrMarkView* pView = pHdlList->GetView(); |
| |
| if(pView && !pView->areMarkHandlesHidden()) |
| { |
| SdrPageView* pPageView = pView->GetSdrPageView(); |
| |
| if(pPageView) |
| { |
| for(sal_uInt32 b(0L); b < pPageView->PageWindowCount(); b++) |
| { |
| const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b); |
| |
| if(rPageWindow.GetPaintWindow().OutputToWindow()) |
| { |
| if(rPageWindow.GetOverlayManager()) |
| { |
| const basegfx::B2DPoint aTopLeft(maRect.Left(), maRect.Top()); |
| const basegfx::B2DPoint aBottomRight(maRect.Right(), maRect.Bottom()); |
| const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer; |
| const Color aHilightColor(aSvtOptionsDrawinglayer.getHilightColor()); |
| const double fTransparence(aSvtOptionsDrawinglayer.GetTransparentSelectionPercent() * 0.01); |
| |
| ::sdr::overlay::OverlayRectangle* pNewOverlayObject = new ::sdr::overlay::OverlayRectangle( |
| aTopLeft, |
| aBottomRight, |
| aHilightColor, |
| fTransparence, |
| 3.0, |
| 3.0, |
| nDrehWink * -F_PI18000, |
| 500, |
| true); // allow animation; the Handle is not shown at text edit time |
| |
| pNewOverlayObject->setHittable(false); |
| |
| // OVERLAYMANAGER |
| if(pNewOverlayObject) |
| { |
| rPageWindow.GetOverlayManager()->add(*pNewOverlayObject); |
| maOverlayGroup.append(*pNewOverlayObject); |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////////////////////////// |
| |
| class ImpSdrHdlListSorter: public ContainerSorter { |
| public: |
| ImpSdrHdlListSorter(Container& rNewCont): ContainerSorter(rNewCont) {} |
| virtual int Compare(const void* pElem1, const void* pElem2) const; |
| }; |
| |
| int ImpSdrHdlListSorter::Compare(const void* pElem1, const void* pElem2) const |
| { |
| SdrHdlKind eKind1=((SdrHdl*)pElem1)->GetKind(); |
| SdrHdlKind eKind2=((SdrHdl*)pElem2)->GetKind(); |
| // Level 1: Erst normale Handles, dann Glue, dann User, dann Plushandles, dann Retpunkt-Handles |
| unsigned n1=1; |
| unsigned n2=1; |
| if (eKind1!=eKind2) |
| { |
| if (eKind1==HDL_REF1 || eKind1==HDL_REF2 || eKind1==HDL_MIRX) n1=5; |
| else if (eKind1==HDL_GLUE) n1=2; |
| else if (eKind1==HDL_USER) n1=3; |
| else if (eKind1==HDL_SMARTTAG) n1=0; |
| if (eKind2==HDL_REF1 || eKind2==HDL_REF2 || eKind2==HDL_MIRX) n2=5; |
| else if (eKind2==HDL_GLUE) n2=2; |
| else if (eKind2==HDL_USER) n2=3; |
| else if (eKind2==HDL_SMARTTAG) n2=0; |
| } |
| if (((SdrHdl*)pElem1)->IsPlusHdl()) n1=4; |
| if (((SdrHdl*)pElem2)->IsPlusHdl()) n2=4; |
| if (n1==n2) |
| { |
| // Level 2: PageView (Pointer) |
| SdrPageView* pPV1=((SdrHdl*)pElem1)->GetPageView(); |
| SdrPageView* pPV2=((SdrHdl*)pElem2)->GetPageView(); |
| if (pPV1==pPV2) |
| { |
| // Level 3: Position (x+y) |
| SdrObject* pObj1=((SdrHdl*)pElem1)->GetObj(); |
| SdrObject* pObj2=((SdrHdl*)pElem2)->GetObj(); |
| if (pObj1==pObj2) |
| { |
| sal_uInt32 nNum1=((SdrHdl*)pElem1)->GetObjHdlNum(); |
| sal_uInt32 nNum2=((SdrHdl*)pElem2)->GetObjHdlNum(); |
| if (nNum1==nNum2) |
| { // #48763# |
| if (eKind1==eKind2) |
| return (long)pElem1<(long)pElem2 ? -1 : 1; // Notloesung, um immer die gleiche Sortierung zu haben |
| return (sal_uInt16)eKind1<(sal_uInt16)eKind2 ? -1 : 1; |
| } |
| else |
| return nNum1<nNum2 ? -1 : 1; |
| } |
| else |
| { |
| return (long)pObj1<(long)pObj2 ? -1 : 1; |
| } |
| } |
| else |
| { |
| return (long)pPV1<(long)pPV2 ? -1 : 1; |
| } |
| } |
| else |
| { |
| return n1<n2 ? -1 : 1; |
| } |
| } |
| |
| SdrMarkView* SdrHdlList::GetView() const |
| { |
| return pView; |
| } |
| |
| // #105678# Help struct for re-sorting handles |
| struct ImplHdlAndIndex |
| { |
| SdrHdl* mpHdl; |
| sal_uInt32 mnIndex; |
| }; |
| |
| // #105678# Help method for sorting handles taking care of OrdNums, keeping order in |
| // single objects and re-sorting polygon handles intuitively |
| extern "C" int __LOADONCALLAPI ImplSortHdlFunc( const void* pVoid1, const void* pVoid2 ) |
| { |
| const ImplHdlAndIndex* p1 = (ImplHdlAndIndex*)pVoid1; |
| const ImplHdlAndIndex* p2 = (ImplHdlAndIndex*)pVoid2; |
| |
| if(p1->mpHdl->GetObj() == p2->mpHdl->GetObj()) |
| { |
| if(p1->mpHdl->GetObj() && p1->mpHdl->GetObj()->ISA(SdrPathObj)) |
| { |
| // same object and a path object |
| if((p1->mpHdl->GetKind() == HDL_POLY || p1->mpHdl->GetKind() == HDL_BWGT) |
| && (p2->mpHdl->GetKind() == HDL_POLY || p2->mpHdl->GetKind() == HDL_BWGT)) |
| { |
| // both handles are point or control handles |
| if(p1->mpHdl->GetPolyNum() == p2->mpHdl->GetPolyNum()) |
| { |
| if(p1->mpHdl->GetPointNum() < p2->mpHdl->GetPointNum()) |
| { |
| return -1; |
| } |
| else |
| { |
| return 1; |
| } |
| } |
| else if(p1->mpHdl->GetPolyNum() < p2->mpHdl->GetPolyNum()) |
| { |
| return -1; |
| } |
| else |
| { |
| return 1; |
| } |
| } |
| } |
| } |
| else |
| { |
| if(!p1->mpHdl->GetObj()) |
| { |
| return -1; |
| } |
| else if(!p2->mpHdl->GetObj()) |
| { |
| return 1; |
| } |
| else |
| { |
| // different objects, use OrdNum for sort |
| const sal_uInt32 nOrdNum1 = p1->mpHdl->GetObj()->GetOrdNum(); |
| const sal_uInt32 nOrdNum2 = p2->mpHdl->GetObj()->GetOrdNum(); |
| |
| if(nOrdNum1 < nOrdNum2) |
| { |
| return -1; |
| } |
| else |
| { |
| return 1; |
| } |
| } |
| } |
| |
| // fallback to indices |
| if(p1->mnIndex < p2->mnIndex) |
| { |
| return -1; |
| } |
| else |
| { |
| return 1; |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////////////////////////// |
| // #97016# II |
| |
| void SdrHdlList::TravelFocusHdl(sal_Bool bForward) |
| { |
| // security correction |
| if(mnFocusIndex != CONTAINER_ENTRY_NOTFOUND && mnFocusIndex >= GetHdlCount()) |
| mnFocusIndex = CONTAINER_ENTRY_NOTFOUND; |
| |
| if(aList.Count()) |
| { |
| // take care of old handle |
| const sal_uIntPtr nOldHdlNum(mnFocusIndex); |
| SdrHdl* pOld = GetHdl(nOldHdlNum); |
| //SDOsal_Bool bRefresh(sal_False); |
| |
| if(pOld) |
| { |
| // switch off old handle |
| mnFocusIndex = CONTAINER_ENTRY_NOTFOUND; |
| pOld->Touch(); |
| //SDObRefresh = sal_True; |
| } |
| |
| // #105678# Alloc pointer array for sorted handle list |
| ImplHdlAndIndex* pHdlAndIndex = new ImplHdlAndIndex[aList.Count()]; |
| |
| // #105678# build sorted handle list |
| sal_uInt32 a; |
| for( a = 0; a < aList.Count(); a++) |
| { |
| pHdlAndIndex[a].mpHdl = (SdrHdl*)aList.GetObject(a); |
| pHdlAndIndex[a].mnIndex = a; |
| } |
| |
| // #105678# qsort all entries |
| qsort(pHdlAndIndex, aList.Count(), sizeof(ImplHdlAndIndex), ImplSortHdlFunc); |
| |
| // #105678# look for old num in sorted array |
| sal_uIntPtr nOldHdl(nOldHdlNum); |
| |
| if(nOldHdlNum != CONTAINER_ENTRY_NOTFOUND) |
| { |
| for(a = 0; a < aList.Count(); a++) |
| { |
| if(pHdlAndIndex[a].mpHdl == pOld) |
| { |
| nOldHdl = a; |
| break; |
| } |
| } |
| } |
| |
| // #105678# build new HdlNum |
| sal_uIntPtr nNewHdl(nOldHdl); |
| |
| // #105678# do the focus travel |
| if(bForward) |
| { |
| if(nOldHdl != CONTAINER_ENTRY_NOTFOUND) |
| { |
| if(nOldHdl == aList.Count() - 1) |
| { |
| // end forward run |
| nNewHdl = CONTAINER_ENTRY_NOTFOUND; |
| } |
| else |
| { |
| // simply the next handle |
| nNewHdl++; |
| } |
| } |
| else |
| { |
| // start forward run at first entry |
| nNewHdl = 0; |
| } |
| } |
| else |
| { |
| if(nOldHdl == CONTAINER_ENTRY_NOTFOUND) |
| { |
| // start backward run at last entry |
| nNewHdl = aList.Count() - 1; |
| |
| } |
| else |
| { |
| if(nOldHdl == 0) |
| { |
| // end backward run |
| nNewHdl = CONTAINER_ENTRY_NOTFOUND; |
| } |
| else |
| { |
| // simply the previous handle |
| nNewHdl--; |
| } |
| } |
| } |
| |
| // #105678# build new HdlNum |
| sal_uInt32 nNewHdlNum(nNewHdl); |
| |
| // look for old num in sorted array |
| if(nNewHdl != CONTAINER_ENTRY_NOTFOUND) |
| { |
| SdrHdl* pNew = pHdlAndIndex[nNewHdl].mpHdl; |
| |
| for(a = 0; a < aList.Count(); a++) |
| { |
| if((SdrHdl*)aList.GetObject(a) == pNew) |
| { |
| nNewHdlNum = a; |
| break; |
| } |
| } |
| } |
| |
| // take care of next handle |
| if(nOldHdlNum != nNewHdlNum) |
| { |
| mnFocusIndex = nNewHdlNum; |
| SdrHdl* pNew = GetHdl(mnFocusIndex); |
| |
| if(pNew) |
| { |
| pNew->Touch(); |
| //SDObRefresh = sal_True; |
| } |
| } |
| |
| // #105678# free mem again |
| delete [] pHdlAndIndex; |
| } |
| } |
| |
| SdrHdl* SdrHdlList::GetFocusHdl() const |
| { |
| if(mnFocusIndex != CONTAINER_ENTRY_NOTFOUND && mnFocusIndex < GetHdlCount()) |
| return GetHdl(mnFocusIndex); |
| else |
| return 0L; |
| } |
| |
| void SdrHdlList::SetFocusHdl(SdrHdl* pNew) |
| { |
| if(pNew) |
| { |
| SdrHdl* pActual = GetFocusHdl(); |
| |
| if(!pActual || pActual != pNew) |
| { |
| sal_uIntPtr nNewHdlNum = GetHdlNum(pNew); |
| |
| if(nNewHdlNum != CONTAINER_ENTRY_NOTFOUND) |
| { |
| //SDOsal_Bool bRefresh(sal_False); |
| mnFocusIndex = nNewHdlNum; |
| |
| if(pActual) |
| { |
| pActual->Touch(); |
| //SDObRefresh = sal_True; |
| } |
| |
| if(pNew) |
| { |
| pNew->Touch(); |
| //SDObRefresh = sal_True; |
| } |
| |
| //OLMif(bRefresh) |
| //OLM{ |
| //OLM if(pView) |
| //OLM pView->RefreshAllIAOManagers(); |
| //OLM} |
| } |
| } |
| } |
| } |
| |
| void SdrHdlList::ResetFocusHdl() |
| { |
| SdrHdl* pHdl = GetFocusHdl(); |
| |
| mnFocusIndex = CONTAINER_ENTRY_NOTFOUND; |
| |
| if(pHdl) |
| { |
| pHdl->Touch(); |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////////////////////////// |
| |
| SdrHdlList::SdrHdlList(SdrMarkView* pV) |
| : mnFocusIndex(CONTAINER_ENTRY_NOTFOUND), |
| pView(pV), |
| aList(1024,32,32) |
| { |
| nHdlSize = 3; |
| bRotateShear = sal_False; |
| bMoveOutside = sal_False; |
| bDistortShear = sal_False; |
| bFineHandles = sal_True; // new default: Handles are fine handles |
| } |
| |
| SdrHdlList::~SdrHdlList() |
| { |
| Clear(); |
| } |
| |
| void SdrHdlList::SetHdlSize(sal_uInt16 nSiz) |
| { |
| if(nHdlSize != nSiz) |
| { |
| // remember new value |
| nHdlSize = nSiz; |
| |
| // propagate change to IAOs |
| for(sal_uInt32 i=0; i<GetHdlCount(); i++) |
| { |
| SdrHdl* pHdl = GetHdl(i); |
| pHdl->Touch(); |
| } |
| } |
| } |
| |
| void SdrHdlList::SetMoveOutside(sal_Bool bOn) |
| { |
| if(bMoveOutside != bOn) |
| { |
| // remember new value |
| bMoveOutside = bOn; |
| |
| // propagate change to IAOs |
| for(sal_uInt32 i=0; i<GetHdlCount(); i++) |
| { |
| SdrHdl* pHdl = GetHdl(i); |
| pHdl->Touch(); |
| } |
| } |
| } |
| |
| void SdrHdlList::SetRotateShear(sal_Bool bOn) |
| { |
| bRotateShear = bOn; |
| } |
| |
| void SdrHdlList::SetDistortShear(sal_Bool bOn) |
| { |
| bDistortShear = bOn; |
| } |
| |
| void SdrHdlList::SetFineHdl(sal_Bool bOn) |
| { |
| if(bFineHandles != bOn) |
| { |
| // remember new state |
| bFineHandles = bOn; |
| |
| // propagate change to IAOs |
| for(sal_uInt32 i=0; i<GetHdlCount(); i++) |
| { |
| SdrHdl* pHdl = GetHdl(i); |
| pHdl->Touch(); |
| } |
| } |
| } |
| |
| SdrHdl* SdrHdlList::RemoveHdl(sal_uIntPtr nNum) |
| { |
| SdrHdl* pRetval = (SdrHdl*)aList.Remove(nNum); |
| |
| return pRetval; |
| } |
| |
| void SdrHdlList::Clear() |
| { |
| for (sal_uIntPtr i=0; i<GetHdlCount(); i++) |
| { |
| SdrHdl* pHdl=GetHdl(i); |
| delete pHdl; |
| } |
| aList.Clear(); |
| |
| bRotateShear=sal_False; |
| bDistortShear=sal_False; |
| } |
| |
| void SdrHdlList::Sort() |
| { |
| // #97016# II: remember current focused handle |
| SdrHdl* pPrev = GetFocusHdl(); |
| |
| ImpSdrHdlListSorter aSort(aList); |
| aSort.DoSort(); |
| |
| // #97016# II: get now and compare |
| SdrHdl* pNow = GetFocusHdl(); |
| |
| if(pPrev != pNow) |
| { |
| //SDOsal_Bool bRefresh(sal_False); |
| |
| if(pPrev) |
| { |
| pPrev->Touch(); |
| //SDObRefresh = sal_True; |
| } |
| |
| if(pNow) |
| { |
| pNow->Touch(); |
| //SDObRefresh = sal_True; |
| } |
| } |
| } |
| |
| sal_uIntPtr SdrHdlList::GetHdlNum(const SdrHdl* pHdl) const |
| { |
| if (pHdl==NULL) |
| return CONTAINER_ENTRY_NOTFOUND; |
| sal_uIntPtr nPos=aList.GetPos(pHdl); |
| return nPos; |
| } |
| |
| void SdrHdlList::AddHdl(SdrHdl* pHdl, sal_Bool bAtBegin) |
| { |
| if (pHdl!=NULL) |
| { |
| if (bAtBegin) |
| { |
| aList.Insert(pHdl,sal_uIntPtr(0)); |
| } |
| else |
| { |
| aList.Insert(pHdl,CONTAINER_APPEND); |
| } |
| pHdl->SetHdlList(this); |
| } |
| } |
| |
| SdrHdl* SdrHdlList::IsHdlListHit(const Point& rPnt, sal_Bool bBack, sal_Bool bNext, SdrHdl* pHdl0) const |
| { |
| SdrHdl* pRet=NULL; |
| sal_uIntPtr nAnz=GetHdlCount(); |
| sal_uIntPtr nNum=bBack ? 0 : nAnz; |
| while ((bBack ? nNum<nAnz : nNum>0) && pRet==NULL) |
| { |
| if (!bBack) |
| nNum--; |
| SdrHdl* pHdl=GetHdl(nNum); |
| if (bNext) |
| { |
| if (pHdl==pHdl0) |
| bNext=sal_False; |
| } |
| else |
| { |
| if (pHdl->IsHdlHit(rPnt)) |
| pRet=pHdl; |
| } |
| if (bBack) |
| nNum++; |
| } |
| return pRet; |
| } |
| |
| SdrHdl* SdrHdlList::GetHdl(SdrHdlKind eKind1) const |
| { |
| SdrHdl* pRet=NULL; |
| for (sal_uIntPtr i=0; i<GetHdlCount() && pRet==NULL; i++) |
| { |
| SdrHdl* pHdl=GetHdl(i); |
| if (pHdl->GetKind()==eKind1) |
| pRet=pHdl; |
| } |
| return pRet; |
| } |
| |
| // -------------------------------------------------------------------- |
| // SdrCropHdl |
| // -------------------------------------------------------------------- |
| |
| SdrCropHdl::SdrCropHdl( |
| const Point& rPnt, |
| SdrHdlKind eNewKind, |
| double fShearX, |
| double fRotation) |
| : SdrHdl(rPnt, eNewKind), |
| mfShearX(fShearX), |
| mfRotation(fRotation) |
| { |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| BitmapEx SdrCropHdl::GetHandlesBitmap( bool bIsFineHdl, bool bIsHighContrast ) |
| { |
| if( bIsHighContrast ) |
| { |
| static BitmapEx* pHighContrastBitmap = 0; |
| if( pHighContrastBitmap == 0 ) |
| pHighContrastBitmap = new BitmapEx(ResId(SIP_SA_ACCESSIBILITY_CROP_MARKERS, *ImpGetResMgr())); |
| return *pHighContrastBitmap; |
| } |
| else if( bIsFineHdl ) |
| { |
| static BitmapEx* pModernBitmap = 0; |
| if( pModernBitmap == 0 ) |
| pModernBitmap = new BitmapEx(ResId(SIP_SA_CROP_FINE_MARKERS, *ImpGetResMgr())); |
| return *pModernBitmap; |
| } |
| else |
| { |
| static BitmapEx* pSimpleBitmap = 0; |
| if( pSimpleBitmap == 0 ) |
| pSimpleBitmap = new BitmapEx(ResId(SIP_SA_CROP_MARKERS, *ImpGetResMgr())); |
| return *pSimpleBitmap; |
| } |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| BitmapEx SdrCropHdl::GetBitmapForHandle( const BitmapEx& rBitmap, int nSize ) |
| { |
| int nPixelSize = 0, nX = 0, nY = 0, nOffset = 0; |
| |
| if( nSize <= 3 ) |
| { |
| nPixelSize = 13; |
| nOffset = 0; |
| } |
| else if( nSize <=4 ) |
| { |
| nPixelSize = 17; |
| nOffset = 36; |
| } |
| else |
| { |
| nPixelSize = 21; |
| nOffset = 84; |
| } |
| |
| switch( eKind ) |
| { |
| case HDL_UPLFT: nX = 0; nY = 0; break; |
| case HDL_UPPER: nX = 1; nY = 0; break; |
| case HDL_UPRGT: nX = 2; nY = 0; break; |
| case HDL_LEFT: nX = 0; nY = 1; break; |
| case HDL_RIGHT: nX = 2; nY = 1; break; |
| case HDL_LWLFT: nX = 0; nY = 2; break; |
| case HDL_LOWER: nX = 1; nY = 2; break; |
| case HDL_LWRGT: nX = 2; nY = 2; break; |
| default: break; |
| } |
| |
| Rectangle aSourceRect( Point( nX * (nPixelSize-1) + nOffset, nY * (nPixelSize-1)), Size(nPixelSize, nPixelSize) ); |
| |
| BitmapEx aRetval(rBitmap); |
| aRetval.Crop(aSourceRect); |
| return aRetval; |
| } |
| |
| // -------------------------------------------------------------------- |
| |
| void SdrCropHdl::CreateB2dIAObject() |
| { |
| // first throw away old one |
| GetRidOfIAObject(); |
| |
| SdrMarkView* pView = pHdlList ? pHdlList->GetView() : 0; |
| SdrPageView* pPageView = pView ? pView->GetSdrPageView() : 0; |
| |
| if( pPageView && !pView->areMarkHandlesHidden() ) |
| { |
| sal_Bool bIsFineHdl(pHdlList->IsFineHdl()); |
| const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings(); |
| sal_Bool bIsHighContrast(rStyleSettings.GetHighContrastMode()); |
| int nHdlSize = pHdlList->GetHdlSize(); |
| if( bIsHighContrast ) |
| nHdlSize = 4; |
| |
| const BitmapEx aHandlesBitmap( GetHandlesBitmap( bIsFineHdl, bIsHighContrast ) ); |
| BitmapEx aBmpEx1( GetBitmapForHandle( aHandlesBitmap, nHdlSize ) ); |
| |
| for(sal_uInt32 b(0L); b < pPageView->PageWindowCount(); b++) |
| { |
| // const SdrPageViewWinRec& rPageViewWinRec = rPageViewWinList[b]; |
| const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b); |
| |
| if(rPageWindow.GetPaintWindow().OutputToWindow()) |
| { |
| if(rPageWindow.GetOverlayManager()) |
| { |
| basegfx::B2DPoint aPosition(aPos.X(), aPos.Y()); |
| |
| ::sdr::overlay::OverlayObject* pOverlayObject = 0L; |
| |
| // animate focused handles |
| if(IsFocusHdl() && (pHdlList->GetFocusHdl() == this)) |
| { |
| if( nHdlSize >= 2 ) |
| nHdlSize = 1; |
| |
| BitmapEx aBmpEx2( GetBitmapForHandle( aHandlesBitmap, nHdlSize + 1 ) ); |
| |
| const sal_uInt32 nBlinkTime = sal::static_int_cast<sal_uInt32>(rStyleSettings.GetCursorBlinkTime()); |
| |
| pOverlayObject = new ::sdr::overlay::OverlayAnimatedBitmapEx( |
| aPosition, |
| aBmpEx1, |
| aBmpEx2, |
| nBlinkTime, |
| (sal_uInt16)(aBmpEx1.GetSizePixel().Width() - 1) >> 1, |
| (sal_uInt16)(aBmpEx1.GetSizePixel().Height() - 1) >> 1, |
| (sal_uInt16)(aBmpEx2.GetSizePixel().Width() - 1) >> 1, |
| (sal_uInt16)(aBmpEx2.GetSizePixel().Height() - 1) >> 1, |
| mfShearX, |
| mfRotation); |
| } |
| else |
| { |
| // create centered handle as default |
| pOverlayObject = new ::sdr::overlay::OverlayBitmapEx( |
| aPosition, |
| aBmpEx1, |
| (sal_uInt16)(aBmpEx1.GetSizePixel().Width() - 1) >> 1, |
| (sal_uInt16)(aBmpEx1.GetSizePixel().Height() - 1) >> 1, |
| 0.0, |
| mfShearX, |
| mfRotation); |
| } |
| |
| // OVERLAYMANAGER |
| if(pOverlayObject) |
| { |
| rPageWindow.GetOverlayManager()->add(*pOverlayObject); |
| maOverlayGroup.append(*pOverlayObject); |
| } |
| } |
| } |
| } |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////////////////////////// |
| // with the correction of crop handling I could get rid of the extra mirroring flag, adapted stuff |
| // accordingly |
| |
| SdrCropViewHdl::SdrCropViewHdl( |
| const basegfx::B2DHomMatrix& rObjectTransform, |
| const Graphic& rGraphic, |
| double fCropLeft, |
| double fCropTop, |
| double fCropRight, |
| double fCropBottom) |
| : SdrHdl(Point(), HDL_USER), |
| maObjectTransform(rObjectTransform), |
| maGraphic(rGraphic), |
| mfCropLeft(fCropLeft), |
| mfCropTop(fCropTop), |
| mfCropRight(fCropRight), |
| mfCropBottom(fCropBottom) |
| { |
| } |
| |
| void SdrCropViewHdl::CreateB2dIAObject() |
| { |
| GetRidOfIAObject(); |
| SdrMarkView* pView = pHdlList ? pHdlList->GetView() : 0; |
| SdrPageView* pPageView = pView ? pView->GetSdrPageView() : 0; |
| |
| if(pPageView && pView->areMarkHandlesHidden()) |
| { |
| return; |
| } |
| |
| // decompose to have current translate and scale |
| basegfx::B2DVector aScale, aTranslate; |
| double fRotate, fShearX; |
| |
| maObjectTransform.decompose(aScale, aTranslate, fRotate, fShearX); |
| |
| if(aScale.equalZero()) |
| { |
| return; |
| } |
| |
| // detect 180 degree rotation, this is the same as mirrored in X and Y, |
| // thus change to mirroring. Prefer mirroring here. Use the equal call |
| // with getSmallValue here, the original which uses rtl::math::approxEqual |
| // is too correct here. Maybe this changes with enhanced precision in aw080 |
| // to the better so that this can be reduced to the more precise call again |
| if(basegfx::fTools::equal(fabs(fRotate), F_PI, 0.000000001)) |
| { |
| aScale.setX(aScale.getX() * -1.0); |
| aScale.setY(aScale.getY() * -1.0); |
| fRotate = 0.0; |
| } |
| |
| // remember mirroring, reset at Scale and adapt crop values for usage; |
| // mirroring can stay in the object transformation, so do not have to |
| // cope with it here (except later for the CroppedImage transformation, |
| // see below) |
| const bool bMirroredX(aScale.getX() < 0.0); |
| const bool bMirroredY(aScale.getY() < 0.0); |
| double fCropLeft(mfCropLeft); |
| double fCropTop(mfCropTop); |
| double fCropRight(mfCropRight); |
| double fCropBottom(mfCropBottom); |
| |
| if(bMirroredX) |
| { |
| aScale.setX(-aScale.getX()); |
| } |
| |
| if(bMirroredY) |
| { |
| aScale.setY(-aScale.getY()); |
| } |
| |
| // create target translate and scale |
| const basegfx::B2DVector aTargetScale( |
| aScale.getX() + fCropRight + fCropLeft, |
| aScale.getY() + fCropBottom + fCropTop); |
| const basegfx::B2DVector aTargetTranslate( |
| aTranslate.getX() - fCropLeft, |
| aTranslate.getY() - fCropTop); |
| |
| // create ranges to make comparisons |
| const basegfx::B2DRange aCurrentForCompare( |
| aTranslate.getX(), aTranslate.getY(), |
| aTranslate.getX() + aScale.getX(), aTranslate.getY() + aScale.getY()); |
| basegfx::B2DRange aCropped( |
| aTargetTranslate.getX(), aTargetTranslate.getY(), |
| aTargetTranslate.getX() + aTargetScale.getX(), aTargetTranslate.getY() + aTargetScale.getY()); |
| |
| if(aCropped.isEmpty()) |
| { |
| // nothing to return since cropped content is completely empty |
| return; |
| } |
| |
| if(aCurrentForCompare.equal(aCropped)) |
| { |
| // no crop at all |
| return; |
| } |
| |
| // back-transform to have values in unit coordinates |
| basegfx::B2DHomMatrix aBackToUnit; |
| aBackToUnit.translate(-aTranslate.getX(), -aTranslate.getY()); |
| aBackToUnit.scale( |
| basegfx::fTools::equalZero(aScale.getX()) ? 1.0 : 1.0 / aScale.getX(), |
| basegfx::fTools::equalZero(aScale.getY()) ? 1.0 : 1.0 / aScale.getY()); |
| |
| // transform cropped back to unit coordinates |
| aCropped.transform(aBackToUnit); |
| |
| // prepare crop PolyPolygon |
| basegfx::B2DPolygon aGraphicOutlinePolygon( |
| basegfx::tools::createPolygonFromRect( |
| aCropped)); |
| basegfx::B2DPolyPolygon aCropPolyPolygon(aGraphicOutlinePolygon); |
| |
| // current range is unit range |
| basegfx::B2DRange aOverlap(0.0, 0.0, 1.0, 1.0); |
| |
| aOverlap.intersect(aCropped); |
| |
| if(!aOverlap.isEmpty()) |
| { |
| aCropPolyPolygon.append( |
| basegfx::tools::createPolygonFromRect( |
| aOverlap)); |
| } |
| |
| // transform to object coordinates to prepare for clip |
| aCropPolyPolygon.transform(maObjectTransform); |
| aGraphicOutlinePolygon.transform(maObjectTransform); |
| |
| // create cropped transformation |
| basegfx::B2DHomMatrix aCroppedTransform; |
| const bool bCombinedMirrorX(bMirroredX); |
| |
| aCroppedTransform.scale( |
| aCropped.getWidth(), |
| aCropped.getHeight()); |
| aCroppedTransform.translate( |
| aCropped.getMinX(), |
| aCropped.getMinY()); |
| aCroppedTransform = maObjectTransform * aCroppedTransform; |
| |
| // prepare graphic primitive (tranformed) |
| const drawinglayer::primitive2d::Primitive2DReference aGraphic( |
| new drawinglayer::primitive2d::GraphicPrimitive2D( |
| aCroppedTransform, |
| maGraphic)); |
| |
| // prepare outline polygon for whole graphic |
| const SvtOptionsDrawinglayer aSvtOptionsDrawinglayer; |
| const basegfx::BColor aHilightColor(aSvtOptionsDrawinglayer.getHilightColor().getBColor()); |
| const drawinglayer::primitive2d::Primitive2DReference aGraphicOutline( |
| new drawinglayer::primitive2d::PolygonHairlinePrimitive2D( |
| aGraphicOutlinePolygon, |
| aHilightColor)); |
| |
| // combine these |
| drawinglayer::primitive2d::Primitive2DSequence aCombination(2); |
| aCombination[0] = aGraphic; |
| aCombination[1] = aGraphicOutline; |
| |
| // embed to MaskPrimitive2D |
| const drawinglayer::primitive2d::Primitive2DReference aMaskedGraphic( |
| new drawinglayer::primitive2d::MaskPrimitive2D( |
| aCropPolyPolygon, |
| aCombination)); |
| |
| // embed to UnifiedTransparencePrimitive2D |
| const drawinglayer::primitive2d::Primitive2DReference aTransparenceMaskedGraphic( |
| new drawinglayer::primitive2d::UnifiedTransparencePrimitive2D( |
| drawinglayer::primitive2d::Primitive2DSequence(&aMaskedGraphic, 1), |
| 0.8)); |
| |
| const drawinglayer::primitive2d::Primitive2DSequence aSequence(&aTransparenceMaskedGraphic, 1); |
| |
| for(sal_uInt32 b(0L); b < pPageView->PageWindowCount(); b++) |
| { |
| // const SdrPageViewWinRec& rPageViewWinRec = rPageViewWinList[b]; |
| const SdrPageWindow& rPageWindow = *pPageView->GetPageWindow(b); |
| |
| if(rPageWindow.GetPaintWindow().OutputToWindow()) |
| { |
| if(rPageWindow.GetOverlayManager()) |
| { |
| ::sdr::overlay::OverlayObject* pNew = new sdr::overlay::OverlayPrimitive2DSequenceObject(aSequence); |
| DBG_ASSERT(pNew, "Got NO new IAO!"); |
| |
| if(pNew) |
| { |
| // only informative object, no hit |
| pNew->setHittable(false); |
| |
| rPageWindow.GetOverlayManager()->add(*pNew); |
| maOverlayGroup.append(*pNew); |
| } |
| } |
| } |
| } |
| } |
| |
| //////////////////////////////////////////////////////////////////////////////////////////////////// |
| // eof |