diff --git a/LcdDrawExample/ExamplesDialog.cs b/LcdDrawExample/ExamplesDialog.cs
new file mode 100644
index 0000000..ed19102
--- /dev/null
+++ b/LcdDrawExample/ExamplesDialog.cs
@@ -0,0 +1,68 @@
+using System;
+using MonoBrickFirmware.Display;
+using MonoBrickFirmware.Display.Dialogs;
+
+namespace LcdDraw
+{
+ public class ExamplesDialog: Dialog{
+
+ private int _currentScreen;
+ private Point _center;
+
+ public ExamplesDialog(string title) :
+ base(Font.MediumFont, title, Lcd.Width, Lcd.Height-(int)Font.MediumFont.maxHeight)
+ {
+ _currentScreen = 1;
+ _center = new Point (Lcd.Width / 2, Lcd.Height / 2);
+ }
+
+ protected override bool OnEnterAction ()
+ {
+ _currentScreen = (_currentScreen == 1 ? 2 : 1);
+ Lcd.Instance.Clear ();
+
+ return false; // no exit
+ }
+
+ protected override bool OnEscape()
+ {
+ return true; // exit
+ }
+
+ protected override void OnDrawContent ()
+ {
+ if (_currentScreen == 1)
+ DrawFirstScreen ();
+ else
+ DrawSecondScreen ();
+ }
+
+ private void DrawFirstScreen()
+ {
+ Lcd.Instance.DrawLine( new Point (0, 0), new Point (Lcd.Width-1, Lcd.Height-1), true);
+ Lcd.Instance.DrawLine( new Point (0, Lcd.Height-1), new Point (Lcd.Width-1, 0), true);
+ Lcd.Instance.DrawLine( new Point (40, 40), new Point (Lcd.Width-40, Lcd.Height-40), true);
+ Lcd.Instance.DrawLine( new Point (40, 100), new Point (Lcd.Width-20, Lcd.Height-60), true);
+
+ Lcd.Instance.DrawCircle (_center, 60, true);
+ Lcd.Instance.DrawCircle (_center, 50, true);
+ Lcd.Instance.DrawCircle (_center, 40, true);
+ Lcd.Instance.DrawCircleFilled (_center, 30, true);
+ Lcd.Instance.DrawCircleFilled (_center, 20, false);
+ Lcd.Instance.DrawCircleFilled (_center, 10, true);
+
+ Lcd.Instance.DrawEllipse (_center, 60, 30, true);
+ }
+
+ private void DrawSecondScreen()
+ {
+ Lcd.Instance.DrawEllipseFilled (_center, 60, 30, true);
+ Lcd.Instance.DrawEllipseFilled (new Point(0, Lcd.Height/2) , 60, 30, false);
+
+ var r = new Rectangle (new Point (15, 28), new Point (Lcd.Width - 15, Lcd.Height - 25));
+ Lcd.Instance.DrawRectangle (r, true);
+ }
+
+ }
+}
+
diff --git a/LcdDrawExample/LcdDrawExample.csproj b/LcdDrawExample/LcdDrawExample.csproj
new file mode 100644
index 0000000..f8eb687
--- /dev/null
+++ b/LcdDrawExample/LcdDrawExample.csproj
@@ -0,0 +1,44 @@
+
+
+
+ Debug
+ AnyCPU
+ 8.0.30703
+ 2.0
+ {2730A667-E9ED-4CA7-8281-CF04EB9707BC}
+ Exe
+ LcdDrawExample
+ LcdDrawExample
+
+
+ true
+ full
+ false
+ bin\Debug
+ DEBUG;
+ prompt
+ 4
+ true
+
+
+ true
+ bin\Release
+ prompt
+ 4
+ true
+
+
+
+
+ {67261E03-D263-4C42-A5AD-2A4820231B28}
+ MonoBrickFirmware
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/LcdDrawExample/Program.cs b/LcdDrawExample/Program.cs
new file mode 100644
index 0000000..3fba88c
--- /dev/null
+++ b/LcdDrawExample/Program.cs
@@ -0,0 +1,14 @@
+using System;
+using MonoBrickFirmware.Display.Dialogs;
+
+namespace LcdDraw
+{
+ public class Program
+ {
+ public static void Main (string[] args)
+ {
+ var examplesDialog = new ExamplesDialog ("Draw example");
+ examplesDialog.Show ();
+ }
+ }
+}
\ No newline at end of file
diff --git a/MonoBrick.sln b/MonoBrick.sln
index 48cbd14..69a39b6 100644
--- a/MonoBrick.sln
+++ b/MonoBrick.sln
@@ -52,6 +52,8 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution
version.txt = version.txt
EndProjectSection
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LcdDrawExample", "LcdDrawExample\LcdDrawExample.csproj", "{2730A667-E9ED-4CA7-8281-CF04EB9707BC}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -72,6 +74,14 @@ Global
{11C84BA4-9A8A-4BF2-AA7B-2D45AC63ACAE}.Release|Any CPU.ActiveCfg = Release|x86
{11C84BA4-9A8A-4BF2-AA7B-2D45AC63ACAE}.Release|x86.ActiveCfg = Release|x86
{11C84BA4-9A8A-4BF2-AA7B-2D45AC63ACAE}.Release|x86.Build.0 = Release|x86
+ {2730A667-E9ED-4CA7-8281-CF04EB9707BC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {2730A667-E9ED-4CA7-8281-CF04EB9707BC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {2730A667-E9ED-4CA7-8281-CF04EB9707BC}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {2730A667-E9ED-4CA7-8281-CF04EB9707BC}.Debug|x86.Build.0 = Debug|Any CPU
+ {2730A667-E9ED-4CA7-8281-CF04EB9707BC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {2730A667-E9ED-4CA7-8281-CF04EB9707BC}.Release|Any CPU.Build.0 = Release|Any CPU
+ {2730A667-E9ED-4CA7-8281-CF04EB9707BC}.Release|x86.ActiveCfg = Release|Any CPU
+ {2730A667-E9ED-4CA7-8281-CF04EB9707BC}.Release|x86.Build.0 = Release|Any CPU
{314570C2-D0F1-45D2-868D-FA54E2F538F8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{314570C2-D0F1-45D2-868D-FA54E2F538F8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{314570C2-D0F1-45D2-868D-FA54E2F538F8}.Debug|x86.ActiveCfg = Debug|Any CPU
@@ -87,7 +97,6 @@ Global
{3FCBF457-301A-4F4E-B2E2-D6D2C680FDAC}.Release|x86.ActiveCfg = Release|x86
{3FCBF457-301A-4F4E-B2E2-D6D2C680FDAC}.Release|x86.Build.0 = Release|x86
{46A2BC89-7B2D-40CC-84D2-67A145924A0B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {46A2BC89-7B2D-40CC-84D2-67A145924A0B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{46A2BC89-7B2D-40CC-84D2-67A145924A0B}.Debug|x86.ActiveCfg = Debug|Any CPU
{46A2BC89-7B2D-40CC-84D2-67A145924A0B}.Debug|x86.Build.0 = Debug|Any CPU
{46A2BC89-7B2D-40CC-84D2-67A145924A0B}.Release|Any CPU.ActiveCfg = Release|Any CPU
@@ -113,7 +122,6 @@ Global
{61423DCA-229C-4A9C-B49A-3F2C1432B8F0}.Release|x86.ActiveCfg = Release|x86
{61423DCA-229C-4A9C-B49A-3F2C1432B8F0}.Release|x86.Build.0 = Release|x86
{640B405A-3BE2-423C-A32F-310EE9C4DFF1}.Debug|Any CPU.ActiveCfg = Debug|x86
- {640B405A-3BE2-423C-A32F-310EE9C4DFF1}.Debug|Any CPU.Build.0 = Debug|x86
{640B405A-3BE2-423C-A32F-310EE9C4DFF1}.Debug|x86.ActiveCfg = Debug|x86
{640B405A-3BE2-423C-A32F-310EE9C4DFF1}.Debug|x86.Build.0 = Debug|x86
{640B405A-3BE2-423C-A32F-310EE9C4DFF1}.Release|Any CPU.ActiveCfg = Release|x86
@@ -121,7 +129,6 @@ Global
{640B405A-3BE2-423C-A32F-310EE9C4DFF1}.Release|x86.ActiveCfg = Release|x86
{640B405A-3BE2-423C-A32F-310EE9C4DFF1}.Release|x86.Build.0 = Release|x86
{64CFD3F7-4F67-4353-9617-BA4804A2F389}.Debug|Any CPU.ActiveCfg = Debug|x86
- {64CFD3F7-4F67-4353-9617-BA4804A2F389}.Debug|Any CPU.Build.0 = Debug|x86
{64CFD3F7-4F67-4353-9617-BA4804A2F389}.Debug|x86.ActiveCfg = Debug|x86
{64CFD3F7-4F67-4353-9617-BA4804A2F389}.Debug|x86.Build.0 = Debug|x86
{64CFD3F7-4F67-4353-9617-BA4804A2F389}.Release|Any CPU.ActiveCfg = Release|x86
@@ -129,13 +136,13 @@ Global
{64CFD3F7-4F67-4353-9617-BA4804A2F389}.Release|x86.ActiveCfg = Release|x86
{64CFD3F7-4F67-4353-9617-BA4804A2F389}.Release|x86.Build.0 = Release|x86
{67261E03-D263-4C42-A5AD-2A4820231B28}.Debug|Any CPU.ActiveCfg = Debug|x86
+ {67261E03-D263-4C42-A5AD-2A4820231B28}.Debug|Any CPU.Build.0 = Debug|x86
{67261E03-D263-4C42-A5AD-2A4820231B28}.Debug|x86.ActiveCfg = Debug|x86
{67261E03-D263-4C42-A5AD-2A4820231B28}.Debug|x86.Build.0 = Debug|x86
{67261E03-D263-4C42-A5AD-2A4820231B28}.Release|Any CPU.ActiveCfg = Release|x86
{67261E03-D263-4C42-A5AD-2A4820231B28}.Release|x86.ActiveCfg = Release|x86
{67261E03-D263-4C42-A5AD-2A4820231B28}.Release|x86.Build.0 = Release|x86
{75E781D0-7313-445B-8430-DECB0AD3C96E}.Debug|Any CPU.ActiveCfg = Debug|x86
- {75E781D0-7313-445B-8430-DECB0AD3C96E}.Debug|Any CPU.Build.0 = Debug|x86
{75E781D0-7313-445B-8430-DECB0AD3C96E}.Debug|x86.ActiveCfg = Debug|x86
{75E781D0-7313-445B-8430-DECB0AD3C96E}.Debug|x86.Build.0 = Debug|x86
{75E781D0-7313-445B-8430-DECB0AD3C96E}.Release|Any CPU.ActiveCfg = Release|x86
@@ -188,7 +195,6 @@ Global
{E069E7FC-8331-40B1-BB45-119E02210B96}.Release|x86.ActiveCfg = Release|x86
{E069E7FC-8331-40B1-BB45-119E02210B96}.Release|x86.Build.0 = Release|x86
{E5C67E4C-5BDE-419A-9014-241E4FCFD2E8}.Debug|Any CPU.ActiveCfg = Debug|x86
- {E5C67E4C-5BDE-419A-9014-241E4FCFD2E8}.Debug|Any CPU.Build.0 = Debug|x86
{E5C67E4C-5BDE-419A-9014-241E4FCFD2E8}.Debug|x86.ActiveCfg = Debug|x86
{E5C67E4C-5BDE-419A-9014-241E4FCFD2E8}.Debug|x86.Build.0 = Debug|x86
{E5C67E4C-5BDE-419A-9014-241E4FCFD2E8}.Release|Any CPU.ActiveCfg = Release|x86
diff --git a/MonoBrickFirmware/Display/Lcd.cs b/MonoBrickFirmware/Display/Lcd.cs
index 1d6c705..9838cde 100644
--- a/MonoBrickFirmware/Display/Lcd.cs
+++ b/MonoBrickFirmware/Display/Lcd.cs
@@ -30,8 +30,21 @@ public enum Alignment { Left, Center, Right };
private static readonly Lcd instance = new Lcd();
+ public static bool IsPixelInLcd(Point pixel)
+ {
+ return (pixel.X >= 0) && (pixel.Y >= 0) && (pixel.X <= Lcd.Width) && (pixel.Y <= Lcd.Height);
+ }
+
+ public static bool IsPixelInLcd(int x, int y)
+ {
+ return (x >= 0) && (y >= 0) && (x <= Lcd.Width) && (y <= Lcd.Height);
+ }
+
public void SetPixel(int x, int y, bool color)
{
+ if (!IsPixelInLcd (x, y))
+ return;
+
int index = (x/8)+ y * bytesPrLine;
int bit = x & 0x7;
if (color)
@@ -46,7 +59,7 @@ public enum ArrowOrientation{Left, Right, Down, Up}
public bool IsPixelSet (int x, int y)
{
- int index = (x / 8) + y * 23;
+ int index = (x / 8) + y * bytesPrLine;
int bit = x & 0x7;
return (displayBuf[index] & (1 << bit)) != 0;
}
@@ -172,45 +185,12 @@ public void DrawBox(Rectangle r, bool setOrClear)
for (int y = r.P1.Y; y <= r.P2.Y; ++y)
DrawHLine(new Point(r.P1.X, y), length, setOrClear);
}
-
+
public void DrawBitmap(Bitmap bm, Point p)
{
DrawBitmap(bm.GetStream(), p, bm.Width, bm.Height, true);
}
- public void DrawLine (Point start, Point end, bool color)
- {
- int height = Math.Abs (end.Y - start.Y);
- int width = Math.Abs (end.X - start.X);
-
- int ix = start.X;
- int iy = start.Y;
- int sx = start.X < end.X ? 1 : -1;
- int sy = start.Y < end.Y ? 1 : -1;
-
- int err = width + (-height);
- int e2;
-
- do {
- SetPixel (ix, iy, color);
-
- if (ix == end.X && iy == end.Y)
- break;
-
- e2 = 2 * err;
- if (e2 > (-height)) {
- err += (-height);
- ix += sx;
- }
- if (e2 < width) {
- err += width;
- iy += sy;
- }
-
- } while (true);
-
- }
-
public void DrawBitmap(BitStreamer bs, Point p, uint xsize, uint ysize, bool color)
{
for (int yPos = p.Y; yPos != p.Y+ysize; yPos++)
diff --git a/MonoBrickFirmware/Display/LcdDrawCircle.cs b/MonoBrickFirmware/Display/LcdDrawCircle.cs
new file mode 100644
index 0000000..5ffb549
--- /dev/null
+++ b/MonoBrickFirmware/Display/LcdDrawCircle.cs
@@ -0,0 +1,59 @@
+using System;
+
+namespace MonoBrickFirmware.Display
+{
+ public static class DrawCircleLcdExtension
+ {
+
+ public static void DrawCircle (this Lcd lcd, Point center, ushort radius, bool color)
+ {
+ int f = 1 - radius;
+ int ddF_x = 0;
+ int ddF_y = -2 * radius;
+ int x = 0;
+ int y = radius;
+
+ var right = new Point(center.X + radius, center.Y);
+ var top = new Point (center.X, center.Y - radius);
+ var left = new Point (center.X - radius, center.Y);
+ var bottom = new Point(center.X, center.Y + radius);
+
+ lcd.SetPixel (right.X, right.Y, color);
+ lcd.SetPixel (top.X, top.Y, color);
+ lcd.SetPixel (left.X, left.Y, color);
+ lcd.SetPixel (bottom.X, bottom.Y, color);
+
+ while (x < y) {
+ if (f >= 0) {
+ y--;
+ ddF_y += 2;
+ f += ddF_y;
+ }
+ x++;
+ ddF_x += 2;
+ f += ddF_x + 1;
+
+ lcd.SetPixel (center.X + x, center.Y + y, color);
+ lcd.SetPixel (center.X - x, center.Y + y, color);
+ lcd.SetPixel (center.X + x, center.Y - y, color);
+ lcd.SetPixel (center.X - x, center.Y - y, color);
+ lcd.SetPixel (center.X + y, center.Y + x, color);
+ lcd.SetPixel (center.X - y, center.Y + x, color);
+ lcd.SetPixel (center.X + y, center.Y - x, color);
+ lcd.SetPixel (center.X - y, center.Y - x, color);
+ }
+ }
+
+ public static void DrawCircleFilled (this Lcd lcd, Point center, ushort radius, bool color)
+ {
+ for (int y = -radius; y <= radius; y++) {
+ for (int x = -radius; x <= radius; x++) {
+ if (x * x + y * y <= radius * radius) {
+ lcd.SetPixel (center.X + x, center.Y + y, color);
+ }
+ }
+ }
+ }
+
+ }
+}
diff --git a/MonoBrickFirmware/Display/LcdDrawEllipse.cs b/MonoBrickFirmware/Display/LcdDrawEllipse.cs
new file mode 100644
index 0000000..13d12e5
--- /dev/null
+++ b/MonoBrickFirmware/Display/LcdDrawEllipse.cs
@@ -0,0 +1,79 @@
+using System;
+
+namespace MonoBrickFirmware.Display
+{
+ public static class DraeEllipseLcdExtension
+ {
+
+ public static void DrawEllipse(this Lcd lcd, Point center, ushort radiusA, ushort radiusB, bool color)
+ {
+
+ int dx = 0;
+ int dy = radiusB;
+ int a2 = radiusA * radiusA;
+ int b2 = radiusB * radiusB;
+ int err = b2 - (2 * radiusB - 1) * a2;
+ int e2;
+
+ do {
+ lcd.SetPixel(center.X + dx, center.Y + dy, color); /* I. Quadrant */
+ lcd.SetPixel(center.X - dx, center.Y + dy, color); /* II. Quadrant */
+ lcd.SetPixel(center.X - dx, center.Y - dy, color); /* III. Quadrant */
+ lcd.SetPixel(center.X + dx, center.Y - dy, color); /* IV. Quadrant */
+
+ e2 = 2 * err;
+
+ if (e2 < (2 * dx + 1) * b2)
+ {
+ dx++;
+ err += (2 * dx + 1) * b2;
+ }
+
+ if (e2 > -(2 * dy - 1) * a2)
+ {
+ dy--;
+ err -= (2 * dy - 1) * a2;
+ }
+ } while (dy >= 0);
+
+ while (dx++ < radiusA)
+ {
+ lcd.SetPixel(center.X + dx, center.Y, color);
+ lcd.SetPixel(center.X - dx, center.Y, color);
+ }
+ }
+
+ public static void DrawEllipseFilled
+ (this Lcd lcd, Point center, ushort radiusA, ushort radiusB, bool color)
+ {
+ int hh = radiusB * radiusB;
+ int ww = radiusA * radiusA;
+ int hhww = hh * ww;
+ int x0 = radiusA;
+ int dx = 0;
+
+ // do the horizontal diameter
+ for (int x = -radiusA; x <= radiusA; x++)
+ lcd.SetPixel(center.X + x, center.Y, color);
+
+ // now do both halves at the same time, away from the diameter
+ for (int y = 1; y <= radiusB; y++)
+ {
+ int x1 = x0 - (dx - 1); // try slopes of dx - 1 or more
+
+ for (; x1 > 0; x1--)
+ if (x1 * x1 * hh + y * y * ww <= hhww)
+ break;
+
+ dx = x0 - x1; // current approximation of the slope
+ x0 = x1;
+
+ for (int x = -x0; x <= x0; x++) {
+ lcd.SetPixel(center.X + x, center.Y - y, color);
+ lcd.SetPixel(center.X + x, center.Y + y, color);
+ }
+ }
+ }
+
+ }
+}
diff --git a/MonoBrickFirmware/Display/LcdDrawLine.cs b/MonoBrickFirmware/Display/LcdDrawLine.cs
new file mode 100644
index 0000000..b7f746a
--- /dev/null
+++ b/MonoBrickFirmware/Display/LcdDrawLine.cs
@@ -0,0 +1,41 @@
+using System;
+
+namespace MonoBrickFirmware.Display
+{
+ public static class DrawLineLcdExtension
+ {
+
+ public static void DrawLine (this Lcd lcd, Point start, Point end, bool color)
+ {
+ int height = Math.Abs (end.Y - start.Y);
+ int width = Math.Abs (end.X - start.X);
+
+ int ix = start.X;
+ int iy = start.Y;
+ int sx = start.X < end.X ? 1 : -1;
+ int sy = start.Y < end.Y ? 1 : -1;
+
+ int err = width + (-height);
+ int e2;
+
+ do {
+ lcd.SetPixel (ix, iy, color);
+
+ if (ix == end.X && iy == end.Y)
+ break;
+
+ e2 = 2 * err;
+ if (e2 > (-height)) {
+ err += (-height);
+ ix += sx;
+ }
+ if (e2 < width) {
+ err += width;
+ iy += sy;
+ }
+
+ } while (true);
+ }
+
+ }
+}
diff --git a/MonoBrickFirmware/Display/LcdDrawRectangle.cs b/MonoBrickFirmware/Display/LcdDrawRectangle.cs
new file mode 100644
index 0000000..8e749cc
--- /dev/null
+++ b/MonoBrickFirmware/Display/LcdDrawRectangle.cs
@@ -0,0 +1,38 @@
+using System;
+
+namespace MonoBrickFirmware.Display
+{
+ public static class DrawRectangleLcdExtension
+ {
+
+ public static void DrawRectangle(this Lcd lcd, Rectangle r, bool color)
+ {
+ int length = r.P2.X - r.P1.X;
+ int height = r.P2.Y - r.P1.Y;
+
+ DrawHLineInLcd(lcd, new Point(r.P1.X, r.P1.Y), length, color);
+ DrawHLineInLcd(lcd, new Point(r.P1.X, r.P2.Y), length, color);
+
+ DrawVLineInLcd(lcd, new Point(r.P1.X, r.P1.Y+1), height-2, color);
+ DrawVLineInLcd(lcd, new Point(r.P2.X, r.P1.Y+1), height-2, color);
+ }
+
+ private static void DrawHLineInLcd(Lcd lcd, Point startPoint, int length, bool color)
+ {
+ for (var x = 0; x <= length; x++) {
+ lcd.SetPixel (startPoint.X + x, startPoint.Y, color);
+ }
+
+ }
+
+ private static void DrawVLineInLcd(Lcd lcd, Point startPoint, int height, bool color)
+ {
+ for (var y = 0; y <= height; y++) {
+ lcd.SetPixel (startPoint.X, startPoint.Y + y, color);
+ }
+
+ }
+
+
+ }
+}
diff --git a/MonoBrickFirmware/MonoBrickFirmware.csproj b/MonoBrickFirmware/MonoBrickFirmware.csproj
index 369d021..a745100 100644
--- a/MonoBrickFirmware/MonoBrickFirmware.csproj
+++ b/MonoBrickFirmware/MonoBrickFirmware.csproj
@@ -9,6 +9,7 @@
Library
MonoBrickFirmware
MonoBrickFirmware
+ False
true
@@ -119,6 +120,10 @@
+
+
+
+