diff --git a/CairoObjective/CairoObjective.csproj b/CairoObjective/CairoObjective.csproj
new file mode 100644
index 0000000..730d608
--- /dev/null
+++ b/CairoObjective/CairoObjective.csproj
@@ -0,0 +1,13 @@
+
+
+
+ net6.0
+ enable
+ enable
+
+
+
+
+
+
+
diff --git a/CairoObjective/DrawObjects/Line.cs b/CairoObjective/DrawObjects/Line.cs
new file mode 100644
index 0000000..c22e8a6
--- /dev/null
+++ b/CairoObjective/DrawObjects/Line.cs
@@ -0,0 +1,21 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace CairoObjective.DrawObjects
+{
+ public class Line
+ {
+ public double X1, X2, Y1, Y2;
+
+ public Line(double x1, double y1, double x2, double y2)
+ {
+ X1 = x1;
+ X2 = x2;
+ Y1 = y1;
+ Y2 = y2;
+ }
+ }
+}
diff --git a/CairoObjective/Line.cs b/CairoObjective/Line.cs
new file mode 100644
index 0000000..755260c
--- /dev/null
+++ b/CairoObjective/Line.cs
@@ -0,0 +1,72 @@
+using Cairo;
+using CairoObjective.DrawObjects;
+
+namespace CairoObjective
+{
+#pragma warning disable CS8602 // Разыменование вероятной пустой ссылки.
+ public class Line
+ {
+ public static double DefaultSize = 1;
+ public static void Make(int pointX1, int pointY1, int pointX2, int pointY2, double size, Cairo.Color color)
+ {
+ Set.CheckContext();
+ var context = Set.Context;
+ context.SetSourceColor(color);
+ context.LineWidth = size;
+ context.MoveTo(pointX1, pointY1);
+ context.LineTo(pointX2, pointY2);
+ context.Stroke();
+ }
+ public static void Make(int pointX1, int pointY1, int pointX2, int pointY2, Cairo.Color color)
+ {
+ Set.CheckContext();
+ var context = Set.Context;
+ context.SetSourceColor(color);
+ context.LineWidth = DefaultSize;
+ context.MoveTo(pointX1, pointY1);
+ context.LineTo(pointX2, pointY2);
+ context.Stroke();
+ }
+ public static void Make(int pointX1, int pointY1, int pointX2, int pointY2, double size)
+ {
+ Set.CheckContext();
+ var context = Set.Context;
+ context.SetSourceColor(Set.Color);
+ context.LineWidth = size;
+ context.MoveTo(pointX1, pointY1);
+ context.LineTo(pointX2, pointY2);
+ context.Stroke();
+ }
+ public static void Make(int pointX1, int pointY1, int pointX2, int pointY2)
+ {
+ Set.CheckContext();
+ var context = Set.Context;
+ context.SetSourceColor(Set.Color);
+ context.LineWidth = DefaultSize;
+ context.MoveTo(pointX1, pointY1);
+ context.LineTo(pointX2, pointY2);
+ context.Stroke();
+ }
+ public static void Make(DrawObjects.Line line)
+ {
+ Set.CheckContext();
+ var context = Set.Context;
+ context.SetSourceColor(Set.Color);
+ context.LineWidth = DefaultSize;
+ context.MoveTo(line.X1, line.Y1);
+ context.LineTo(line.X2, line.Y2);
+ context.Stroke();
+ }
+ public static void Make(DrawObjects.Line line, Color color)
+ {
+ Set.CheckContext();
+ var context = Set.Context;
+ context.SetSourceColor(color);
+ context.LineWidth = DefaultSize;
+ context.MoveTo(line.X1, line.Y1);
+ context.LineTo(line.X2, line.Y2);
+ context.Stroke();
+ }
+
+ }
+}
diff --git a/CairoObjective/Set.cs b/CairoObjective/Set.cs
new file mode 100644
index 0000000..81da678
--- /dev/null
+++ b/CairoObjective/Set.cs
@@ -0,0 +1,30 @@
+namespace CairoObjective
+{
+ public static class Set
+ {
+ public static void CheckContext()
+ {
+ if (Context == null)
+ {
+ throw new NullReferenceException("Context is Null. Set context on Set class.");
+ }
+ }
+ public static Cairo.Context? Context;
+ public static Cairo.Color Color = new Cairo.Color(1,1,1);//White
+#pragma warning disable CS8602 // Разыменование вероятной пустой ссылки.
+ public static void Background(Cairo.Color color)
+ {
+ CheckContext();
+ var context = Set.Context;
+ context.SetSourceColor(color);
+ context.Paint();
+ }
+ public static void Background()
+ {
+ CheckContext();
+ var context = Set.Context;
+ context.SetSourceColor(Color);
+ context.Paint();
+ }
+ }
+}
diff --git a/CairoObjective/Text.cs b/CairoObjective/Text.cs
new file mode 100644
index 0000000..c1fb489
--- /dev/null
+++ b/CairoObjective/Text.cs
@@ -0,0 +1,49 @@
+namespace CairoObjective
+{
+#pragma warning disable CS8602 // Разыменование вероятной пустой ссылки.
+ public class Text
+ {
+ public static double DefaultFontSize = 20;//Default Font Size
+
+ public static void Make(string text, int pointX, int pointY, double size, Cairo.Color color)
+ {
+ Set.CheckContext();
+ var context = Set.Context;
+ context.SetSourceColor(color);
+ context.SetFontSize(size);
+ Cairo.TextExtents extents = context.TextExtents(text);
+ context.MoveTo(pointX - extents.Width / 2, pointY + extents.Height / 2);
+ context.ShowText(text);
+ }
+ public static void Make(string text, int pointX, int pointY, Cairo.Color color)
+ {
+ Set.CheckContext();
+ var context = Set.Context;
+ context.SetSourceColor(color);
+ context.SetFontSize(DefaultFontSize);
+ Cairo.TextExtents extents = context.TextExtents(text);
+ context.MoveTo(pointX - extents.Width / 2, pointY + extents.Height / 2);
+ context.ShowText(text);
+ }
+ public static void Make(string text, int pointX, int pointY, double size)
+ {
+ Set.CheckContext();
+ var context = Set.Context;
+ context.SetSourceColor(Set.Color);
+ context.SetFontSize(size);
+ Cairo.TextExtents extents = context.TextExtents(text);
+ context.MoveTo(pointX - extents.Width / 2, pointY + extents.Height / 2);
+ context.ShowText(text);
+ }
+ public static void Make(string text, int pointX, int pointY)
+ {
+ Set.CheckContext();
+ var context = Set.Context;
+ context.SetSourceColor(Set.Color);
+ context.SetFontSize(DefaultFontSize);
+ Cairo.TextExtents extents = context.TextExtents(text);
+ context.MoveTo(pointX - extents.Width / 2, pointY + extents.Height / 2);
+ context.ShowText(text);
+ }
+ }
+}
\ No newline at end of file
diff --git a/FractalTree.sln b/FractalTree.sln
new file mode 100644
index 0000000..13d7f3e
--- /dev/null
+++ b/FractalTree.sln
@@ -0,0 +1,31 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.4.33103.184
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CairoObjective", "CairoObjective\CairoObjective.csproj", "{943860CD-7811-4089-ACC8-FD57D67A4FE9}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FractalTreeGtk", "FractalTreeGtk\FractalTreeGtk.csproj", "{510C072F-F749-4343-A4C2-523358FA3F7E}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {943860CD-7811-4089-ACC8-FD57D67A4FE9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {943860CD-7811-4089-ACC8-FD57D67A4FE9}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {943860CD-7811-4089-ACC8-FD57D67A4FE9}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {943860CD-7811-4089-ACC8-FD57D67A4FE9}.Release|Any CPU.Build.0 = Release|Any CPU
+ {510C072F-F749-4343-A4C2-523358FA3F7E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {510C072F-F749-4343-A4C2-523358FA3F7E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {510C072F-F749-4343-A4C2-523358FA3F7E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {510C072F-F749-4343-A4C2-523358FA3F7E}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {6D5961A6-3340-47D1-8DA9-9A6219BD8501}
+ EndGlobalSection
+EndGlobal
diff --git a/FractalTree/CairoWindow.cs b/FractalTree/CairoWindow.cs
new file mode 100644
index 0000000..52f36ff
--- /dev/null
+++ b/FractalTree/CairoWindow.cs
@@ -0,0 +1,85 @@
+using Gtk;
+using CairoObjective;
+using System.Linq;
+using System.Diagnostics;
+
+namespace FractalTree
+{
+ class CairoWindow : Window
+ {
+ DrawingArea drawing = new DrawingArea();
+ DrawObjects.Grid grid;
+ int Scaler = 50;
+ int offsetX = 0;
+ int offsetY = 0;
+ public CairoWindow(string title) : base(title)
+ {
+ Fullscreen();
+ DeleteEvent += delegate { Application.Quit(); };
+ drawing.Drawn += OnDrawn;
+ KeyPressEvent += CairoWindow_KeyPressEvent;
+ Add(drawing);
+ ShowAll();
+ Line.DefaultSize = 2;
+ }
+
+ private void CairoWindow_KeyPressEvent(object o, KeyPressEventArgs args)
+ {
+ if(args.Event.Key == Gdk.Key.equal)
+ {
+ Trace.WriteLine("+");
+ Scaler++;
+ QueueDraw();
+ }
+ if (args.Event.Key == Gdk.Key.minus && Scaler > 1)
+ {
+ Trace.WriteLine("-");
+ Scaler--;
+ QueueDraw();
+ }
+ if (args.Event.Key == Gdk.Key.a)
+ {
+ Trace.WriteLine("←");
+ offsetX-=10;
+ QueueDraw();
+ }
+ if (args.Event.Key == Gdk.Key.d)
+ {
+ Trace.WriteLine("→");
+ offsetX+=10;
+ QueueDraw();
+ }
+ if (args.Event.Key == Gdk.Key.w)
+ {
+ Trace.WriteLine("↑");
+ offsetY += 10;
+ QueueDraw();
+ }
+ if (args.Event.Key == Gdk.Key.s)
+ {
+ Trace.WriteLine("↓");
+ offsetY -= 10;
+ QueueDraw();
+ }
+ }
+
+ private void OnDrawn(object sender, DrawnArgs args)
+ {
+ MainDrawer();
+ }
+ private void MainDrawer()
+ {
+ grid = new(AllocatedWidth, AllocatedHeight, Scaler, offsetX, offsetY);
+ Set.Context = Gdk.CairoHelper.Create(drawing.GdkWindow);
+ Set.Background(new Cairo.Color(0, 0, 0));
+ foreach(CairoObjective.DrawObjects.Line gridline in grid.LinesHorizontal)
+ {
+ Line.Make(gridline, new Cairo.Color(1,1,1));
+ }
+ foreach (CairoObjective.DrawObjects.Line gridline in grid.LinesVertical)
+ {
+ Line.Make(gridline, new Cairo.Color(1, 1, 1));
+ }
+ }
+ }
+}
diff --git a/FractalTree/DrawObjects/Grid.cs b/FractalTree/DrawObjects/Grid.cs
new file mode 100644
index 0000000..1495ba0
--- /dev/null
+++ b/FractalTree/DrawObjects/Grid.cs
@@ -0,0 +1,49 @@
+using CairoObjective.DrawObjects;
+using System;
+using System.Diagnostics;
+
+namespace FractalTree.DrawObjects
+{
+ internal class Grid
+ {
+ public Line[] LinesHorizontal;
+ public Line[] LinesVertical;
+ int Scaler;
+ int Width;
+ int Height;
+ int offsetX;
+ int offsetY;
+ ///
+ /// Make Grid Array of lines
+ ///
+ /// Width of Window
+ /// Height of Window
+ /// Pixels Per Lines
+ public Grid(int Width, int Height, int Scaler, int offsetX, int offsetY)
+ {
+ this.Width = Width;
+ this.Height = Height;
+ this.Scaler = Scaler;
+ this.offsetX = offsetX;
+ this.offsetY = offsetY;
+ LinesHorizontal = new Line[this.Width / Scaler + 1];
+ LinesVertical = new Line[this.Height / Scaler + 1];
+ MakeHorizontal();
+ MakeVertical();
+ }
+ private void MakeHorizontal()
+ {
+ for(int i = 0; i < Width / Scaler + 1; i++)
+ {
+ LinesHorizontal[i] = new Line(i * Scaler + offsetX, 0, i * Scaler, Height);
+ }
+ }
+ private void MakeVertical()
+ {
+ for (int i = 0; i < Height / Scaler + 1; i++)
+ {
+ LinesVertical[i] = new Line(0, i * Scaler, Width, i * Scaler);
+ }
+ }
+ }
+}
diff --git a/FractalTree/FractalTree.csproj b/FractalTree/FractalTree.csproj
new file mode 100644
index 0000000..0849e29
--- /dev/null
+++ b/FractalTree/FractalTree.csproj
@@ -0,0 +1,19 @@
+
+
+
+ WinExe
+ net6.0
+ disable
+ enable
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/FractalTree/Program.cs b/FractalTree/Program.cs
new file mode 100644
index 0000000..307a9a3
--- /dev/null
+++ b/FractalTree/Program.cs
@@ -0,0 +1,15 @@
+using Gtk;
+
+namespace FractalTree
+{
+ internal class Program
+ {
+ static void Main()
+ {
+ Application.Init();
+ //Create the Window
+ new CairoWindow("Window");
+ Application.Run();
+ }
+ }
+}
\ No newline at end of file
diff --git a/FractalTreeGtk/CairoWindow.cs b/FractalTreeGtk/CairoWindow.cs
new file mode 100644
index 0000000..7fada7b
--- /dev/null
+++ b/FractalTreeGtk/CairoWindow.cs
@@ -0,0 +1,31 @@
+using Gtk;
+using CairoObjective;
+using GLib;
+using FractalTreeGtk.Draw;
+
+namespace FractalTreeGtk
+{
+ internal class CairoWindow : Window
+ {
+ DrawingArea drawing = new DrawingArea();
+ Fractal fractal = new Fractal();
+ public CairoWindow(string title) : base(title) {
+ Fullscreen();
+ drawing.Drawn += Drawing_Drawn;
+ Add(drawing);
+ ShowAll();
+ }
+
+ private void Drawing_Drawn(object o, DrawnArgs args)
+ {
+ args.Cr.Translate(AllocatedWidth / 2, AllocatedHeight);
+ Set.Context = args.Cr;
+ Set.Background(new Cairo.Color(0, 0, 0));
+ foreach(CairoObjective.DrawObjects.Line[] lines in fractal.Fractallines)
+ {
+ foreach(CairoObjective.DrawObjects.Line line in lines)
+ Line.Make(line);
+ }
+ }
+ }
+}
diff --git a/FractalTreeGtk/Draw/Fractal.cs b/FractalTreeGtk/Draw/Fractal.cs
new file mode 100644
index 0000000..ac4a2d8
--- /dev/null
+++ b/FractalTreeGtk/Draw/Fractal.cs
@@ -0,0 +1,87 @@
+using CairoObjective.DrawObjects;
+using System;
+namespace FractalTreeGtk.Draw
+{
+ internal class Fractal
+ {
+ double Length = 50;
+ double deg = 0.2;
+ int levels = 14;
+ int level = 0;
+ double deltaLength = 2;
+ double deltaDeg = 0;
+ public Line[][] Fractallines;
+ public Fractal()
+ {
+ Fractallines = new Line[levels + 1][];
+ CreateBranch();
+ }
+ private void CreateBranch()
+ {
+ Fractallines[level] = new Line[Convert.ToInt32(Math.Pow(2, level))];
+ for (int i = 0; i < Fractallines[level].Length; i++)
+ {
+ Fractallines[level][i] = new Line(0, 0, 0, -Length);
+ }
+ level++;
+ NextLevel();
+ }
+ private void NextLevel()
+ {
+ Length -= deltaLength;
+ //deg += Math.Sin(deg) + deltadeg;
+ Fractallines[level] = new Line[Convert.ToInt32(Math.Pow(2, level))];
+ int x = 0;
+ for (int i = 0; i < Fractallines[level - 1].Length; i++)
+ {
+ Fractallines[level][x] = new Line(
+ Fractallines[level - 1][i].X2, Fractallines[level - 1][i].Y2,
+ -(Math.Sin(deg) * Length) + Fractallines[level - 1][i].X2, -(Math.Cos(deg) * Length) + Fractallines[level - 1][i].Y2
+ );
+ Fractallines[level][++x] = new Line(
+ Fractallines[level - 1][i].X2, Fractallines[level - 1][i].Y2,
+ -(Math.Sin(-deg) * Length) + Fractallines[level - 1][i].X2, -(Math.Cos(-deg) * Length) + Fractallines[level - 1][i].Y2
+ );
+ x++;
+ }
+ deltaDeg += deg + 0.1;
+ level++;
+ if(level <= levels)
+ {
+ NextLevel();
+ }
+ }
+ //private int SumOfBranches()
+ //{
+ // double sum = 0;
+ // for (int i = 0; i <= levels; i++)
+ // {
+ // sum += Math.Pow(2, i);
+ // }
+ // return (int)sum;
+ //}
+
+ //private void Branch()
+ //{
+ // for(int i = 0; i < Convert.ToInt32(Math.Pow(2, level)); i+=2)
+ // {
+ // int z = i;
+ // if(i == 0)
+ // {
+ // z = 1;
+ // }
+ // Lines[iter + i] = new Line(
+ // Lines[iter - z].X2, Lines[iter - z].Y2,
+ // -(Math.Sin(deg) * Length) + Lines[iter - z].X2, -(Math.Cos(deg) * Length) + Lines[iter - z].Y2
+ // );
+ // Lines[iter + i + 1] = new Line(
+ // Lines[iter - z].X2, Lines[iter - z].Y2,
+ // -(Math.Sin(-deg) * Length) + Lines[iter - z].X2, -(Math.Cos(-deg) * Length) + Lines[iter - z].Y2
+ // );
+ // deg += 0.05;
+ // }
+ // iter += Convert.ToInt32(Math.Pow(2, level));
+ // level++;
+ //}
+ }
+}
diff --git a/FractalTreeGtk/FractalTreeGtk.csproj b/FractalTreeGtk/FractalTreeGtk.csproj
new file mode 100644
index 0000000..0540961
--- /dev/null
+++ b/FractalTreeGtk/FractalTreeGtk.csproj
@@ -0,0 +1,19 @@
+
+
+
+ WinExe
+ net6.0
+ disable
+ enable
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/FractalTreeGtk/Program.cs b/FractalTreeGtk/Program.cs
new file mode 100644
index 0000000..7c2858c
--- /dev/null
+++ b/FractalTreeGtk/Program.cs
@@ -0,0 +1,18 @@
+using Gtk;
+
+namespace FractalTreeGtk
+{
+ internal class Program
+ {
+ static void Main(string[] args)
+ {
+ Application.Init();
+
+ //Create the Window
+
+ Window myWin = new CairoWindow("My first GTK# Application! ");
+
+ Application.Run();
+ }
+ }
+}
\ No newline at end of file