[2768] | 1 | using System;
|
---|
| 2 | using System.Drawing;
|
---|
| 3 | using System.Drawing.Drawing2D;
|
---|
| 4 |
|
---|
[2861] | 5 | namespace Netron.Diagramming.Core {
|
---|
| 6 | // ----------------------------------------------------------------------
|
---|
| 7 | /// <summary>
|
---|
| 8 | /// The default connector. Represents an endpoint of a connection or a
|
---|
| 9 | /// location of a bundle to which a connection can be attached.
|
---|
| 10 | /// </summary>
|
---|
| 11 | // ----------------------------------------------------------------------
|
---|
| 12 | public partial class Connector : ConnectorBase {
|
---|
| 13 | #region Fields
|
---|
| 14 |
|
---|
| 15 | // ------------------------------------------------------------------
|
---|
| 16 | /// <summary>
|
---|
| 17 | /// Implementation of IVersion - the current version of
|
---|
| 18 | /// Connector.
|
---|
[2768] | 19 | /// </summary>
|
---|
[2861] | 20 | // ------------------------------------------------------------------
|
---|
| 21 | protected const double connectorVersion = 1.0;
|
---|
[2768] | 22 |
|
---|
[2861] | 23 | // ------------------------------------------------------------------
|
---|
| 24 | /// <summary>
|
---|
| 25 | /// Specifies how the connector is drawn on the canvas when 'IsVisible'
|
---|
| 26 | /// is true. The default style is 'Simple', which is a transparent
|
---|
| 27 | /// background with a blue 'x' (similar to Visio).
|
---|
| 28 | /// </summary>
|
---|
| 29 | // ------------------------------------------------------------------
|
---|
| 30 | protected ConnectorStyle myStyle = ConnectorStyle.Simple;
|
---|
[2768] | 31 |
|
---|
[2861] | 32 | #endregion
|
---|
[2768] | 33 |
|
---|
[2861] | 34 | #region Properties
|
---|
[2768] | 35 |
|
---|
[2861] | 36 | // ------------------------------------------------------------------
|
---|
| 37 | /// <summary>
|
---|
| 38 | /// Gets the current version.
|
---|
| 39 | /// </summary>
|
---|
| 40 | // ------------------------------------------------------------------
|
---|
| 41 | public override double Version {
|
---|
| 42 | get {
|
---|
| 43 | return connectorVersion;
|
---|
| 44 | }
|
---|
| 45 | }
|
---|
[2768] | 46 |
|
---|
[2861] | 47 | // ------------------------------------------------------------------
|
---|
| 48 | /// <summary>
|
---|
| 49 | /// Gets or sets how the connector is drawn on the canvas when
|
---|
| 50 | /// 'IsVisible' is true.
|
---|
| 51 | /// </summary>
|
---|
| 52 | // ------------------------------------------------------------------
|
---|
| 53 | public ConnectorStyle ConnectorStyle {
|
---|
| 54 | get {
|
---|
| 55 | return this.myStyle;
|
---|
| 56 | }
|
---|
| 57 | set {
|
---|
| 58 | this.myStyle = value;
|
---|
| 59 | }
|
---|
| 60 | }
|
---|
[2768] | 61 |
|
---|
[2861] | 62 | // ------------------------------------------------------------------
|
---|
| 63 | /// <summary>
|
---|
| 64 | /// Gets the friendly name of the entity to be displayed in the UI
|
---|
| 65 | /// </summary>
|
---|
| 66 | /// <value></value>
|
---|
| 67 | // ------------------------------------------------------------------
|
---|
| 68 | public override string EntityName {
|
---|
| 69 | get { return "Connector"; }
|
---|
| 70 | }
|
---|
[2768] | 71 |
|
---|
[2861] | 72 | // ------------------------------------------------------------------
|
---|
| 73 | /// <summary>
|
---|
| 74 | /// The bounds of the paintable entity.
|
---|
| 75 | /// </summary>
|
---|
| 76 | /// <value></value>
|
---|
| 77 | // ------------------------------------------------------------------
|
---|
| 78 | public override Rectangle Rectangle {
|
---|
| 79 | get {
|
---|
| 80 | return new Rectangle(Point.X - 2, Point.Y - 2, 4, 4);
|
---|
| 81 | }
|
---|
| 82 | //set { Point = value.Location;
|
---|
| 83 | //TODO: think about what to do when setting the size }
|
---|
| 84 | }
|
---|
[2768] | 85 |
|
---|
[2861] | 86 | #endregion
|
---|
[2768] | 87 |
|
---|
[2861] | 88 | #region Constructor
|
---|
[2768] | 89 |
|
---|
[2861] | 90 | // ------------------------------------------------------------------
|
---|
| 91 | /// <summary>
|
---|
| 92 | /// Initializes a new instance of the <see cref="T:Connector"/> class.
|
---|
| 93 | /// </summary>
|
---|
| 94 | /// <param name="site">The site.</param>
|
---|
| 95 | // ------------------------------------------------------------------
|
---|
| 96 | public Connector(IModel site)
|
---|
| 97 | : base(site) {
|
---|
| 98 | }
|
---|
[2768] | 99 |
|
---|
[2861] | 100 | // ------------------------------------------------------------------
|
---|
| 101 | /// <summary>
|
---|
| 102 | /// Initializes a new instance of the <see cref="T:Connector"/> class.
|
---|
| 103 | /// </summary>
|
---|
| 104 | /// <param name="p">The p.</param>
|
---|
| 105 | /// <param name="site">The site.</param>
|
---|
| 106 | // ------------------------------------------------------------------
|
---|
| 107 | public Connector(Point p, IModel site)
|
---|
| 108 | : base(p, site) {
|
---|
| 109 | }
|
---|
[2768] | 110 |
|
---|
[2861] | 111 | // ------------------------------------------------------------------
|
---|
| 112 | /// <summary>
|
---|
| 113 | /// Initializes a new instance of the <see cref="T:Connector"/> class.
|
---|
| 114 | /// </summary>
|
---|
| 115 | /// <param name="p">The p.</param>
|
---|
| 116 | // ------------------------------------------------------------------
|
---|
| 117 | public Connector(Point p)
|
---|
| 118 | : base(p) {
|
---|
| 119 | }
|
---|
[2768] | 120 |
|
---|
[2861] | 121 | #endregion
|
---|
[2768] | 122 |
|
---|
[2861] | 123 | #region Methods
|
---|
[2768] | 124 |
|
---|
[2861] | 125 | // ------------------------------------------------------------------
|
---|
| 126 | /// <summary>
|
---|
| 127 | /// Paints the connector on the canvas.
|
---|
| 128 | /// </summary>
|
---|
| 129 | /// <param name="g"></param>
|
---|
| 130 | // ------------------------------------------------------------------
|
---|
| 131 | public override void Paint(Graphics g) {
|
---|
| 132 | if (g == null) {
|
---|
| 133 | throw new ArgumentNullException(
|
---|
| 134 | "The Graphics object is 'null'");
|
---|
| 135 | }
|
---|
[2768] | 136 |
|
---|
[2861] | 137 | if (Hovered || IsSelected) {
|
---|
| 138 | Rectangle area = Rectangle;
|
---|
| 139 | area.Inflate(3, 3);
|
---|
| 140 | g.DrawRectangle(
|
---|
| 141 | ArtPalette.ConnectionHighlightPen,
|
---|
| 142 | area);
|
---|
| 143 | //g.FillRectangle(
|
---|
| 144 | // Brushes.Green,
|
---|
| 145 | // Point.X - 4,
|
---|
| 146 | // Point.Y - 4,
|
---|
| 147 | // 8,
|
---|
| 148 | // 8);
|
---|
| 149 | } else {
|
---|
| 150 | if (Visible) {
|
---|
| 151 | switch (this.myStyle) {
|
---|
| 152 | case ConnectorStyle.Simple:
|
---|
| 153 | DrawSimpleConnector(g);
|
---|
| 154 | break;
|
---|
[2768] | 155 |
|
---|
[2861] | 156 | case ConnectorStyle.Round:
|
---|
| 157 | break;
|
---|
[2768] | 158 |
|
---|
[2861] | 159 | case ConnectorStyle.Square:
|
---|
| 160 | DrawSquareConnector(g);
|
---|
| 161 | break;
|
---|
| 162 | }
|
---|
[2768] | 163 |
|
---|
[2861] | 164 | if (this.mShowName) {
|
---|
| 165 | DrawName(g);
|
---|
| 166 | }
|
---|
| 167 | }
|
---|
| 168 | }
|
---|
| 169 | }
|
---|
[2768] | 170 |
|
---|
[2861] | 171 | // ------------------------------------------------------------------
|
---|
| 172 | /// <summary>
|
---|
| 173 | /// Draws the name of this connector.
|
---|
| 174 | /// </summary>
|
---|
| 175 | /// <param name="g">Graphics</param>
|
---|
| 176 | // ------------------------------------------------------------------
|
---|
| 177 | void DrawName(Graphics g) {
|
---|
| 178 | Size size = Size.Round(
|
---|
| 179 | g.MeasureString(mName, mFont));
|
---|
[2768] | 180 |
|
---|
[2861] | 181 | int xOffset = (size.Width - Rectangle.Width) / 2;
|
---|
| 182 | int yOffset = (size.Height - Rectangle.Height) / 2;
|
---|
[2768] | 183 |
|
---|
[2861] | 184 | System.Drawing.Point location = Rectangle.Location;
|
---|
[2768] | 185 |
|
---|
[2861] | 186 | switch (this.mNameLocation) {
|
---|
| 187 | case ConnectorNameLocation.Top:
|
---|
| 188 | location = new Point(
|
---|
| 189 | Rectangle.X - xOffset,
|
---|
| 190 | Rectangle.Y - size.Height);
|
---|
| 191 | break;
|
---|
[2768] | 192 |
|
---|
[2861] | 193 | case ConnectorNameLocation.Bottom:
|
---|
| 194 | location = new Point(
|
---|
| 195 | Rectangle.X - xOffset,
|
---|
| 196 | Rectangle.Bottom + size.Height);
|
---|
| 197 | break;
|
---|
[2768] | 198 |
|
---|
[2861] | 199 | case ConnectorNameLocation.Left:
|
---|
| 200 | location = new Point(
|
---|
| 201 | Rectangle.X - size.Width,
|
---|
| 202 | Rectangle.Y - yOffset);
|
---|
| 203 | break;
|
---|
[2768] | 204 |
|
---|
[2861] | 205 | case ConnectorNameLocation.Right:
|
---|
| 206 | location = new Point(
|
---|
| 207 | Rectangle.Right,
|
---|
| 208 | Rectangle.Y - yOffset);
|
---|
| 209 | break;
|
---|
| 210 | }
|
---|
[2768] | 211 |
|
---|
[2861] | 212 | Rectangle textArea = new Rectangle(location, size);
|
---|
| 213 | StringFormat format = new StringFormat();
|
---|
| 214 | format.FormatFlags = StringFormatFlags.FitBlackBox;
|
---|
| 215 | g.DrawString(
|
---|
| 216 | mName,
|
---|
| 217 | mFont,
|
---|
| 218 | new SolidBrush(mForeColor),
|
---|
| 219 | location);
|
---|
| 220 | }
|
---|
[2768] | 221 |
|
---|
[2861] | 222 | // ------------------------------------------------------------------
|
---|
| 223 | /// <summary>
|
---|
| 224 | /// Draws a blue 'x' using 'Dot' as the line style, with a transparent
|
---|
| 225 | /// color.
|
---|
| 226 | /// </summary>
|
---|
| 227 | /// <param name="g">Graphics</param>
|
---|
| 228 | // ------------------------------------------------------------------
|
---|
| 229 | protected virtual void DrawSimpleConnector(Graphics g) {
|
---|
| 230 | Pen pen = ArtPalette.GetSimpleConnectorPenStyle().DrawingPen();
|
---|
| 231 | Brush brush =
|
---|
| 232 | ArtPalette.GetSimpleConnectorPaintStyle().GetBrush(
|
---|
| 233 | this.Rectangle);
|
---|
[2768] | 234 |
|
---|
[2861] | 235 | GraphicsPath path = new GraphicsPath();
|
---|
| 236 | // Diagonal line from top left to bottom right.
|
---|
| 237 | g.DrawLine(pen, this.TopLeftCorner, this.BottomRightCorner);
|
---|
[2768] | 238 |
|
---|
| 239 |
|
---|
[2861] | 240 | // Diagonal line from top right to bottom lrft.
|
---|
| 241 | g.DrawLine(pen, this.TopRightCorner, this.BottomLeftCorner);
|
---|
| 242 | }
|
---|
[2768] | 243 |
|
---|
[2861] | 244 | protected virtual void DrawSquareConnector(Graphics g) {
|
---|
| 245 | Pen pen = ArtPalette.GetSimpleConnectorPenStyle().DrawingPen();
|
---|
| 246 | Brush brush = ArtPalette.GetSimpleConnectorPaintStyle().GetBrush(this.Rectangle);
|
---|
| 247 | g.DrawRectangle(pen, this.Rectangle);
|
---|
| 248 | }
|
---|
[2768] | 249 |
|
---|
| 250 |
|
---|
[2861] | 251 | // ------------------------------------------------------------------
|
---|
| 252 | /// <summary>
|
---|
| 253 | /// Tests if the mouse hits this connector.
|
---|
| 254 | /// </summary>
|
---|
| 255 | /// <param name="p">Point</param>
|
---|
| 256 | /// <returns>bool</returns>
|
---|
| 257 | // ------------------------------------------------------------------
|
---|
| 258 | public override bool Hit(Point p) {
|
---|
| 259 | Point a = p;
|
---|
| 260 | Point b = Point;
|
---|
| 261 | b.Offset(-7, -7);
|
---|
| 262 | //a.Offset(-1,-1);
|
---|
| 263 | Rectangle r = new Rectangle(a, new Size(0, 0));
|
---|
| 264 | Rectangle d = new Rectangle(b, new Size(15, 15));
|
---|
| 265 | return d.Contains(r);
|
---|
| 266 | }
|
---|
[2768] | 267 |
|
---|
[2861] | 268 | // ------------------------------------------------------------------
|
---|
| 269 | /// <summary>
|
---|
| 270 | /// Invalidates the connector
|
---|
| 271 | /// </summary>
|
---|
| 272 | // ------------------------------------------------------------------
|
---|
| 273 | public override void Invalidate() {
|
---|
| 274 | Point p = Point;
|
---|
| 275 | p.Offset(-5, -5);
|
---|
| 276 | if (Model != null)
|
---|
| 277 | Model.RaiseOnInvalidateRectangle(
|
---|
| 278 | new Rectangle(p, new Size(10, 10)));
|
---|
| 279 | }
|
---|
[2768] | 280 |
|
---|
[2861] | 281 | // ------------------------------------------------------------------
|
---|
| 282 | /// <summary>
|
---|
| 283 | /// Moves the connector with the given shift-vector.
|
---|
| 284 | /// </summary>
|
---|
| 285 | /// <param name="p">Point</param>
|
---|
| 286 | // ------------------------------------------------------------------
|
---|
| 287 | public override void MoveBy(Point p) {
|
---|
| 288 | Point pt = new Point(this.Point.X + p.X, this.Point.Y + p.Y);
|
---|
| 289 | IConnection con = null;
|
---|
| 290 | Point p1 = Point.Empty, p2 = Point.Empty;
|
---|
[2768] | 291 |
|
---|
[2861] | 292 | Rectangle rec = new Rectangle(
|
---|
| 293 | Point.X - 10,
|
---|
| 294 | Point.Y - 10,
|
---|
| 295 | 20,
|
---|
| 296 | 20);
|
---|
[2768] | 297 |
|
---|
[2861] | 298 | this.Point = pt;
|
---|
[2768] | 299 |
|
---|
[2861] | 300 | #region Case of connection
|
---|
| 301 | if (typeof(IConnection).IsInstanceOfType(this.Parent)) {
|
---|
| 302 | (Parent as IConnection).Invalidate();
|
---|
| 303 | }
|
---|
| 304 | #endregion
|
---|
| 305 |
|
---|
| 306 | #region Case of attached connectors
|
---|
| 307 | for (int k = 0; k < AttachedConnectors.Count; k++) {
|
---|
| 308 | if (typeof(IConnection).IsInstanceOfType(AttachedConnectors[k].Parent)) {
|
---|
| 309 | //keep a reference to the two points so we can invalidate the region afterwards
|
---|
| 310 | con = AttachedConnectors[k].Parent as IConnection;
|
---|
| 311 | p1 = con.From.Point;
|
---|
| 312 | p2 = con.To.Point;
|
---|
| 313 | }
|
---|
| 314 | AttachedConnectors[k].MoveBy(p);
|
---|
| 315 | if (con != null) {
|
---|
| 316 | //invalidate the 'before the move'-region
|
---|
| 317 | Rectangle f = new Rectangle(p1, new Size(10, 10));
|
---|
| 318 | Rectangle t = new Rectangle(p2, new Size(10, 10));
|
---|
| 319 | Model.RaiseOnInvalidateRectangle(Rectangle.Union(f, t));
|
---|
| 320 | //finally, invalidate the region where the connection is now
|
---|
| 321 | (AttachedConnectors[k].Parent as IConnection).Invalidate();
|
---|
| 322 | }
|
---|
| 323 | }
|
---|
| 324 | #endregion
|
---|
| 325 | //invalidate this connector, since it's been moved
|
---|
| 326 | Invalidate(rec);//before the move
|
---|
| 327 | this.Invalidate();//after the move
|
---|
| 328 |
|
---|
| 329 | }
|
---|
| 330 |
|
---|
| 331 | // ------------------------------------------------------------------
|
---|
| 332 | /// <summary>
|
---|
| 333 | /// Moves the connector with the given shift-vector
|
---|
| 334 | /// </summary>
|
---|
| 335 | /// <param name="x">The x.</param>
|
---|
| 336 | /// <param name="y">The y.</param>
|
---|
| 337 | // ------------------------------------------------------------------
|
---|
| 338 | public void MoveBy(int x, int y) {
|
---|
| 339 | Point pt = new Point(x, y);
|
---|
| 340 | MoveBy(pt);
|
---|
| 341 | }
|
---|
| 342 |
|
---|
| 343 | #endregion
|
---|
| 344 | }
|
---|
[2768] | 345 | }
|
---|