Skip to content

Instantly share code, notes, and snippets.

@TheCloudlessSky
Created June 27, 2013 22:25
Show Gist options
  • Save TheCloudlessSky/5880943 to your computer and use it in GitHub Desktop.
Save TheCloudlessSky/5880943 to your computer and use it in GitHub Desktop.
public class Line
{
public Point Start { get; set; }
public Point End { get; set; }
public int Width { get; set; }
public Color Color { get; set; }
}
public class LineControl : Panel
{
private readonly List<Line> lines = new List<Line>();
private readonly ComboBox colorPicker = new ComboBox();
private readonly NumericUpDown thickness = new NumericUpDown();
private readonly ComboBox toolPicker = new ComboBox();
public LineControl()
{
colorPicker.Items.AddRange(new object[] { Color.Black, Color.Red, Color.Green, Color.Blue });
colorPicker.Location = new Point(0, 0);
colorPicker.Width = 100;
colorPicker.DropDownStyle = ComboBoxStyle.DropDownList;
colorPicker.SelectedIndex = 0;
colorPicker.DisplayMember = "Name";
Controls.Add(colorPicker);
thickness.Location = new Point(110, 0);
thickness.Maximum = 10;
thickness.Minimum = 1;
thickness.Width = 50;
thickness.Value = 1;
Controls.Add(thickness);
toolPicker.Items.AddRange(new object[] { Tool.Line, Tool.Pointer });
toolPicker.Location = new Point(170, 0);
toolPicker.DropDownStyle = ComboBoxStyle.DropDownList;
toolPicker.Width = 60;
toolPicker.SelectedIndexChanged += OnSelectedToolChanged;
toolPicker.SelectedIndex = 0;
Controls.Add(toolPicker);
// Optimize drawing and reduce "flickering" when doing lots of paints.
SetStyle(ControlStyles.UserPaint, true);
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
SetStyle(ControlStyles.DoubleBuffer, true);
}
private void OnSelectedToolChanged(object sender, EventArgs e)
{
switch (GetSelectedTool())
{
case Tool.Line:
Cursor = Cursors.Cross;
break;
case Tool.Pointer:
Cursor = Cursors.Default;
break;
}
}
private Tool GetSelectedTool()
{
return (Tool)toolPicker.SelectedItem;
}
protected override void OnPaint(PaintEventArgs e)
{
// Reset the background.
e.Graphics.Clear(Color.White);
// Smooth the lines.
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
// Draw each line.
foreach (var line in lines)
{
using (var pen = new Pen(line.Color, line.Width))
{
e.Graphics.DrawLine(pen, line.Start, line.End);
}
}
}
protected override void OnMouseDown(MouseEventArgs e)
{
switch (GetSelectedTool())
{
case Tool.Line:
OnLineToolMouseDown(e);
break;
case Tool.Pointer:
OnPointerToolMouseDown(e);
break;
}
}
private void OnLineToolMouseDown(MouseEventArgs e)
{
if (e.Button != MouseButtons.Left) return;
// Start the drag operation of the new line.
var dragLine = new Line();
dragLine.Color = (Color)colorPicker.SelectedItem;
dragLine.Width = (int)thickness.Value;
lines.Add(dragLine);
dragLine.Start = dragLine.End = e.Location;
Refresh();
}
private void OnPointerToolMouseDown(MouseEventArgs e)
{
// TODO...
}
protected override void OnMouseMove(MouseEventArgs e)
{
switch (GetSelectedTool())
{
case Tool.Line:
OnLineToolMouseMove(e);
break;
case Tool.Pointer:
OnPointerToolMouseMove(e);
break;
}
}
private void OnLineToolMouseMove(MouseEventArgs e)
{
if (e.Button != MouseButtons.Left) return;
// Move the end point of the new line.
var dragLine = lines.Last();
dragLine.End = e.Location;
Refresh();
}
private void OnPointerToolMouseMove(MouseEventArgs e)
{
// TODO...
}
protected override void OnMouseUp(MouseEventArgs e)
{
switch (GetSelectedTool())
{
case Tool.Line:
OnLineToolMouseUp(e);
break;
case Tool.Pointer:
OnPointerToolMouseUp(e);
break;
}
}
private void OnLineToolMouseUp(MouseEventArgs e)
{
if (e.Button != MouseButtons.Left) return;
// Finish the drag operation of the new line.
var dragLine = lines.Last();
dragLine.End = e.Location;
Refresh();
}
private void OnPointerToolMouseUp(MouseEventArgs e)
{
// TODO...
}
}
public class MainForm : Form
{
public MainForm()
{
SuspendLayout();
var lineControl = new LineControl();
lineControl.Dock = DockStyle.Fill;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(500, 500);
this.Controls.Add(lineControl);
this.Text = "Main Form";
this.ResumeLayout(false);
}
}
public static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.Run(new MainForm());
}
}
// These should be classes so we don't have to do the "switch" statements.
public enum Tool
{
Line,
Pointer
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment