In this post, we will switch gears and setup a line drawing capability in Test Diagram which will be used for wires that interconnect components in the Engineering Tools application. We will create a new Wire class for this purpose. We will add a button that sets a line drawing mode. The mouse event handlers will be modified to detect if we are in line drawing mode using a flag. The mouse down event will capture the start point of the line, the mouse move event will draw a so-called "rubberband" line in real time. The mouse up event will capture the end point of the line. If the line is not horizontal or vertical, we will add a rectilinear line capability to draw a "L-shaped" line. Finally, during the line draw opertion, we will add end caps or highlights (small red squares) on the ends of the line to indicate the start and end points. The end caps will disappear after the line is drawn. The line will be added to the component list so that it is drawn in the schematicCanvas Paint event. In a future post, we will discuss how to "traverse" a diagram to perform analysis. The components will capture the output wires or lines in a local list.
Wire Class
Create a new class called Wire which is derived from the Comp base class. The Wire class requires 4 attributes:// Create wire start and end points
public Point Pt1 = new Point();
public Point Pt2 = new Point();
// End caps variables
private const int
endcap_radius = 3;
public bool endcapsVisible = false;
Here is the Wire Draw() method:
public override void
Draw(Graphics gr)
{
if (Pt1.X != Pt2.X || Pt1.Y != Pt2.Y)
{
// Draw L-shaped wire
gr.DrawLine(pen,
Pt1.X, Pt1.Y, Pt1.X, Pt2.Y); // Vertical line
gr.DrawLine(pen,
Pt1.X, Pt2.Y, Pt2.X, Pt2.Y); // Horizontal line
}
else
{
// Draw straight wire
gr.DrawLine(pen,
Pt1, Pt2);
}
// Draw the wire end caps
drawEndCaps(gr);
}
private void drawEndCaps(Graphics gr)
{
if (this.endcapsVisible)
{
// Draw custom end cap for Pt1
gr.DrawRectangle(Pens.Red, Pt1.X - endcap_radius, Pt1.Y - endcap_radius,
2 *
endcap_radius, 2 * endcap_radius); // Rectangular end cap
// Draw custom end cap for Pt2
gr.DrawRectangle(Pens.Red, Pt2.X - endcap_radius, Pt2.Y - endcap_radius,
2 *
endcap_radius, 2 * endcap_radius); // Rectangular end cap
}
}
Mouse Event modifications to draw lines
// Mouse event attributes
bool isMouseDown = false;
bool lineDrawing = false;
private Point NewPt1, NewPt2, offset;
Comp tempComp = new Comp();
// The wire we are drawing
private Wire
NewWire = null;
private void schematicCanvas_MouseDown(object sender, MouseEventArgs e)
{
isMouseDown = true;
// Snap the start point to the Grid
int x = e.X;
int y = e.Y;
SnapToGrid(ref x, ref y);
NewPt1.X = x;
NewPt1.Y = y;
if (!lineDrawing)
{
// Iterate over the component list and test each to see if it is
"hit"
foreach (Comp comp in comps)
{
if (hitTest(comp))
{
tempComp =
comp;
offset.X =
NewPt1.X - comp.loc.X;
offset.Y =
NewPt1.Y - comp.loc.Y;
}
}
}
if (lineDrawing)
{
// Snap the line end point to the Grid
NewPt2 = new Point(x, y);
// Create a new wire and add it to the schematic wires list
NewWire = new Wire(); // Use the constructor with no parameters
NewWire.Pt1 =
NewPt1;
NewWire.Pt2 =
NewPt2;
NewWire.endcapsVisible = true;
comps.Add(NewWire);
// Debugs to show the line points on the console
Debug.WriteLine("Line Start Points: (" +
NewPt1.X + ", " + NewPt1.Y + " )");
}
}
private void schematicCanvas_MouseMove(object sender, MouseEventArgs e)
{
if (isMouseDown == true)
{
int x = e.X;
int y = e.Y;
SnapToGrid(ref x, ref y);
if (!lineDrawing)
{
if (tempComp != null)
{
tempComp.loc
= new Point(x - offset.X, y - offset.Y);
}
}
if (lineDrawing)
{
if (NewWire == null) return;
NewPt2 = new Point(x, y);
NewWire.Pt2 =
NewPt2;
}
schematicCanvas.Invalidate(); // Refresh the
drawing canvas pictureBox
}
}
private void schematicCanvas_MouseUp(object sender, MouseEventArgs e)
{
isMouseDown = false;
tempComp = null;
if (lineDrawing)
{
int x = e.X;
int y = e.Y;
SnapToGrid(ref x, ref y);
NewPt1.Y = y;
// Update the new wire end points
NewWire.Pt2 =
NewPt2;
NewWire.endcapsVisible = false;
// Terminate any further updates to the new wire, this makes it
permanent in the schematic wires list
NewWire = null;
// Redraw.
schematicCanvas.Invalidate(); // Refresh the
drawing canvas pictureBox
// Debugs to show the line points on the console
Debug.WriteLine("Line End Points: (" +
NewPt2.X + ", " + NewPt2.Y + " )");
}
}
Wire Mode Button
- Text: Wire Mode
- Name: btnWireMode
No comments:
Post a Comment