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
};
💡 Quick Tip

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 Tip

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);
    }
}
🎨 Theming Tip

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
⚠️ Rotation Warning

When using rotation, be aware that hit testing areas may not align perfectly with visual appearance. Test interaction carefully with rotated shapes.

✅ Auto-Updates

BeepShape automatically manages connection point updates when shapes are moved or resized, ensuring connections remain accurate.

💡 Pro Tip

Use the ShapeText property combined with appropriate fonts to create professional-looking diagram elements with clear labeling.