diff options
Diffstat (limited to 'include/svx/svdhdl.hxx')
-rw-r--r-- | include/svx/svdhdl.hxx | 535 |
1 files changed, 535 insertions, 0 deletions
diff --git a/include/svx/svdhdl.hxx b/include/svx/svdhdl.hxx new file mode 100644 index 0000000000..4cece68952 --- /dev/null +++ b/include/svx/svdhdl.hxx @@ -0,0 +1,535 @@ +/* -*- 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 <tools/gen.hxx> +#include <vcl/graph.hxx> + +#include <svx/svdoedge.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <svx/sdr/overlay/overlayobjectlist.hxx> +#include <svx/svxdllapi.h> +#include <deque> + +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* m_pObj; // does handle belong to an object? + SdrPageView* m_pPV; // does handle belong to an object in certain pageview? + SdrHdlList* m_pHdlList; // to store the handlesize + // OVERLAYMANAGER + sdr::overlay::OverlayObjectList maOverlayGroup; + + Point m_aPos; + + SdrHdlKind m_eKind; + + Degree100 m_nRotationAngle; // turn handle or mousepointer + sal_uInt32 m_nObjHdlNum; // required by MarkView + sal_uInt32 m_nPolyNum; // Polygonpoint + sal_uInt32 m_nPPntNum; // Point number of the polygon + sal_uInt32 m_nSourceHdlNum; // still to implement + + bool m_bSelect : 1; // is a polygon point selected? + bool m_b1PixMore : 1; // True=handle is shown 1 pixel larger + bool m_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<sdr::overlay::OverlayObject> 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<sdr::overlay::OverlayObject> 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 m_eKind; } + void Touch(); + + const Point& GetPos() const { return m_aPos; } + void SetPos(const Point& rPnt); + + SdrPageView* GetPageView() const { return m_pPV; } + void SetPageView(SdrPageView* pNewPV) { m_pPV=pNewPV; } + + SdrObject* GetObj() const { return m_pObj; } + void SetObj(SdrObject* pNewObj); + + bool IsSelected() const { return m_bSelect; } + void SetSelected(bool bJa=true); + + void Set1PixMore(bool bJa=true); + void SetRotationAngle(Degree100 n); + + bool IsCornerHdl() const { return m_eKind==SdrHdlKind::UpperLeft || m_eKind==SdrHdlKind::UpperRight || m_eKind==SdrHdlKind::LowerLeft || m_eKind==SdrHdlKind::LowerRight; } + bool IsVertexHdl() const { return m_eKind==SdrHdlKind::Upper || m_eKind==SdrHdlKind::Lower || m_eKind==SdrHdlKind::Left || m_eKind==SdrHdlKind::Right; } + + void SetObjHdlNum(sal_uInt32 nNum) { m_nObjHdlNum=nNum; } + sal_uInt32 GetObjHdlNum() const { return m_nObjHdlNum; } + + void SetPolyNum(sal_uInt32 nNum) { m_nPolyNum=nNum; } + sal_uInt32 GetPolyNum() const { return m_nPolyNum; } + + void SetPointNum(sal_uInt32 nNum) { m_nPPntNum=nNum; } + sal_uInt32 GetPointNum() const { return m_nPPntNum; } + + void SetPlusHdl(bool bOn) { m_bPlusHdl=bOn; } + bool IsPlusHdl() const { return m_bPlusHdl; } + + void SetSourceHdlNum(sal_uInt32 nNum) { m_nSourceHdlNum=nNum; } + sal_uInt32 GetSourceHdlNum() const { return m_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 m_aMarkerSize; + + // color + Color m_aMarkerColor; + + // callback link when value changed + Link<SdrHdlColor*,void> m_aColorChangeHdl; + + // use luminance values only + bool m_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 m_bUseLuminance; } + + const Color& GetColor() const { return m_aMarkerColor; } + void SetColor(Color aNew, bool bCallLink = false); + + void SetSize(const Size& rNew); + + void SetColorChangeHdl(const Link<SdrHdlColor*,void>& rLink) { m_aColorChangeHdl = rLink; } +}; + + +class SdrHdlGradient final : public SdrHdl +{ +private: + // pointer to used color handles + SdrHdlColor* m_pColHdl1; + SdrHdlColor* m_pColHdl2; + + // 2nd position + Point m_a2ndPos; + + // is this a gradient or a transparence + bool m_bGradient : 1; + + // select which handle to move + bool m_bMoveSingleHandle : 1; + bool m_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 m_bGradient; } + + // set the associated color handles + void SetColorHandles(SdrHdlColor* pL1, SdrHdlColor* pL2) { m_pColHdl1 = pL1; m_pColHdl2 = pL2; } + SdrHdlColor* GetColorHdl1() const { return m_pColHdl1; } + SdrHdlColor* GetColorHdl2() const { return m_pColHdl2; } + + const Point& Get2ndPos() const { return m_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 m_bMoveSingleHandle; } + void SetMoveSingleHandle(bool bNew) { m_bMoveSingleHandle = bNew; } + bool IsMoveFirstHandle() const { return m_bMoveFirstHandle; } + void SetMoveFirstHandle(bool bNew) { m_bMoveFirstHandle = bNew; } +}; + + +// Mirror axis +class SdrHdlLine final : public SdrHdl +{ + // create marker for this kind + virtual void CreateB2dIAObject() override; + + SdrHdl* m_pHdl1; + SdrHdl* m_pHdl2; + +public: + SdrHdlLine(SdrHdl& rHdl1, SdrHdl& rHdl2, SdrHdlKind eNewKind) { m_eKind=eNewKind; m_pHdl1=&rHdl1; m_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) { m_eKind=eNewKind; m_pHdl1=pRefHdl1; } + virtual ~SdrHdlBezWgt() override; + +private: + // create marker for this kind + virtual void CreateB2dIAObject() override; + + const SdrHdl* m_pHdl1; +}; + + +class E3dVolumeMarker final : public SdrHdl +{ + basegfx::B2DPolyPolygon m_aWireframePoly; + + // create marker for this kind + virtual void CreateB2dIAObject() override; + +public: + explicit E3dVolumeMarker(const basegfx::B2DPolyPolygon& rWireframePoly); +}; + + +class ImpEdgeHdl final : public SdrHdl +{ + SdrEdgeLineCode m_eLineCode; + + // create marker for this kind + virtual void CreateB2dIAObject() override; + +public: + ImpEdgeHdl(const Point& rPnt, SdrHdlKind eNewKind): SdrHdl(rPnt,eNewKind),m_eLineCode(SdrEdgeLineCode::MiddleLine) {} + virtual ~ImpEdgeHdl() override; + + void SetLineCode(SdrEdgeLineCode eCode); + SdrEdgeLineCode GetLineCode() const { return m_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* m_pView; + std::deque<std::unique_ptr<SdrHdl>> maList; + sal_uInt16 m_nHdlSize; + + bool m_bRotateShear : 1; + bool m_bDistortShear : 1; + bool m_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 m_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 m_nHdlSize; } + void SetMoveOutside(bool bOn); + bool IsMoveOutside() const { return m_bMoveOutside; } + void SetRotateShear(bool bOn); + bool IsRotateShear() const { return m_bRotateShear; } + void SetDistortShear(bool bOn); + bool IsDistortShear() const { return m_bDistortShear; } + + // AddHdl takes ownership of the handle. It should be on the Heap + // as Clear() deletes it. + void AddHdl(std::unique_ptr<SdrHdl> pHdl); + std::unique_ptr<SdrHdl> 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( + basegfx::B2DHomMatrix aObjectTransform, + Graphic aGraphic, + 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: */ |