/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ #ifndef INCLUDED_SVX_SVDHDL_HXX #define INCLUDED_SVX_SVDHDL_HXX #include #include #include #include #include #include #include class OutputDevice; class SdrHdlList; class SdrMarkView; class SdrObject; class SdrPageView; class MouseEvent; class HelpEvent; namespace sdr::contact { class ObjectContact; } // Every object must be able to create its handles. They will be fetched on // selection, registered at the View and made visible. // When a handle is touched by the mouse (IsHit()), from the view the matching mouse pointer // is picked up from the handle and passed to the app (on demand) to be switched on // Handles like e.g. rotation center or the mirror axis are generated by // the view if the correct transformation mode was selected by the controller. // SdrHdlKind::Move...SdrHdlKind::LowerRight should always be consecutive in the enum! enum class SdrHdlKind { Move, // Handle to move the object UpperLeft, // Upper left Upper, // Upper UpperRight, // Upper right Left, // Left Right, // Right LowerLeft, // Bottom left Lower, // Bottom LowerRight, // Bottom right Poly, // Select point in polygon or beziercurve BezierWeight, // Weight of a beziercurve Circle, // Angle to circle segment, corner radius to rectangle Ref1, // Reference point 1, e.g. rotation center Ref2, // Reference point 2, e.g. endpoint of mirror axis MirrorAxis, // Mirror axis Glue, // GluePoint Anchor, // Anchor symbol (SD, SW) Transparence, // Interactive transparence Gradient, // Interactive gradient Color, // Interactive color User, Anchor_TR, // #101688# Anchor handle with (0,0) at top right for SW // for SJ and the CustomShapeHandles: CustomShape1, SmartTag }; enum class BitmapColorIndex { LightGreen = 0, Cyan = 1, LightCyan = 2, Red = 3, LightRed = 4, Yellow = 5, }; enum class BitmapMarkerKind { Rect_7x7, Rect_9x9, Rect_11x11, Rect_13x13, Circ_7x7, Circ_9x9, Circ_11x11, Elli_7x9, Elli_9x11, Elli_9x7, Elli_11x9, RectPlus_7x7, RectPlus_9x9, RectPlus_11x11, Crosshair, Glue, Glue_Deselected, Anchor, // #98388# add AnchorPressed to be able to animate anchor control, too. AnchorPressed, // #101688# AnchorTR for SW AnchorTR, AnchorPressedTR, // for SJ and the CustomShapeHandles: Customshape_7x7, Customshape_9x9, Customshape_11x11 }; class SVXCORE_DLLPUBLIC SdrHdl { friend class SdrMarkView; // for the access to nObjHdlNum friend class SdrHdlList; protected: SdrObject* pObj; // does handle belong to an object? SdrPageView* pPV; // does handle belong to an object in certain pageview? SdrHdlList* pHdlList; // to store the handlesize // OVERLAYMANAGER sdr::overlay::OverlayObjectList maOverlayGroup; Point aPos; SdrHdlKind eKind; Degree100 nRotationAngle; // turn handle or mousepointer sal_uInt32 nObjHdlNum; // required by MarkView sal_uInt32 nPolyNum; // Polygonpoint sal_uInt32 nPPntNum; // Point number of the polygon sal_uInt32 nSourceHdlNum; // still to implement bool bSelect : 1; // is a polygon point selected? bool b1PixMore : 1; // True=handle is shown 1 pixel larger bool bPlusHdl : 1; // for Hld-Paint optimisation at MarkPoint/UnmarkPoint, and other ... bool mbMoveOutside; // forces this handle to be moved outside of the selection rectangle // create marker for this kind virtual void CreateB2dIAObject(); // cleanup marker if one exists void GetRidOfIAObject(); private: bool mbMouseOver; // is true if the mouse is over this handle protected: std::unique_ptr CreateOverlayObject( const basegfx::B2DPoint& rPos, BitmapColorIndex eColIndex, BitmapMarkerKind eKindOfMarker, Point aMoveOutsideOffset = Point()); static BitmapMarkerKind GetNextBigger(BitmapMarkerKind eKnd); // Helper to support inserting a new OverlayObject. It will do all // necessary stuff involved with that: // - add GridOffset for non-linear ViewToDevice transformation (calc) // - add to OverlayManager // - add to local OverlayObjectList - ownership change (!) // It is centralized here (and protected) to avoid that new usages/ // implementations forget one of these needed steps. void insertNewlyCreatedOverlayObjectForSdrHdl( std::unique_ptr pOverlayObject, const sdr::contact::ObjectContact& rObjectContact, sdr::overlay::OverlayManager& rOverlayManager); public: SdrHdl(); explicit SdrHdl(const Point& rPnt, SdrHdlKind eNewKind); virtual ~SdrHdl(); const sdr::overlay::OverlayObjectList& getOverlayObjectList() const { return maOverlayGroup; } void SetHdlList(SdrHdlList* pList); SdrHdlKind GetKind() const { return eKind; } void Touch(); const Point& GetPos() const { return aPos; } void SetPos(const Point& rPnt); SdrPageView* GetPageView() const { return pPV; } void SetPageView(SdrPageView* pNewPV) { pPV=pNewPV; } SdrObject* GetObj() const { return pObj; } void SetObj(SdrObject* pNewObj); bool IsSelected() const { return bSelect; } void SetSelected(bool bJa=true); void Set1PixMore(bool bJa=true); void SetRotationAngle(Degree100 n); bool IsCornerHdl() const { return eKind==SdrHdlKind::UpperLeft || eKind==SdrHdlKind::UpperRight || eKind==SdrHdlKind::LowerLeft || eKind==SdrHdlKind::LowerRight; } bool IsVertexHdl() const { return eKind==SdrHdlKind::Upper || eKind==SdrHdlKind::Lower || eKind==SdrHdlKind::Left || eKind==SdrHdlKind::Right; } void SetObjHdlNum(sal_uInt32 nNum) { nObjHdlNum=nNum; } sal_uInt32 GetObjHdlNum() const { return nObjHdlNum; } void SetPolyNum(sal_uInt32 nNum) { nPolyNum=nNum; } sal_uInt32 GetPolyNum() const { return nPolyNum; } void SetPointNum(sal_uInt32 nNum) { nPPntNum=nNum; } sal_uInt32 GetPointNum() const { return nPPntNum; } void SetPlusHdl(bool bOn) { bPlusHdl=bOn; } bool IsPlusHdl() const { return bPlusHdl; } void SetSourceHdlNum(sal_uInt32 nNum) { nSourceHdlNum=nNum; } sal_uInt32 GetSourceHdlNum() const { return nSourceHdlNum; } virtual PointerStyle GetPointer() const; bool IsHdlHit(const Point& rPnt) const; virtual bool IsFocusHdl() const; void SetMoveOutside( bool bMoveOutside ); /** is called when the mouse enters the area of this handle. If the handle changes his visualisation during mouse over it must override this method and call Touch(). */ virtual void onMouseEnter(const MouseEvent& rMEvt); /** is called when help is requested for the area of this handle */ virtual void onHelpRequest(); /** is called when the mouse leaves the area of this handle. If the handle changes his visualisation during mouse over it must override this method and call Touch(). */ virtual void onMouseLeave(); static BitmapEx createGluePointBitmap(); }; #define SDR_HANDLE_COLOR_SIZE_NORMAL Size(13, 13) #define SDR_HANDLE_COLOR_SIZE_SELECTED Size(17, 17) class SVXCORE_DLLPUBLIC SdrHdlColor final : public SdrHdl { // size of colr markers Size aMarkerSize; // color Color aMarkerColor; // callback link when value changed Link aColorChangeHdl; // use luminance values only bool bUseLuminance : 1; // create marker for this kind SVX_DLLPRIVATE virtual void CreateB2dIAObject() override; // help functions SVX_DLLPRIVATE BitmapEx CreateColorDropper(Color aCol); SVX_DLLPRIVATE static Color GetLuminance(const Color& rCol); public: explicit SdrHdlColor(const Point& rRef, Color aCol, const Size& rSize, bool bLuminance); virtual ~SdrHdlColor() override; bool IsUseLuminance() const { return bUseLuminance; } const Color& GetColor() const { return aMarkerColor; } void SetColor(Color aNew, bool bCallLink = false); void SetSize(const Size& rNew); void SetColorChangeHdl(const Link& rLink) { aColorChangeHdl = rLink; } }; class SdrHdlGradient final : public SdrHdl { private: // pointer to used color handles SdrHdlColor* pColHdl1; SdrHdlColor* pColHdl2; // 2nd position Point a2ndPos; // is this a gradient or a transparence bool bGradient : 1; // select which handle to move bool bMoveSingleHandle : 1; bool bMoveFirstHandle : 1; // create marker for this kind virtual void CreateB2dIAObject() override; public: SdrHdlGradient(const Point& rRef1, const Point& rRef2, bool bGrad); virtual ~SdrHdlGradient() override; bool IsGradient() const { return bGradient; } // set the associated color handles void SetColorHandles(SdrHdlColor* pL1, SdrHdlColor* pL2) { pColHdl1 = pL1; pColHdl2 = pL2; } SdrHdlColor* GetColorHdl1() const { return pColHdl1; } SdrHdlColor* GetColorHdl2() const { return pColHdl2; } const Point& Get2ndPos() const { return a2ndPos; } void Set2ndPos(const Point& rPnt); // the link called by the color handles DECL_LINK(ColorChangeHdl, SdrHdlColor*, void); // transformation call, create gradient from this handle void FromIAOToItem(SdrObject* pObj, bool bSetItemOnObject, bool bUndo); // selection flags for interaction bool IsMoveSingleHandle() const { return bMoveSingleHandle; } void SetMoveSingleHandle(bool bNew) { bMoveSingleHandle = bNew; } bool IsMoveFirstHandle() const { return bMoveFirstHandle; } void SetMoveFirstHandle(bool bNew) { bMoveFirstHandle = bNew; } }; // Mirror axis class SdrHdlLine final : public SdrHdl { // create marker for this kind virtual void CreateB2dIAObject() override; SdrHdl* pHdl1; SdrHdl* pHdl2; public: SdrHdlLine(SdrHdl& rHdl1, SdrHdl& rHdl2, SdrHdlKind eNewKind) { eKind=eNewKind; pHdl1=&rHdl1; pHdl2=&rHdl2; } virtual ~SdrHdlLine() override; virtual PointerStyle GetPointer() const override; }; // a SdrHdlBezWgt knows about its "base handle". Its draw method // draws additionally a line from its position to the position // of the base handle class SdrHdlBezWgt final : public SdrHdl { public: // this is not a Copy-Ctor!!! SdrHdlBezWgt(const SdrHdl* pRefHdl1, SdrHdlKind eNewKind=SdrHdlKind::BezierWeight) { eKind=eNewKind; pHdl1=pRefHdl1; } virtual ~SdrHdlBezWgt() override; private: // create marker for this kind virtual void CreateB2dIAObject() override; const SdrHdl* pHdl1; }; class E3dVolumeMarker final : public SdrHdl { basegfx::B2DPolyPolygon aWireframePoly; // create marker for this kind virtual void CreateB2dIAObject() override; public: explicit E3dVolumeMarker(const basegfx::B2DPolyPolygon& rWireframePoly); }; class ImpEdgeHdl final : public SdrHdl { SdrEdgeLineCode eLineCode; // create marker for this kind virtual void CreateB2dIAObject() override; public: ImpEdgeHdl(const Point& rPnt, SdrHdlKind eNewKind): SdrHdl(rPnt,eNewKind),eLineCode(SdrEdgeLineCode::MiddleLine) {} virtual ~ImpEdgeHdl() override; void SetLineCode(SdrEdgeLineCode eCode); SdrEdgeLineCode GetLineCode() const { return eLineCode; } bool IsHorzDrag() const; virtual PointerStyle GetPointer() const override; }; class ImpMeasureHdl final : public SdrHdl { // create marker for this kind virtual void CreateB2dIAObject() override; public: ImpMeasureHdl(const Point& rPnt, SdrHdlKind eNewKind): SdrHdl(rPnt,eNewKind) {} virtual ~ImpMeasureHdl() override; virtual PointerStyle GetPointer() const override; }; class ImpTextframeHdl final : public SdrHdl { const tools::Rectangle maRect; // create marker for this kind virtual void CreateB2dIAObject() override; public: explicit ImpTextframeHdl(const tools::Rectangle& rRect); }; class SVXCORE_DLLPUBLIC SdrHdlList { size_t mnFocusIndex; SdrMarkView* pView; std::deque> maList; sal_uInt16 nHdlSize; bool bRotateShear : 1; bool bDistortShear : 1; bool bMoveOutside : 1; // move handles outwards (for TextEdit) SVX_DLLPRIVATE SdrHdlList(const SdrHdlList&) = delete; SVX_DLLPRIVATE void operator=(const SdrHdlList&) = delete; public: explicit SdrHdlList(SdrMarkView* pV); ~SdrHdlList(); void Clear(); void TravelFocusHdl(bool bForward); SdrHdl* GetFocusHdl() const; void SetFocusHdl(SdrHdl* pNew); void ResetFocusHdl(); // Access to View SdrMarkView* GetView() const { return pView;} // Sorting: 1.Level first reference point handle, then normal handles, next Glue, then User then Plushandles // 2.Level PageView (Pointer) // 3.Level Position (x+y) void Sort(); size_t GetHdlCount() const { return maList.size(); } SdrHdl* GetHdl(size_t nNum) const { return nNum < maList.size() ? maList[nNum].get() : nullptr; } size_t GetHdlNum(const SdrHdl* pHdl) const; void SetHdlSize(sal_uInt16 nSiz); sal_uInt16 GetHdlSize() const { return nHdlSize; } void SetMoveOutside(bool bOn); bool IsMoveOutside() const { return bMoveOutside; } void SetRotateShear(bool bOn); bool IsRotateShear() const { return bRotateShear; } void SetDistortShear(bool bOn); bool IsDistortShear() const { return bDistortShear; } // AddHdl takes ownership of the handle. It should be on the Heap // as Clear() deletes it. void AddHdl(std::unique_ptr pHdl); std::unique_ptr RemoveHdl(size_t nNum); void RemoveAllByKind(SdrHdlKind eKind); // move the ownership of all the SdrHdl to rOther void MoveTo(SdrHdlList& rOther); // Last inserted handles are likely hit (if the handles are above each other) SdrHdl* IsHdlListHit(const Point& rPnt) const; SdrHdl* GetHdl(SdrHdlKind eKind1) const; }; class SVXCORE_DLLPUBLIC SdrCropHdl final : public SdrHdl { public: SdrCropHdl( const Point& rPnt, SdrHdlKind eNewKind, double fShearX, double fRotation); private: // create marker for this kind virtual void CreateB2dIAObject() override; BitmapEx GetBitmapForHandle( const BitmapEx& rBitmap, int nSize ); // evtl. shear and rotation, equal to the object's one to allow adaptation of // the visualization handles double mfShearX; double mfRotation; }; class SdrCropViewHdl final : public SdrHdl { private: basegfx::B2DHomMatrix maObjectTransform; Graphic maGraphic; double mfCropLeft; double mfCropTop; double mfCropRight; double mfCropBottom; public: SdrCropViewHdl( const basegfx::B2DHomMatrix& rObjectTransform, const Graphic& rGraphic, double fCropLeft, double fCropTop, double fCropRight, double fCropBottom); private: // create marker for this kind virtual void CreateB2dIAObject() override; }; #endif // INCLUDED_SVX_SVDHDL_HXX /* vim:set shiftwidth=4 softtabstop=4 expandtab: */