using System; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Animation; using System.Windows.Media.Imaging; using System.Windows.Shapes; using System.Windows.Browser; namespace Psychlops { namespace Templates { public class StackableDrawable : Drawable { // protected System.Collections.Generic.Queue stack; internal Internal.PrimitiveFigure[] stack; internal int stackN; internal Line[] lineStack; internal int lineStackN; internal Rectangle[] rectStack; internal int rectStackN; internal Ellipse[] ellipseStack; internal int ellipseStackN; internal Polygon[] polygonStack; internal int polygonStackN; internal Letters[] lettersStack; internal int lettersStackN; internal Image[] imageStack; internal int imageStackN; public StackableDrawable() { // stack = new System.Collections.Generic.Queue(); stack = new Internal.PrimitiveFigure[40000]; lineStack = new Line[10000]; rectStack = new Rectangle[10000]; ellipseStack = new Ellipse[10000]; polygonStack = new Polygon[1000]; lettersStack = new Letters[1000]; imageStack = new Image[1000]; for (int i = 0; i < 10000; i++) { lineStack[i] = new Line(0,0,0,0); rectStack[i] = new Rectangle(); ellipseStack[i] = new Ellipse(); } for (int i = 0; i < 1000; i++) { polygonStack[i] = new Polygon(); lettersStack[i] = new Letters(); //imageStack[i] = new Image(); } } public void clear() { clear(Color.black); } public virtual void clear(Color col) { //rect(back_panel, col); } public virtual void pix(int x, int y, Color col) { } public virtual void line(Line drawee) { // stack.Enqueue(drawee.clone()); } public virtual void rect(Rectangle drawee) { //stack.Enqueue(drawee.clone()); // stack.Enqueue(drawee.copyToStack(this)); drawee.copyToStack(this); } public virtual void ellipse(Ellipse drawee) { // stack.Enqueue(drawee.clone()); drawee.copyToStack(this); } public virtual void polygon(Polygon drawee) { // stack.Enqueue(drawee.clone()); drawee.copyToStack(this); } public virtual void letters(Letters drawee) { // stack.Enqueue(drawee.clone()); drawee.copyToStack(this); } public virtual void image(Image drawee) { // stack.Enqueue(drawee.clone()); drawee.copyToStack(this); } public void msg(string str, double x, double y) { msg(str, x, y, Color.white); } public virtual void msg(string dstr, double x, double y, Color col) { var let = new Letters(dstr); let.locate(x, y); let.fill = col; this.letters(let); } public void var(Type val, double x, double y) { msg(val.ToString(), x, y, Color.white); } public void var(Type val, double x, double y, Color col) { msg(val.ToString(), x, y, col); } public virtual Point getCenter() { return new Point(0, 0, 0); } } } public class Canvas : Templates.StackableDrawable { internal System.Windows.Controls.Canvas masterPool, prevPool; internal System.Windows.Point[] pointPool; internal int pointPoolN; internal SolidColorBrush[] brushPool; internal int brushPoolN; internal System.Windows.Shapes.Line[] linePool; internal int linePoolN; internal System.Windows.Shapes.Rectangle[] rectPool; internal int rectPoolN; internal System.Windows.Shapes.Ellipse[] ellipsePool; internal int ellipsePoolN; internal System.Windows.Shapes.Polygon[] polygonPool; internal int polygonPoolN; #region initializer internal delegate void TwoIntProcedure(int x, int y); internal delegate void SimpleProcedure(); SimpleProcedure flipexec; //public static System.Windows.Controls.Image default_buffer_frame; public static System.Windows.Controls.UserControl default_panel; public static System.Windows.Controls.Canvas default_api_canvas; public static WriteableBitmap default_buffer; //WriteableBitmap buffer; //System.Windows.Controls.Image instance; System.Windows.Controls.Canvas api_canvas; System.Windows.Controls.UserControl panel; Rectangle back_panel; double width_, height_; public Canvas(int wid, int hei) { panel = default_panel; api_canvas = default_api_canvas; initialize(wid, hei); } public Canvas(int wid, int hei, System.Windows.Controls.Canvas apicnvs, System.Windows.Controls.UserControl system) { panel = system; api_canvas = apicnvs; initialize(wid, hei); } protected void initialize(int wid, int hei) { width_ = wid; height_ = hei; api_canvas.Dispatcher.BeginInvoke(new TwoIntProcedure(initialize__), wid, hei); Mouse._prime = api_canvas; Main.drawable = this; Main.canvas = this; back_panel = new Rectangle(wid, hei); flipexec = new SimpleProcedure(executeFlip); } protected void initialize__(int wid, int hei) { api_canvas.Width = wid; api_canvas.Height = hei; api_canvas.MouseMove += Mouse.Canvas_MousePos; api_canvas.MouseLeftButtonDown += Mouse.Canvas_LDown; api_canvas.MouseLeftButtonUp += Mouse.Canvas_LUp; api_canvas.MouseWheel += Mouse.Canvas_MouseWheel; panel.KeyDown += Keyboard.Canvas_KeyDown; panel.KeyUp += Keyboard.Canvas_KeyUp; HtmlElement htmlHost = HtmlPage.Document.GetElementById("silverlightControlHost"); //if (htmlHost != null) HtmlPage.Window.Alert("silverlightControlHost is null"); htmlHost.SetStyleAttribute("width", (wid).ToString()+"px"); htmlHost.SetStyleAttribute("height", (20+hei).ToString() + "px"); htmlHost.SetStyleAttribute("margin", "2em auto auto auto"); pointPool = new System.Windows.Point[10000]; brushPool = new SolidColorBrush[10000]; linePool = new System.Windows.Shapes.Line[10000]; rectPool = new System.Windows.Shapes.Rectangle[10000]; for (int i = 0; i < 10000; i++) { pointPool[i] = new System.Windows.Point(); brushPool[i] = new SolidColorBrush(); linePool[i] = new System.Windows.Shapes.Line(); rectPool[i] = new System.Windows.Shapes.Rectangle(); } for (int i = 0; i < 300; i++) { api_canvas.Children.Add(rectStack[i].poolNative(this)); api_canvas.Children.Add(rectStack[i].poolNative(this)); } masterPool = new System.Windows.Controls.Canvas(); prevPool = new System.Windows.Controls.Canvas(); // masterPool.Children.Add() } #endregion #region static initializer /* static System.Windows.Shapes.Line api_line; static System.Windows.Shapes.Path api_curve; static System.Windows.Shapes.Rectangle api_rect; static System.Windows.Shapes.Ellipse api_ellipse; static System.Windows.Shapes.Polygon api_polygon; static System.Windows.Shapes.Polyline api_polyline; static System.Windows.Media.Color api_color; static System.Windows.Media.SolidColorBrush api_fill; static System.Windows.Media.SolidColorBrush api_stroke; static System.Windows.Media.TranslateTransform api_translation; static Canvas() { api_line = new System.Windows.Shapes.Line(); api_curve = new System.Windows.Shapes.Path(); api_rect = new System.Windows.Shapes.Rectangle(); api_ellipse = new System.Windows.Shapes.Ellipse(); api_polygon = new System.Windows.Shapes.Polygon(); api_polyline = new System.Windows.Shapes.Polyline(); api_color = new System.Windows.Media.Color(); api_fill = new System.Windows.Media.SolidColorBrush(); api_stroke = new System.Windows.Media.SolidColorBrush(); api_translation = new System.Windows.Media.TranslateTransform(); } */ #endregion public override void clear(Color col) { back_panel.fill = col; // stack.Clear(); stackN = 0; rect(back_panel); } int nextIntervalFrame = 1, chacked = 0; /* public void flip() { //api_canvas.Dispatcher.BeginInvoke(flipexec); //flipexec(); //System.Threading.Thread.Sleep(System.Threading.Timeout.Infinite); lock (this) { nextIntervalFrame = 1; chacked = 1; } // pointPoolN = 0; // brushPoolN = 0; // linePoolN = 0; rectPoolN = 0; lineStackN = 0; rectStackN = 0; Internal.Main.canvas_flag.WaitOne(); } public void executeFlip() { lock (this) { nextIntervalFrame--; } if (nextIntervalFrame <= 0) { var rr = new Random(); //Psychlops.AppState.statusBar = chacked.ToString(); if (chacked > 0) { // prevPool.Children.Clear(); var tmp = new System.Windows.Controls.Canvas(); if (stack.Count > 0) // if (stackN > 0) { //foreach (UIElement e in api_canvas.Children) //{ //} // foreach (Internal.PrimitiveFigure f in stack) for (int i = 0; i < stackN - 2; i++) { // tmp.Children.Add(f.toNative()); // tmp.Children.Add(f.poolNative(this)); tmp.Children.Add(stack[i].poolNative(this)); // System.Windows.Controls.Canvas.SetLeft(api_canvas.Children[i + 1], rectStack[i].left); // api_canvas.Children[0] = api_canvas.Children[0]; } stackN = 0; } api_canvas.Children.Clear(); api_canvas.Children.Add(tmp); // stack.Clear(); lock (this) { chacked = 0; } Psychlops.Internal.Main.canvas_flag.Set(); // prevPool = tmp; } } System.Threading.Thread.Sleep(0); } */ public void flip() { lock (this) { nextIntervalFrame = 1; chacked = 1; } // pointPoolN = 0; // brushPoolN = 0; // linePoolN = 0; rectPoolN = 0; lineStackN = 0; rectStackN = 0; Internal.Main.canvas_flag.WaitOne(); } public void executeFlip() { lock (this) { nextIntervalFrame--; } if (nextIntervalFrame <= 0) { if (chacked > 0) { //api_canvas.Children.Clear(); //var tmp = new System.Windows.Controls.Canvas(); if (stackN > 0) { for (int i = 0; i < stackN - 2; i++) { //api_canvas.Children.Add(stack[i].poolNative(this)); api_canvas.Children.Add(stack[i].poolNative(this)); } stackN = 0; } //api_canvas.Children.Clear(); //api_canvas.Children.Add(tmp); lock (this) { chacked = 0; } Psychlops.Internal.Main.canvas_flag.Set(); } } System.Threading.Thread.Sleep(0); } #region Properties public double width { get { return width_; } } public double height { get { return height_; } } public Point center { get { return new Point(width / 2.0, height / 2.0, 0); } } public double getWidth() { return width; } public double getHeight() { return height; } public override Point getCenter() { return center; } public double getHCenter() { return width / 2; } public double getVCenter() { return height / 2; } public double getRefreshRate() { return 60; } #endregion } #region primitive tokenizer partial struct Point { public static implicit operator System.Windows.Point(Point d) { return new System.Windows.Point(d.x, d.y); } } partial struct Color { public static implicit operator System.Windows.Media.Color(Color d) { return System.Windows.Media.Color.FromArgb((byte)(d.a * 255), (byte)(d.r * 255), (byte)(d.g * 255), (byte)(d.b * 255)); } public static implicit operator System.Windows.Media.SolidColorBrush(Color d) { return new SolidColorBrush { Color = d }; } } partial struct Stroke { public void apply(System.Windows.Shapes.Shape target) { target.Stroke = this; //target.StrokeDashArray target.StrokeThickness = thick; } public static implicit operator SolidColorBrush(Stroke d) { return new SolidColorBrush { Color = d.color }; } } partial class Line { public Line dup() { return (Line)MemberwiseClone(); } public Line clone() { return (Line)MemberwiseClone(); } public static implicit operator System.Windows.Shapes.Line(Line d) { var tmp = new System.Windows.Shapes.Line() { X1 = d.begin.x, Y1 = d.begin.y, X2 = d.end.x, Y2 = d.end.y }; if (d.stroke.thick == 0.0) tmp.Stroke = d.fill; else d.stroke.apply(tmp); return tmp; } public UIElement toNative() { return this; } public UIElement poolNative(Canvas d) { var tmp = d.linePool[d.linePoolN]; tmp.X1 = begin.x; tmp.Y1 = begin.y; tmp.X2 = end.x; tmp.Y2 = end.y; if (stroke.thick == 0.0) tmp.Stroke = fill; else stroke.apply(tmp); System.Windows.Controls.Canvas.SetLeft(tmp, left); System.Windows.Controls.Canvas.SetTop(tmp, top); tmp.Visibility = Visibility.Visible; d.linePoolN++; return tmp; } } partial class Rectangle { public Rectangle dup() { return (Rectangle)MemberwiseClone(); } public Rectangle clone() { return (Rectangle)MemberwiseClone(); } public static implicit operator System.Windows.Rect(Rectangle d) { return new System.Windows.Rect(d.v1.x, d.v1.y, d.v2.x, d.v2.y); } public static implicit operator System.Windows.Shapes.Rectangle(Rectangle d) { var tmp = new System.Windows.Shapes.Rectangle { Width = d.width, Height = d.height, Fill = d.fill }; d.stroke.apply(tmp); System.Windows.Controls.Canvas.SetLeft(tmp, d.left); System.Windows.Controls.Canvas.SetTop(tmp, d.top); return tmp; } public UIElement toNative() { return this; } public void copyToStack(Templates.StackableDrawable d) { var tmp = d.rectStack[d.rectStackN]; tmp.v1 = v1; tmp.v2 = v2; tmp.fill = fill; d.stack[d.stackN] = tmp; d.rectStackN++; d.stackN++; } public UIElement poolNative(Canvas d) { var tmp = d.rectPool[d.rectPoolN]; tmp.Width = width; tmp.Height = height; tmp.Fill = fill; System.Windows.Controls.Canvas.SetLeft(tmp, left); System.Windows.Controls.Canvas.SetTop(tmp, top); tmp.Visibility = Visibility.Visible; d.rectPoolN++; return tmp; } } partial class Ellipse { public Ellipse dup() { return (Ellipse)MemberwiseClone(); } public Ellipse clone() { return (Ellipse)MemberwiseClone(); } public static implicit operator System.Windows.Shapes.Ellipse(Ellipse d) { var tmp = new System.Windows.Shapes.Ellipse { Width = d.width, Height = d.height, Fill = d.fill }; d.stroke.apply(tmp); System.Windows.Controls.Canvas.SetLeft(tmp, d.left); System.Windows.Controls.Canvas.SetTop(tmp, d.top); return tmp; } public UIElement toNative() { return this; } public void copyToStack(Templates.StackableDrawable d) { var tmp = d.ellipseStack[d.ellipseStackN]; tmp.datum = datum; tmp.xdiameter = xdiameter; tmp.ydiameter = ydiameter; tmp.fill = fill; d.stack[d.stackN] = tmp; d.rectStackN++; d.stackN++; } public UIElement poolNative(Canvas d) { var tmp = d.ellipsePool[d.ellipsePoolN]; tmp.Width = width; tmp.Height = height; tmp.Fill = fill; System.Windows.Controls.Canvas.SetLeft(tmp, left); System.Windows.Controls.Canvas.SetTop(d.rectPool[d.rectPoolN], top); tmp.Visibility = Visibility.Visible; d.ellipsePoolN++; return this; } } partial class Polygon { public Polygon dup() { return (Polygon)MemberwiseClone(); } public Polygon clone() { return (Polygon)MemberwiseClone(); } public static implicit operator System.Windows.Shapes.Polygon(Polygon d) { var tmp = new System.Windows.Shapes.Polygon { Fill = d.fill }; d.stroke.apply(tmp); foreach (Point p in d.vertices) { tmp.Points.Add(p); } System.Windows.Controls.Canvas.SetLeft(tmp, d.datum.x); System.Windows.Controls.Canvas.SetTop(tmp, d.datum.y); return tmp; } public UIElement toNative() { return this; } public void copyToStack(Templates.StackableDrawable d) { var tmp = d.polygonStack[d.polygonStackN]; tmp.datum = datum; tmp.vertices.Clear(); foreach (var v in vertices) { tmp.vertices.Add(v); } tmp.fill = fill; d.stack[d.stackN] = tmp; d.rectStackN++; d.stackN++; } public UIElement poolNative(Canvas d) { var tmp = d.polygonPool[d.polygonPoolN]; tmp.Fill = fill; /* System.Windows.Controls.Canvas.SetLeft(tmp, left); System.Windows.Controls.Canvas.SetTop(d.rectPool[d.rectPoolN], top); */ tmp.Visibility = Visibility.Visible; d.polygonPoolN++; return this; } } partial class Letters { #region static initializer internal static System.Collections.Generic.Dictionary FONT_WEIGHT_BRIDGE; internal static System.Collections.Generic.Dictionary FONT_STYLE_BRIDGE; internal static System.Collections.Generic.Dictionary LETTERS_H_ALIGN_BRIDGE; static Letters() { FONT_WEIGHT_BRIDGE = new System.Collections.Generic.Dictionary(); FONT_WEIGHT_BRIDGE.Add((int)Font.Weight.normal, System.Windows.FontWeights.Normal); FONT_WEIGHT_BRIDGE.Add((int)Font.Weight.bold, System.Windows.FontWeights.Bold); FONT_STYLE_BRIDGE = new System.Collections.Generic.Dictionary(); FONT_STYLE_BRIDGE.Add(Font.Style.normal, System.Windows.FontStyles.Normal); FONT_STYLE_BRIDGE.Add(Font.Style.italic, System.Windows.FontStyles.Italic); FONT_STYLE_BRIDGE.Add(Font.Style.oblique, System.Windows.FontStyles.Italic); LETTERS_H_ALIGN_BRIDGE = new System.Collections.Generic.Dictionary(); LETTERS_H_ALIGN_BRIDGE.Add(Letters.HorizontalAlign.left, TextAlignment.Left); LETTERS_H_ALIGN_BRIDGE.Add(Letters.HorizontalAlign.center, TextAlignment.Center); LETTERS_H_ALIGN_BRIDGE.Add(Letters.HorizontalAlign.right, TextAlignment.Right); LETTERS_H_ALIGN_BRIDGE.Add(Letters.HorizontalAlign.not_specified, TextAlignment.Left); } #endregion public Letters dup() { return (Letters)MemberwiseClone(); } public Letters clone() { return (Letters)MemberwiseClone(); } public static implicit operator System.Windows.Controls.TextBlock(Letters d) { //var zapi_shape = new System.Windows.Documents.Glyphs(); var tmp = new System.Windows.Controls.TextBlock { Text = d.str, Width = 500, Height = 500, FontSize = d.font.size, //tmp.FontFamily = , FontStyle = FONT_STYLE_BRIDGE[d.font.style], FontWeight = FONT_WEIGHT_BRIDGE[d.font.weight], TextAlignment = LETTERS_H_ALIGN_BRIDGE[d.align], Foreground = d.fill }; double left = 0; switch (d.align) { case Letters.HorizontalAlign.left: break; case Letters.HorizontalAlign.center: left = tmp.Width / 2; break; case Letters.HorizontalAlign.right: left = tmp.Width; break; } System.Windows.Controls.Canvas.SetLeft(tmp, d.datum.x - left); System.Windows.Controls.Canvas.SetTop(tmp, d.datum.y - d.font.size); return tmp; } public UIElement toNative() { return this; } public void copyToStack(Templates.StackableDrawable d) { var tmp = d.polygonStack[d.polygonStackN]; tmp.datum = datum; tmp.fill = fill; d.stack[d.stackN] = tmp; d.rectStackN++; d.stackN++; } public UIElement poolNative(Canvas d) { /* var tmp = d.rectPool[d.rectPoolN]; tmp.Width = width; tmp.Height = height; tmp.Fill = fill; System.Windows.Controls.Canvas.SetLeft(tmp, left); System.Windows.Controls.Canvas.SetTop(d.rectPool[d.rectPoolN], top); tmp.Visibility = Visibility.Visible; d.rectPoolN++; */ return this; } } partial class Image { internal void initialize__(int wid, int hei) { Canvas.default_api_canvas.Dispatcher.BeginInvoke(new Canvas.TwoIntProcedure(create__), wid, hei); //buffer = new WriteableBitmap(wid, hei); } internal void create__(int wid, int hei) { buffer = new WriteableBitmap(wid, hei); } delegate void FieldFunc1(System.Func func); delegate void FieldFunc2(System.Func func); public void field__(System.Func func) { Canvas.default_api_canvas.Dispatcher.BeginInvoke(new FieldFunc1(field___), func); //buffer.ForEach(func); } public void field__(System.Func func) { Canvas.default_api_canvas.Dispatcher.BeginInvoke(new FieldFunc2(field___), func); //buffer.ForEach(func); } public void field___(System.Func func) { buffer.ForEach(func); } public void field___(System.Func func) { buffer.ForEach(func); } public Image clone() { return (Image)MemberwiseClone(); } public static implicit operator System.Windows.Controls.Image(Image d) { var tmp = new System.Windows.Controls.Image(); tmp.Source = d.buffer; System.Windows.Controls.Canvas.SetLeft(tmp, d.datum.x); System.Windows.Controls.Canvas.SetTop(tmp, d.datum.y); return tmp; } public UIElement toNative() { return this; } public UIElement poolNative(Canvas d) { /* var tmp = d.rectPool[d.rectPoolN]; tmp.Width = width; tmp.Height = height; tmp.Fill = fill; System.Windows.Controls.Canvas.SetLeft(tmp, left); System.Windows.Controls.Canvas.SetTop(d.rectPool[d.rectPoolN], top); tmp.Visibility = Visibility.Visible; d.rectPoolN++; */ return this; } } #endregion }