/src/libreoffice/include/svx/svdoedge.hxx
Line | Count | Source |
1 | | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | | /* |
3 | | * This file is part of the LibreOffice project. |
4 | | * |
5 | | * This Source Code Form is subject to the terms of the Mozilla Public |
6 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
7 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. |
8 | | * |
9 | | * This file incorporates work covered by the following license notice: |
10 | | * |
11 | | * Licensed to the Apache Software Foundation (ASF) under one or more |
12 | | * contributor license agreements. See the NOTICE file distributed |
13 | | * with this work for additional information regarding copyright |
14 | | * ownership. The ASF licenses this file to you under the Apache |
15 | | * License, Version 2.0 (the "License"); you may not use this file |
16 | | * except in compliance with the License. You may obtain a copy of |
17 | | * the License at http://www.apache.org/licenses/LICENSE-2.0 . |
18 | | */ |
19 | | |
20 | | #pragma once |
21 | | |
22 | | #include <memory> |
23 | | #include <optional> |
24 | | #include <svx/svdotext.hxx> |
25 | | #include <svx/svdglue.hxx> |
26 | | #include <svx/svxdllapi.h> |
27 | | #include <svx/xpoly.hxx> |
28 | | |
29 | | |
30 | | class SdrDragMethod; |
31 | | class SdrPageView; |
32 | | |
33 | | namespace sdr::properties { |
34 | | class ConnectorProperties; |
35 | | } |
36 | | |
37 | | |
38 | | /// Utility class SdrObjConnection |
39 | | class SdrObjConnection final |
40 | | { |
41 | | friend class SdrEdgeObj; |
42 | | friend class ImpEdgeHdl; |
43 | | friend class SdrCreateView; |
44 | | |
45 | | Point m_aObjOfs; // set during dragging of a node |
46 | | SdrObject* m_pSdrObj; // referenced object |
47 | | sal_uInt16 m_nConId; // connector number |
48 | | |
49 | | bool m_bBestConn : 1; // true -> the best-matching connector is searched for |
50 | | bool m_bBestVertex : 1; // true -> the best-matching vertex to connect is searched for |
51 | | bool m_bAutoVertex : 1; // autoConnector at apex nCon |
52 | | bool m_bAutoCorner : 1; // autoConnector at corner nCon |
53 | | |
54 | | public: |
55 | 26.9k | SdrObjConnection() { ResetVars(); } |
56 | | |
57 | | void ResetVars(); |
58 | | bool TakeGluePoint(SdrGluePoint& rGP) const; |
59 | | |
60 | 16.5k | void SetBestConnection( bool rB ) { m_bBestConn = rB; }; |
61 | 16.5k | void SetBestVertex( bool rB ) { m_bBestVertex = rB; }; |
62 | 16.5k | void SetAutoVertex( bool rB ) { m_bAutoVertex = rB; }; |
63 | 16.5k | void SetConnectorId( sal_uInt16 nId ) { m_nConId = nId; }; |
64 | | |
65 | 0 | bool IsBestConnection() const { return m_bBestConn; }; |
66 | 0 | bool IsAutoVertex() const { return m_bAutoVertex; }; |
67 | 0 | sal_uInt16 GetConnectorId() const { return m_nConId; }; |
68 | 30.5k | SdrObject* GetSdrObject() const { return m_pSdrObj; } |
69 | | }; |
70 | | |
71 | | |
72 | | enum class SdrEdgeLineCode { Obj1Line2, Obj1Line3, Obj2Line2, Obj2Line3, MiddleLine }; |
73 | | |
74 | | /// Utility class SdrEdgeInfoRec |
75 | | class SdrEdgeInfoRec |
76 | | { |
77 | | public: |
78 | | // The 5 distances are set on dragging or via SetAttr and are |
79 | | // evaluated by ImpCalcEdgeTrack. Only 0-3 longs are transported |
80 | | // via Get/SetAttr/Get/SetStyleSh though. |
81 | | Point m_aObj1Line2; |
82 | | Point m_aObj1Line3; |
83 | | Point m_aObj2Line2; |
84 | | Point m_aObj2Line3; |
85 | | Point m_aMiddleLine; |
86 | | |
87 | | // Following values are set by ImpCalcEdgeTrack |
88 | | tools::Long m_nAngle1; // exit angle at Obj1 |
89 | | tools::Long m_nAngle2; // exit angle at Obj2 |
90 | | sal_uInt16 m_nObj1Lines; // 1..3 |
91 | | sal_uInt16 m_nObj2Lines; // 1..3 |
92 | | sal_uInt16 m_nMiddleLine; // 0xFFFF=none, otherwise point number of the beginning of the line |
93 | | |
94 | | // The value determines how curved connectors are routed. With value 'true' it is routed |
95 | | // compatible to OOXML, with value 'false' LO routing is used. |
96 | | // The value is set/get via property SDRATTR_EDGEOOXMLCURVE. |
97 | | bool m_bUseOOXMLCurve; |
98 | | |
99 | | public: |
100 | | SdrEdgeInfoRec() |
101 | 104k | : m_nAngle1(0), |
102 | 104k | m_nAngle2(0), |
103 | 104k | m_nObj1Lines(0), |
104 | 104k | m_nObj2Lines(0), |
105 | 104k | m_nMiddleLine(0xFFFF), |
106 | 104k | m_bUseOOXMLCurve(false) |
107 | 104k | {} |
108 | | |
109 | | Point& ImpGetLineOffsetPoint(SdrEdgeLineCode eLineCode); |
110 | | sal_uInt16 ImpGetPolyIdx(SdrEdgeLineCode eLineCode, const XPolygon& rXP) const; |
111 | | bool ImpIsHorzLine(SdrEdgeLineCode eLineCode, const XPolygon& rXP) const; |
112 | | void ImpSetLineOffset(SdrEdgeLineCode eLineCode, const XPolygon& rXP, tools::Long nVal); |
113 | | tools::Long ImpGetLineOffset(SdrEdgeLineCode eLineCode, const XPolygon& rXP) const; |
114 | | }; |
115 | | |
116 | | |
117 | | /// Utility class SdrEdgeObjGeoData |
118 | | class SdrEdgeObjGeoData final : public SdrTextObjGeoData |
119 | | { |
120 | | public: |
121 | | SdrObjConnection m_aCon1; // connection status of the beginning of the line |
122 | | SdrObjConnection m_aCon2; // connection status of the end of the line |
123 | | std::optional<XPolygon> m_pEdgeTrack; |
124 | | bool m_bEdgeTrackDirty; // true -> connector track needs to be recalculated |
125 | | bool m_bEdgeTrackUserDefined; |
126 | | SdrEdgeInfoRec m_aEdgeInfo; |
127 | | |
128 | | public: |
129 | | SdrEdgeObjGeoData(); |
130 | | virtual ~SdrEdgeObjGeoData() override; |
131 | | }; |
132 | | |
133 | | |
134 | | /// Utility class SdrEdgeObj |
135 | | class SVXCORE_DLLPUBLIC SdrEdgeObj final : public SdrTextObj |
136 | | { |
137 | | private: |
138 | | // to allow sdr::properties::ConnectorProperties access to ImpSetAttrToEdgeInfo() |
139 | | friend class sdr::properties::ConnectorProperties; |
140 | | |
141 | | friend class SdrCreateView; |
142 | | friend class ImpEdgeHdl; |
143 | | |
144 | | SAL_DLLPRIVATE virtual std::unique_ptr<sdr::contact::ViewContact> CreateObjectSpecificViewContact() override; |
145 | | SAL_DLLPRIVATE virtual std::unique_ptr<sdr::properties::BaseProperties> CreateObjectSpecificProperties() override; |
146 | | |
147 | | SdrObjConnection m_aCon1; // Connection status of the beginning of the line |
148 | | SdrObjConnection m_aCon2; // Connection status of the end of the line |
149 | | |
150 | | std::optional<XPolygon> m_pEdgeTrack; |
151 | | sal_uInt16 m_nNotifyingCount; // Locking |
152 | | SdrEdgeInfoRec m_aEdgeInfo; |
153 | | |
154 | | bool m_bEdgeTrackDirty : 1; // true -> Connection track needs to be recalculated |
155 | | bool m_bEdgeTrackUserDefined : 1; |
156 | | |
157 | | // Bool to allow suppression of default connects at object |
158 | | // inside test (HitTest) and object center test (see ImpFindConnector()) |
159 | | bool mbSuppressDefaultConnect : 1; |
160 | | |
161 | | // Flag value for avoiding infinite loops when calculating |
162 | | // BoundRects from ring-connected connectors. A coloring algorithm |
163 | | // is used here. When the GetCurrentBoundRect() calculation of a |
164 | | // SdrEdgeObj is running, the flag is set, else it is always |
165 | | // false. |
166 | | bool mbBoundRectCalculationRunning : 1; |
167 | | |
168 | | // #i123048# need to remember if layouting was suppressed before to get |
169 | | // to a correct state for first real layouting |
170 | | bool mbSuppressed : 1; |
171 | | |
172 | | public: |
173 | | // Interface to default connect suppression |
174 | 0 | void SetSuppressDefaultConnect(bool bNew) { mbSuppressDefaultConnect = bNew; } |
175 | 0 | bool GetSuppressDefaultConnect() const { return mbSuppressDefaultConnect; } |
176 | | |
177 | | private: |
178 | | SAL_DLLPRIVATE virtual void Notify(SfxBroadcaster& rBC, const SfxHint& rHint) override; |
179 | | |
180 | | SAL_DLLPRIVATE static XPolygon ImpCalcObjToCenter(const Point& rStPt, tools::Long nEscAngle, const tools::Rectangle& rRect, const Point& rCenter); |
181 | | SAL_DLLPRIVATE void ImpRecalcEdgeTrack(); // recalculation of the connection track |
182 | | SAL_DLLPRIVATE XPolygon ImpCalcEdgeTrack(const XPolygon& rTrack0, SdrObjConnection& rCon1, SdrObjConnection& rCon2, SdrEdgeInfoRec* pInfo) const; |
183 | | SAL_DLLPRIVATE XPolygon ImpCalcEdgeTrack(const Point& rPt1, tools::Long nAngle1, const tools::Rectangle& rBoundRect1, const tools::Rectangle& rBewareRect1, |
184 | | const Point& rPt2, tools::Long nAngle2, const tools::Rectangle& rBoundRect2, const tools::Rectangle& rBewareRect2, |
185 | | sal_uInt64* pnQuality, SdrEdgeInfoRec* pInfo) const; |
186 | | SAL_DLLPRIVATE static bool ImpFindConnector(const Point& rPt, const SdrPageView& rPV, SdrObjConnection& rCon, const SdrEdgeObj* pThis, OutputDevice* pOut=nullptr, SdrDragStat* pDragStat = nullptr); |
187 | | SAL_DLLPRIVATE static SdrEscapeDirection ImpCalcEscAngle(SdrObject const * pObj, const Point& aPt2); |
188 | | SAL_DLLPRIVATE void ImpSetTailPoint(bool bTail1, const Point& rPt); |
189 | | SAL_DLLPRIVATE void ImpUndirtyEdgeTrack(); // potential recalculation of the connection track |
190 | | SAL_DLLPRIVATE void ImpDirtyEdgeTrack(); // invalidate connector path, so it will be recalculated next time |
191 | | SAL_DLLPRIVATE void ImpSetAttrToEdgeInfo(); // copying values from the pool to aEdgeInfo |
192 | | SAL_DLLPRIVATE void ImpSetEdgeInfoToAttr(); // copying values from the aEdgeInfo to the pool |
193 | | |
194 | | // protected destructor |
195 | | SAL_DLLPRIVATE virtual ~SdrEdgeObj() override; |
196 | | |
197 | | public: |
198 | | SdrEdgeObj(SdrModel& rSdrModel); |
199 | | // Copy constructor |
200 | | SAL_DLLPRIVATE SdrEdgeObj(SdrModel& rSdrModel, SdrEdgeObj const & rSource); |
201 | | |
202 | | // react on model/page change |
203 | | SAL_DLLPRIVATE virtual void handlePageChange(SdrPage* pOldPage, SdrPage* pNewPage) override; |
204 | | |
205 | 135k | SdrObjConnection& GetConnection(bool bTail1) { return *(bTail1 ? &m_aCon1 : &m_aCon2); } |
206 | | SAL_DLLPRIVATE virtual void TakeObjInfo(SdrObjTransformInfoRec& rInfo) const override; |
207 | | SAL_DLLPRIVATE virtual SdrObjKind GetObjIdentifier() const override; |
208 | | SAL_DLLPRIVATE virtual const tools::Rectangle& GetCurrentBoundRect() const override; |
209 | | SAL_DLLPRIVATE virtual const tools::Rectangle& GetSnapRect() const override; |
210 | | SAL_DLLPRIVATE virtual SdrGluePoint GetVertexGluePoint(sal_uInt16 nNum) const override; |
211 | | SAL_DLLPRIVATE virtual SdrGluePoint GetCornerGluePoint(sal_uInt16 nNum) const override; |
212 | | SAL_DLLPRIVATE virtual const SdrGluePointList* GetGluePointList() const override; |
213 | | SAL_DLLPRIVATE virtual SdrGluePointList* ForceGluePointList() override; |
214 | | |
215 | | // * for all of the below: bTail1=true: beginning of the line, |
216 | | // otherwise end of the line |
217 | | // * pObj=NULL: disconnect connector |
218 | 22.8k | void SetEdgeTrackDirty() { m_bEdgeTrackDirty=true; } |
219 | | void ConnectToNode(bool bTail1, SdrObject* pObj) override; |
220 | | SAL_DLLPRIVATE void DisconnectFromNode(bool bTail1) override; |
221 | | SdrObject* GetConnectedNode(bool bTail1) const override; |
222 | 72 | const SdrObjConnection& GetConnection(bool bTail1) const { return *(bTail1 ? &m_aCon1 : &m_aCon2); } |
223 | | SAL_DLLPRIVATE bool CheckNodeConnection(bool bTail1) const; |
224 | | |
225 | | SAL_DLLPRIVATE virtual void RecalcSnapRect() override; |
226 | | SAL_DLLPRIVATE virtual void TakeUnrotatedSnapRect(tools::Rectangle& rRect) const override; |
227 | | virtual rtl::Reference<SdrObject> CloneSdrObject(SdrModel& rTargetModel) const override; |
228 | | SAL_DLLPRIVATE virtual OUString TakeObjNameSingul() const override; |
229 | | SAL_DLLPRIVATE virtual OUString TakeObjNamePlural() const override; |
230 | | |
231 | | void SetEdgeTrackPath( const basegfx::B2DPolyPolygon& rPoly ); |
232 | | basegfx::B2DPolyPolygon GetEdgeTrackPath() const; |
233 | | |
234 | | SAL_DLLPRIVATE virtual basegfx::B2DPolyPolygon TakeXorPoly() const override; |
235 | | SAL_DLLPRIVATE virtual sal_uInt32 GetHdlCount() const override; |
236 | | SAL_DLLPRIVATE virtual void AddToHdlList(SdrHdlList& rHdlList) const override; |
237 | | |
238 | | // special drag methods |
239 | | SAL_DLLPRIVATE virtual bool hasSpecialDrag() const override; |
240 | | SAL_DLLPRIVATE virtual bool beginSpecialDrag(SdrDragStat& rDrag) const override; |
241 | | SAL_DLLPRIVATE virtual bool applySpecialDrag(SdrDragStat& rDrag) override; |
242 | | SAL_DLLPRIVATE virtual OUString getSpecialDragComment(const SdrDragStat& rDrag) const override; |
243 | | |
244 | | // FullDrag support |
245 | | SAL_DLLPRIVATE virtual rtl::Reference<SdrObject> getFullDragClone() const override; |
246 | | |
247 | | SAL_DLLPRIVATE virtual void NbcSetSnapRect(const tools::Rectangle& rRect) override; |
248 | | SAL_DLLPRIVATE virtual void NbcMove(const Size& aSize) override; |
249 | | SAL_DLLPRIVATE virtual void NbcResize(const Point& rRefPnt, double aXFact, double aYFact) override; |
250 | | |
251 | | // #i54102# added rotate, mirror and shear support |
252 | | SAL_DLLPRIVATE virtual void NbcRotate(const Point& rRef, Degree100 nAngle, double sn, double cs) override; |
253 | | SAL_DLLPRIVATE virtual void NbcMirror(const Point& rRef1, const Point& rRef2) override; |
254 | | SAL_DLLPRIVATE virtual void NbcShear(const Point& rRef, Degree100 nAngle, double tn, bool bVShear) override; |
255 | | |
256 | | // #102344# Added missing implementation |
257 | | SAL_DLLPRIVATE virtual void NbcSetAnchorPos(const Point& rPnt) override; |
258 | | |
259 | | SAL_DLLPRIVATE virtual bool BegCreate(SdrDragStat& rStat) override; |
260 | | SAL_DLLPRIVATE virtual bool MovCreate(SdrDragStat& rStat) override; |
261 | | SAL_DLLPRIVATE virtual bool EndCreate(SdrDragStat& rStat, SdrCreateCmd eCmd) override; |
262 | | SAL_DLLPRIVATE virtual bool BckCreate(SdrDragStat& rStat) override; |
263 | | SAL_DLLPRIVATE virtual void BrkCreate(SdrDragStat& rStat) override; |
264 | | SAL_DLLPRIVATE virtual basegfx::B2DPolyPolygon TakeCreatePoly(const SdrDragStat& rDrag) const override; |
265 | | SAL_DLLPRIVATE virtual PointerStyle GetCreatePointer() const override; |
266 | | SAL_DLLPRIVATE virtual rtl::Reference<SdrObject> DoConvertToPolyObj(bool bBezier, bool bAddText) const override; |
267 | | |
268 | | SAL_DLLPRIVATE virtual sal_uInt32 GetSnapPointCount() const override; |
269 | | SAL_DLLPRIVATE virtual Point GetSnapPoint(sal_uInt32 i) const override; |
270 | | SAL_DLLPRIVATE virtual bool IsPolyObj() const override; |
271 | | SAL_DLLPRIVATE virtual sal_uInt32 GetPointCount() const override; |
272 | | SAL_DLLPRIVATE virtual Point GetPoint(sal_uInt32 i) const override; |
273 | | SAL_DLLPRIVATE virtual void NbcSetPoint(const Point& rPnt, sal_uInt32 i) override; |
274 | | |
275 | | SAL_DLLPRIVATE virtual std::unique_ptr<SdrObjGeoData> NewGeoData() const override; |
276 | | SAL_DLLPRIVATE virtual void SaveGeoData(SdrObjGeoData& rGeo) const override; |
277 | | SAL_DLLPRIVATE virtual void RestoreGeoData(const SdrObjGeoData& rGeo) override; |
278 | | |
279 | | /** updates edges that are connected to the edges of this object |
280 | | as if the connected objects send a repaint broadcast |
281 | | #103122# |
282 | | */ |
283 | | SAL_DLLPRIVATE void Reformat(); |
284 | | |
285 | | // helper methods for the StarOffice api |
286 | | SAL_DLLPRIVATE Point GetTailPoint( bool bTail ) const; |
287 | | void SetTailPoint( bool bTail, const Point& rPt ); |
288 | | SAL_DLLPRIVATE void setGluePointIndex( bool bTail, sal_Int32 nId = -1 ); |
289 | | SAL_DLLPRIVATE sal_Int32 getGluePointIndex( bool bTail ); |
290 | | |
291 | | SAL_DLLPRIVATE virtual bool TRGetBaseGeometry(basegfx::B2DHomMatrix& rMatrix, basegfx::B2DPolyPolygon& rPolyPolygon) const override; |
292 | | SAL_DLLPRIVATE virtual void TRSetBaseGeometry(const basegfx::B2DHomMatrix& rMatrix, const basegfx::B2DPolyPolygon& rPolyPolygon) override; |
293 | | |
294 | | // for geometry access |
295 | | SAL_DLLPRIVATE ::basegfx::B2DPolygon getEdgeTrack() const; |
296 | | |
297 | | // helper method for SdrDragMethod::AddConnectorOverlays. Adds an overlay polygon for |
298 | | // this connector to rResult. |
299 | | SAL_DLLPRIVATE basegfx::B2DPolygon ImplAddConnectorOverlay(const SdrDragMethod& rDragMethod, bool bTail1, bool bTail2, bool bDetail) const; |
300 | | }; |
301 | | |
302 | | // The following item parameters of the SdrItemPool are used to |
303 | | // determine the actual connector line routing: |
304 | | // |
305 | | // sal_uInt16 EdgeFlowAngle default 9000 (= 90.00 deg), min 0, max 9000 |
306 | | // Clearance angle. |
307 | | // The angle at which the connecting line may run. |
308 | | // |
309 | | // sal_uInt16 EdgeEscAngle default 9000 (= 90.00 Deg), min 0, max 9000 |
310 | | // Object exit angle. |
311 | | // The angle at which the connection line may exit from the object. |
312 | | // |
313 | | // bool EdgeEscAsRay default false |
314 | | // true -> the connecting line emerges from the object radially. |
315 | | // Thus, angle specification by the line ObjCenter / connector. |
316 | | // |
317 | | // bool EdgeEscUseObjAngle default false |
318 | | // Object rotation angle is considered |
319 | | // true -> when determining the connector exit angle, angle for |
320 | | // object rotation is taken as an offset. |
321 | | // |
322 | | // sal_uInt64 EdgeFlowDefDist default 0, min 0, max ? |
323 | | // This is the default minimum distance on calculation of the |
324 | | // connection Line to the docked objects is in logical units. |
325 | | // This distance is overridden within the object, as soon as the |
326 | | // user drags on the lines. When docking onto a new object, |
327 | | // however, this default is used again. |
328 | | // |
329 | | // |
330 | | // General Information About Connectors: |
331 | | // |
332 | | // There are nodes and edge objects. Two nodes can be joined by an |
333 | | // edge. If a connector is connected to a node only at one end, the |
334 | | // other end is fixed to an absolute position in the document. It is |
335 | | // of course also possible for a connector to be "free" at both ends, |
336 | | // i.e. not connected to a node object on each side. |
337 | | // |
338 | | // A connector object can also theoretically be a node object at the |
339 | | // same time. In the first version, however, this will not yet be |
340 | | // realized. |
341 | | // |
342 | | // A connection between node and connector edge can be established by: |
343 | | // - Interactive creation of a new edge object at the SdrView where |
344 | | // the beginning or end point of the edge is placed on a connector |
345 | | // (glueing point) of an already existing node object. |
346 | | // - Interactive dragging of the beginning or end point of an |
347 | | // existing connector edge object on the SdrView to a connector |
348 | | // (glueing point) of an already existing node object. |
349 | | // - Undo/Redo |
350 | | // Moving node objects does not make any connections. Also not the |
351 | | // direct shifting of edge endpoints on the SdrModel... Connections |
352 | | // can also be established, if the connectors are not configured to |
353 | | // be visible in the view. |
354 | | // |
355 | | // An existing connection between node and edge is retained for: |
356 | | // - Dragging (Move/Resize/Rotate/...) of the node object |
357 | | // - Moving a connector position in the node object |
358 | | // - Simultaneous dragging (Move/Resize/Rotate/...) of the node and the |
359 | | // edge |
360 | | // |
361 | | // A connection between node and edge can be removed by: |
362 | | // - Deleting one of the objects |
363 | | // - Dragging the edge object without simultaneously dragging the node |
364 | | // - Deleting the connector at the node object |
365 | | // - Undo/Redo/Repeat |
366 | | // When dragging, the request to remove the connection must be |
367 | | // requested from outside of the model (for example, from the |
368 | | // SdrView). SdrEdgeObj::Move() itself does not remove the |
369 | | // connection. |
370 | | // |
371 | | // Each node object can have connectors, so-called gluepoints. These |
372 | | // are the geometric points at which the connecting edge object ends |
373 | | // when the connection is established. By default, each object has no |
374 | | // connectors. Nevertheless, one can dock an edge in certain view |
375 | | // settings since then, e.g., connectors can be automatically |
376 | | // generated at the 4 vertices of the node object when needed. Each |
377 | | // object provides 2x4 so-called default connector positions, 4 at |
378 | | // the vertices and 4 at the corner positions. In the normal case, |
379 | | // these are located at the 8 handle positions; exceptions here are |
380 | | // ellipses, parallelograms, ... . In addition, user-specific |
381 | | // connectors can be set for each node object. |
382 | | // |
383 | | // Then there is also the possibility to dock an edge on an object |
384 | | // with the attribute "bUseBestConnector". The best-matching |
385 | | // connector position for the routing of the connection line is then |
386 | | // used from the offering of connectors of the object or/and of the |
387 | | // vertices. The user assigns this attribute by docking the node in |
388 | | // its center (see, e.g., Visio). |
389 | | // 09-06-1996: bUseBestConnector uses vertex gluepoints only. |
390 | | // |
391 | | // And here is some terminology: |
392 | | // Connector : The connector object (edge object) |
393 | | // Node : Any object to which a connector can be glued to, e.g., a rectangle, |
394 | | // etc. |
395 | | // Gluepoint: The point at which the connector is glued to the node object. |
396 | | // There are: |
397 | | // Vertex gluepoints: Each node object presents these glue |
398 | | // points inherently. Perhaps there is already the option |
399 | | // "automatically glue to object vertex" in Draw (default is |
400 | | // on). |
401 | | // Corner gluepoints: These gluepoints, too, are already |
402 | | // auto-enabled on objects. Similar to the ones above, |
403 | | // there may already be an option for them in Draw (default is |
404 | | // off). |
405 | | // In contrast to Visio, vertex gluepoints and corner glue |
406 | | // points are not displayed in the UI; they are simply there (if |
407 | | // the option is activated). |
408 | | // Custom gluepoints: Any number of them are present on each |
409 | | // node object. They can be made visible using the option |
410 | | // (always visible when editing). At the moment, however, they |
411 | | // are not yet fully implemented. |
412 | | // Automatic gluepoint selection: If the connector is docked |
413 | | // to the node object so that the black frame encompasses the |
414 | | // entire object, then the connector tries to find the most |
415 | | // convenient of the 4 vertex gluepoints (and only of those). |
416 | | |
417 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |