BeepShape
Advanced shape control with connection support, interactive features, and professional drawing capabilities
📑 Table of Contents
Overview
BeepShape is a powerful geometric shape control designed for creating diagrams, flowcharts, and visual layouts. It supports multiple shape types, connection management, interactive features like dragging and resizing, and professional rendering with gradients and effects.
Built on the BeepControl foundation, it provides advanced features including connection points, rotation, custom fill styles, and text overlays, making it ideal for diagram editors, flowchart builders, and visual design applications.
Key Features
🔷 Multiple Shape Types
Rectangle, Ellipse, Triangle, Star, Diamond, Pentagon, Hexagon, Octagon, and Line
🔗 Connection Support
Connect shapes with lines and manage relationships between controls
🖱️ Interactive Editing
Drag to move, resize handles, rotation, and selection management
🎨 Professional Rendering
Gradients, patterns, line styles, and anti-aliased drawing
📝 Text Integration
Display text inside shapes with automatic centering
🎯 Connection Points
Visual connection points for linking shapes together
🔄 Transformation
Rotation, scaling, and positioning with smooth rendering
🎯 Hit Testing
Advanced hit testing for precise interaction and selection
Basic Usage
Simple Rectangle Shape
// Create a basic rectangle shape
var rectangle = new BeepShape
{
ShapeType = BeepShapeType.Rectangle,
Size = new Size(100, 60),
Location = new Point(50, 50),
BackColor = Color.LightBlue,
BorderColor = Color.DarkBlue,
BorderThickness = 2
};
// Add to form
this.Controls.Add(rectangle);
Circle with Text
var circle = new BeepShape
{
ShapeType = BeepShapeType.Ellipse,
Size = new Size(80, 80),
Location = new Point(150, 100),
ShapeText = "Start",
BackColor = Color.LightGreen,
ForeColor = Color.DarkGreen,
Font = new Font("Arial", 12, FontStyle.Bold)
};
Star with Gradient Fill
var star = new BeepShape
{
ShapeType = BeepShapeType.Star,
StarPoints = 5,
StarInnerRatio = 0.4f,
Size = new Size(100, 100),
FillStyle = ShapeFillStyle.Gradient,
GradientStartColor = Color.Yellow,
GradientEndColor = Color.Orange,
BorderColor = Color.Red
};
Use different shape types to represent different elements in your diagrams: rectangles for processes, diamonds for decisions, ellipses for start/end points.
Shape Types
| Shape Type | Description | Special Properties |
|---|---|---|
| Rectangle | Standard rectangle with optional rounded corners | CornerRadius for rounded corners |
| Ellipse | Oval or circle shape | Perfect circle when width equals height |
| Triangle | Three-sided polygon pointing upward | Equilateral triangle shape |
| Diamond | Four-sided diamond shape | Perfect diamond with centered points |
| Star | Multi-pointed star shape | StarPoints (number of points), StarInnerRatio |
| Pentagon | Five-sided regular polygon | PolygonSides property (set to 5) |
| Hexagon | Six-sided regular polygon | PolygonSides property (set to 6) |
| Octagon | Eight-sided regular polygon | PolygonSides property (set to 8) |
| Line | Straight line with optional arrow head | ShowArrowHead, ArrowHeadSize |
Properties
Shape Properties
| Property | Type | Default | Description |
|---|---|---|---|
ShapeType |
BeepShapeType | Rectangle | Type of shape to draw |
RotationAngle |
float | 0f | Rotation angle in degrees |
PolygonSides |
int | 6 | Number of sides for polygon shapes |
StarPoints |
int | 5 | Number of points for star shapes |
StarInnerRatio |
float | 0.5f | Inner radius ratio for star shapes (0.0 to 1.0) |
CornerRadius |
int | 10 | Corner radius for rounded shapes |
ShapeText |
string | "" | Text to display inside the shape |
Appearance Properties
| Property | Type | Default | Description |
|---|---|---|---|
FillStyle |
ShapeFillStyle | Solid | Fill style (Solid, Gradient, Hatch, None) |
LineStyle |
DashStyle | Solid | Line style for the shape outline |
GradientStartColor |
Color | White | Gradient start color |
GradientEndColor |
Color | LightGray | Gradient end color |
Behavior Properties
AllowDrag bool
Allow shape to be dragged
AllowResize bool
Allow shape to be resized
ShowResizeHandles bool
Show resize handles when selected
ShowConnectionPoints bool
Show connection points when selected
Connection Properties
| Property | Type | Description |
|---|---|---|
ConnectedStart |
BeepControl | Control connected to the start of this shape |
ConnectedEnd |
BeepControl | Control connected to the end of this shape |
Line-Specific Properties
| Property | Type | Default | Description |
|---|---|---|---|
ShowArrowHead |
bool | false | Show arrow head on line end |
ArrowHeadSize |
int | 12 | Arrow head size for line shapes |
Methods
| Method | Parameters | Description |
|---|---|---|
ConnectTo |
BeepControl target, bool asStart = true | Connect this shape to another control |
Disconnect |
bool fromStart = true | Disconnect from connected control |
DrawContent |
Graphics g | Draw the shape content with all effects |
UpdateConnectionPoints |
none | Update the positions of connection points |
SetupHitAreas |
none | Configure hit test areas for interaction |
ApplyTheme |
none | Apply current theme to shape appearance |
Events
| Event | Description |
|---|---|
MouseDown |
Handle mouse down for dragging and selection |
MouseMove |
Handle mouse movement for dragging and resizing |
MouseUp |
Handle mouse release to end dragging/resizing |
Resize |
Update connection points and hit areas when size changes |
HitDetected |
Triggered when a hit test area is activated |
Event Handling Examples
var shape = new BeepShape
{
ShapeType = BeepShapeType.Rectangle,
ShapeText = "Process"
};
// Handle shape selection
shape.HitDetected += (s, e) => {
if (e.HitTest.Name == "Shape")
{
shape.IsSelected = !shape.IsSelected;
UpdateSelectionUI(shape.IsSelected);
}
};
// Handle custom mouse interactions
shape.MouseDown += (s, e) => {
if (e.Button == MouseButtons.Right)
{
ShowContextMenu(shape, e.Location);
}
};
Examples
Flowchart Node
public BeepShape CreateFlowchartNode(string text, BeepShapeType shapeType, Point location)
{
var node = new BeepShape
{
ShapeType = shapeType,
ShapeText = text,
Size = new Size(120, 60),
Location = location,
BackColor = Color.LightBlue,
BorderColor = Color.DarkBlue,
BorderThickness = 2,
Font = new Font("Arial", 10, FontStyle.Bold),
ForeColor = Color.DarkBlue,
AllowDrag = true,
AllowResize = true,
ShowConnectionPoints = true
};
// Add to form
this.Controls.Add(node);
return node;
}
// Create flowchart elements
var startNode = CreateFlowchartNode("Start", BeepShapeType.Ellipse, new Point(50, 50));
var processNode = CreateFlowchartNode("Process Data", BeepShapeType.Rectangle, new Point(50, 150));
var decisionNode = CreateFlowchartNode("Valid?", BeepShapeType.Diamond, new Point(50, 250));
Diagram Designer
public class DiagramDesigner : UserControl
{
private List shapes = new List();
private BeepShape selectedShape;
public void AddShape(BeepShapeType shapeType, Point location)
{
var shape = new BeepShape
{
ShapeType = shapeType,
Size = GetDefaultSize(shapeType),
Location = location,
BackColor = Color.White,
BorderColor = Color.Black,
BorderThickness = 1,
AllowDrag = true,
AllowResize = true
};
// Configure based on shape type
switch (shapeType)
{
case BeepShapeType.Star:
shape.StarPoints = 5;
shape.StarInnerRatio = 0.4f;
shape.FillStyle = ShapeFillStyle.Gradient;
shape.GradientStartColor = Color.Yellow;
shape.GradientEndColor = Color.Orange;
break;
case BeepShapeType.Rectangle:
shape.CornerRadius = 5;
break;
case BeepShapeType.Line:
shape.ShowArrowHead = true;
shape.ArrowHeadSize = 10;
break;
}
// Handle selection
shape.HitDetected += (s, e) => {
SelectShape(shape);
};
shapes.Add(shape);
this.Controls.Add(shape);
}
private void SelectShape(BeepShape shape)
{
// Deselect previous
if (selectedShape != null)
selectedShape.IsSelected = false;
// Select new shape
selectedShape = shape;
selectedShape.IsSelected = true;
// Update property panel
UpdatePropertyPanel(selectedShape);
}
private Size GetDefaultSize(BeepShapeType shapeType)
{
return shapeType switch
{
BeepShapeType.Line => new Size(100, 2),
BeepShapeType.Ellipse => new Size(80, 80),
BeepShapeType.Star => new Size(100, 100),
_ => new Size(100, 60)
};
}
}
Network Diagram
public void CreateNetworkDiagram()
{
// Server node
var server = new BeepShape
{
ShapeType = BeepShapeType.Rectangle,
ShapeText = "Server",
Size = new Size(100, 60),
Location = new Point(200, 50),
BackColor = Color.LightGray,
BorderColor = Color.Black,
CornerRadius = 8
};
// Client nodes
var client1 = CreateClientNode("Client 1", new Point(50, 200));
var client2 = CreateClientNode("Client 2", new Point(200, 200));
var client3 = CreateClientNode("Client 3", new Point(350, 200));
// Connection lines
var connection1 = CreateConnectionLine(server, client1);
var connection2 = CreateConnectionLine(server, client2);
var connection3 = CreateConnectionLine(server, client3);
// Add all to form
this.Controls.AddRange(new Control[] {
server, client1, client2, client3,
connection1, connection2, connection3
});
}
private BeepShape CreateClientNode(string name, Point location)
{
return new BeepShape
{
ShapeType = BeepShapeType.Ellipse,
ShapeText = name,
Size = new Size(80, 80),
Location = location,
BackColor = Color.LightBlue,
BorderColor = Color.DarkBlue,
Font = new Font("Arial", 9)
};
}
private BeepShape CreateConnectionLine(BeepShape start, BeepShape end)
{
var line = new BeepShape
{
ShapeType = BeepShapeType.Line,
ShowArrowHead = true,
ArrowHeadSize = 8,
BorderColor = Color.Gray,
BorderThickness = 2,
AllowDrag = false,
AllowResize = false
};
// Connect the line to the shapes
line.ConnectTo(start, true);
line.ConnectTo(end, false);
return line;
}
Interactive Shape with Animations
public class AnimatedShape : BeepShape
{
private Timer animationTimer;
private float currentRotation = 0f;
public bool IsAnimating { get; private set; }
public AnimatedShape()
{
animationTimer = new Timer { Interval = 50 };
animationTimer.Tick += AnimationTimer_Tick;
}
public void StartRotationAnimation()
{
IsAnimating = true;
animationTimer.Start();
}
public void StopRotationAnimation()
{
IsAnimating = false;
animationTimer.Stop();
}
private void AnimationTimer_Tick(object sender, EventArgs e)
{
currentRotation += 5f;
if (currentRotation >= 360f)
currentRotation = 0f;
RotationAngle = currentRotation;
Invalidate();
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
animationTimer?.Dispose();
}
base.Dispose(disposing);
}
}
Connections
BeepShape supports connecting shapes together to create relationships and data flow diagrams:
Basic Connection
// Create two shapes
var sourceShape = new BeepShape { ShapeType = BeepShapeType.Rectangle };
var targetShape = new BeepShape { ShapeType = BeepShapeType.Ellipse };
// Create a connecting line
var connector = new BeepShape
{
ShapeType = BeepShapeType.Line,
ShowArrowHead = true
};
// Connect the line to both shapes
connector.ConnectTo(sourceShape, true); // Connect start to source
connector.ConnectTo(targetShape, false); // Connect end to target
Connection Management
public class ConnectionManager
{
private List connectors = new List();
public BeepShape CreateConnection(BeepShape from, BeepShape to, string label = "")
{
var connector = new BeepShape
{
ShapeType = BeepShapeType.Line,
ShowArrowHead = true,
ArrowHeadSize = 10,
BorderColor = Color.DarkGray,
BorderThickness = 2,
ShapeText = label
};
connector.ConnectTo(from, true);
connector.ConnectTo(to, false);
connectors.Add(connector);
return connector;
}
public void RemoveConnection(BeepShape connector)
{
connector.Disconnect(true); // Disconnect from start
connector.Disconnect(false); // Disconnect from end
connectors.Remove(connector);
}
public void UpdateConnections()
{
foreach (var connector in connectors)
{
connector.Invalidate(); // Redraw with updated positions
}
}
}
Connection points are automatically positioned at the top, right, bottom, and left of each shape. Use ShowConnectionPoints = true to visualize them during design.
Theming
BeepShape integrates with the Beep theming system to provide consistent appearance:
Theme Integration
var themedShape = new BeepShape
{
ShapeType = BeepShapeType.Rectangle,
Theme = "DarkTheme"
};
// Theme properties are automatically applied:
// - BorderColor uses theme.BorderColor
// - GradientStartColor uses theme.GradientStartColor
// - GradientEndColor uses theme.GradientEndColor
// - BackColor uses theme.BackColor
Custom Themed Shapes
public void CreateThemedDiagram(string themeName)
{
var shapes = new[]
{
new BeepShape { ShapeType = BeepShapeType.Rectangle, ShapeText = "Input" },
new BeepShape { ShapeType = BeepShapeType.Diamond, ShapeText = "Decision" },
new BeepShape { ShapeType = BeepShapeType.Ellipse, ShapeText = "Output" }
};
foreach (var shape in shapes)
{
shape.Theme = themeName;
shape.FillStyle = ShapeFillStyle.Gradient;
shape.ApplyTheme(); // Ensure theme is applied
this.Controls.Add(shape);
}
}
BeepShape automatically applies theme colors to all visual elements. Use FillStyle = Gradient with theme colors for professional-looking shapes.
Best Practices
🎨 Design Guidelines
- Consistent sizing: Use standard sizes for similar shape types
- Color coding: Use consistent colors to represent different categories
- Text placement: Keep text concise and centered within shapes
- Connection clarity: Use arrow heads to indicate direction of flow
- Shape semantics: Use appropriate shapes for their intended meaning (diamond for decisions, etc.)
⚡ Performance
- Caching: BeepShape automatically caches GraphicsPath objects for better performance
- Hit testing: Use hit areas efficiently for interactive elements
- Rendering: Avoid unnecessary redraws by checking if changes actually affect appearance
- Memory: Dispose of custom brushes and pens in drawing methods
- Connection updates: Batch connection updates when moving multiple shapes
🖱️ Interaction Design
- Selection feedback: Provide clear visual feedback when shapes are selected
- Resize handles: Show resize handles only when needed to reduce visual clutter
- Drag behavior: Implement smooth dragging with appropriate cursors
- Connection points: Make connection points visible during connection operations
- Context menus: Provide right-click context menus for shape operations
♿ Accessibility
- Text contrast: Ensure sufficient contrast between text and shape background
- Size constraints: Maintain minimum sizes for readability
- Keyboard support: Consider adding keyboard navigation for accessibility
- Screen readers: Provide meaningful text content for shapes
- Focus indicators: Ensure focused shapes have clear visual indicators
When using rotation, be aware that hit testing areas may not align perfectly with visual appearance. Test interaction carefully with rotated shapes.
BeepShape automatically manages connection point updates when shapes are moved or resized, ensuring connections remain accurate.
Use the ShapeText property combined with appropriate fonts to create professional-looking diagram elements with clear labeling.