OSDN Git Service

many
[psychlops/silverlight.git] / dev3 / psychlops / core / graphic / canvas.cs
1 using System;\r
2 using System.Windows;\r
3 using System.Windows.Controls;\r
4 using System.Windows.Documents;\r
5 using System.Windows.Input;\r
6 using System.Windows.Media;\r
7 using System.Windows.Media.Animation;\r
8 using System.Windows.Media.Imaging;\r
9 using System.Windows.Shapes;\r
10 \r
11 \r
12 \r
13 namespace Psychlops\r
14 {\r
15 \r
16         namespace Templates\r
17         {\r
18 \r
19                 public class StackableDrawable : Drawable\r
20                 {\r
21                         protected System.Collections.Generic.Queue<Internal.PrimitiveFigure> stack;\r
22 \r
23                         public StackableDrawable()\r
24                         {\r
25                                 stack = new System.Collections.Generic.Queue<Internal.PrimitiveFigure>();\r
26                         }\r
27 \r
28                         public void clear()\r
29                         {\r
30                                 clear(Color.black);\r
31                         }\r
32                         public virtual void clear(Color col)\r
33                         {\r
34                                 //rect(back_panel, col);\r
35                         }\r
36 \r
37                         public virtual void pix(int x, int y, Color col)\r
38                         {\r
39                         }\r
40 \r
41                         public virtual void line(Line drawee)\r
42                         {\r
43                                 stack.Enqueue(drawee.clone());\r
44                         }\r
45 \r
46                         public virtual void rect(Rectangle drawee)\r
47                         {\r
48                                 stack.Enqueue(drawee.clone());\r
49                         }\r
50 \r
51                         public virtual void ellipse(Ellipse drawee)\r
52                         {\r
53                                 stack.Enqueue(drawee.clone());\r
54                         }\r
55 \r
56                         public virtual void polygon(Polygon drawee)\r
57                         {\r
58                                 stack.Enqueue(drawee.clone());\r
59                         }\r
60 \r
61                         public virtual void letters(Letters drawee)\r
62                         {\r
63                                 stack.Enqueue(drawee.clone());\r
64                         }\r
65 \r
66                         public virtual void image(Image drawee)\r
67                         {\r
68                                 stack.Enqueue(drawee.clone());\r
69                         }\r
70 \r
71                         public void msg(string str, double x, double y) { msg(str, x, y, Color.white); }\r
72                         public virtual void msg(string str, double x, double y, Color col)\r
73                         {\r
74                                 var let = new Letters(str);\r
75                                 let.locate(x, y);\r
76                                 let.fill = col;\r
77                                 this.letters(let);\r
78                         }\r
79                         public void var<Type>(Type val, double x, double y) { msg(val.ToString(), x, y, Color.white); }\r
80                         public void var<Type>(Type val, double x, double y, Color col) { msg(val.ToString(), x, y, col); }\r
81 \r
82                         public virtual Point getCenter() { return new Point(0, 0, 0); }\r
83                 }\r
84 \r
85         }\r
86 \r
87         public class Canvas : Templates.StackableDrawable\r
88         {\r
89 \r
90                 #region initializer\r
91 \r
92                 internal delegate void TwoIntProcedure(int x, int y);\r
93                 internal delegate void SimpleProcedure();\r
94                 SimpleProcedure flipexec;\r
95 \r
96                 //public static System.Windows.Controls.Image default_buffer_frame;\r
97                 public static System.Windows.Controls.UserControl default_panel;\r
98                 public static System.Windows.Controls.Canvas default_api_canvas;\r
99                 public static WriteableBitmap default_buffer;\r
100                 //WriteableBitmap buffer;\r
101                 //System.Windows.Controls.Image instance;\r
102                 System.Windows.Controls.Canvas api_canvas;\r
103                 System.Windows.Controls.UserControl panel;\r
104                 Rectangle back_panel;\r
105                 double width_, height_;\r
106 \r
107                 public Canvas(int wid, int hei)\r
108                 {\r
109                         panel = default_panel;\r
110                         api_canvas = default_api_canvas;\r
111                         initialize(wid, hei);\r
112                 }\r
113                 public Canvas(int wid, int hei, System.Windows.Controls.Canvas apicnvs, System.Windows.Controls.UserControl system)\r
114                 {\r
115                         panel = system;\r
116                         api_canvas = apicnvs;\r
117                         initialize(wid, hei);\r
118                 }\r
119                 protected void initialize(int wid, int hei)\r
120                 {\r
121 \r
122                         width_ = wid;\r
123                         height_ = hei;\r
124                         api_canvas.Dispatcher.BeginInvoke(new TwoIntProcedure(initialize__), wid, hei);\r
125                         Mouse._prime = api_canvas;\r
126                         Main.drawable = this;\r
127                         Main.canvas = this;\r
128 \r
129                         back_panel = new Rectangle(wid, hei);\r
130 \r
131                         flipexec = new SimpleProcedure(executeFlip);\r
132                 }\r
133                 protected void initialize__(int wid, int hei)\r
134                 {\r
135                         api_canvas.Width = wid;\r
136                         api_canvas.Height = hei;\r
137                         api_canvas.MouseMove += Mouse.Canvas_MousePos;\r
138                         api_canvas.MouseLeftButtonDown += Mouse.Canvas_LDown;\r
139                         api_canvas.MouseLeftButtonUp += Mouse.Canvas_LUp;\r
140                         api_canvas.MouseWheel += Mouse.Canvas_MouseWheel;\r
141                         panel.KeyDown += Keyboard.Canvas_KeyDown;\r
142                         panel.KeyUp += Keyboard.Canvas_KeyUp;\r
143                 }\r
144 \r
145                 #endregion\r
146 \r
147                 #region static initializer\r
148                 /*\r
149                 static System.Windows.Shapes.Line api_line;\r
150                 static System.Windows.Shapes.Path api_curve;\r
151                 static System.Windows.Shapes.Rectangle api_rect;\r
152                 static System.Windows.Shapes.Ellipse api_ellipse;\r
153                 static System.Windows.Shapes.Polygon api_polygon;\r
154                 static System.Windows.Shapes.Polyline api_polyline;\r
155                 static System.Windows.Media.Color api_color;\r
156                 static System.Windows.Media.SolidColorBrush api_fill;\r
157                 static System.Windows.Media.SolidColorBrush api_stroke;\r
158                 static System.Windows.Media.TranslateTransform api_translation;\r
159                 static Canvas()\r
160                 {\r
161                         api_line = new System.Windows.Shapes.Line();\r
162                         api_curve    = new System.Windows.Shapes.Path();\r
163                         api_rect     = new System.Windows.Shapes.Rectangle();\r
164                         api_ellipse  = new System.Windows.Shapes.Ellipse();\r
165                         api_polygon  = new System.Windows.Shapes.Polygon();\r
166                         api_polyline = new System.Windows.Shapes.Polyline();\r
167                         api_color       = new System.Windows.Media.Color();\r
168                         api_fill        = new System.Windows.Media.SolidColorBrush();\r
169                         api_stroke      = new System.Windows.Media.SolidColorBrush();\r
170                         api_translation = new System.Windows.Media.TranslateTransform();\r
171                 }\r
172                 */\r
173                 #endregion\r
174 \r
175 \r
176                 public override void clear(Color col)\r
177                 {\r
178                         back_panel.fill = col;\r
179                         rect(back_panel);\r
180                 }\r
181 \r
182                 int nextIntervalFrame = 1;\r
183                 public void flip()\r
184                 {\r
185                         //api_canvas.Dispatcher.BeginInvoke(flipexec);\r
186                         //flipexec();\r
187                         //System.Threading.Thread.Sleep(System.Threading.Timeout.Infinite);\r
188                         lock (this)\r
189                         {\r
190                                 nextIntervalFrame = 1;\r
191                         }\r
192                         Internal.Main.canvas_flag.WaitOne();\r
193                 }\r
194                 public void executeFlip()\r
195                 {\r
196                         lock (this)\r
197                         {\r
198                                 nextIntervalFrame--;\r
199                         }\r
200                         if (nextIntervalFrame <= 0)\r
201                         {\r
202                                 var tmp = new System.Windows.Controls.Canvas();\r
203                                 foreach (Internal.PrimitiveFigure f in stack)\r
204                                 {\r
205                                         tmp.Children.Add(f.toNative());\r
206                                 }\r
207                                 api_canvas.Children.Clear();\r
208                                 api_canvas.Children.Add(tmp);\r
209                                 stack.Clear();\r
210                                 Psychlops.Internal.Main.canvas_flag.Set();\r
211                         }\r
212                         System.Threading.Thread.Sleep(0);\r
213                 }\r
214 \r
215                 #region Properties\r
216 \r
217                 public double width { get { return width_; } }\r
218                 public double height { get { return height_; } }\r
219                 public Point center { get { return new Point(width / 2.0, height / 2.0, 0); } }\r
220                 public double getWidth() { return width; }\r
221                 public double getHeight() { return height; }\r
222                 public override Point getCenter() { return center; }\r
223                 public double getHCenter() { return width / 2; }\r
224                 public double getVCenter() { return height / 2; }\r
225                 public double getRefreshRate() { return 60; }\r
226 \r
227                 #endregion\r
228 \r
229 \r
230         }\r
231 \r
232 \r
233 \r
234         #region primitive tokenizer\r
235 \r
236         partial struct Point\r
237         {\r
238                 public static implicit operator System.Windows.Point(Point d)\r
239                 {\r
240                         return new System.Windows.Point(d.x, d.y);\r
241                 }\r
242         }\r
243 \r
244         partial struct Color\r
245         {\r
246                 public static implicit operator System.Windows.Media.Color(Color d)\r
247                 {\r
248                         return System.Windows.Media.Color.FromArgb((byte)(d.a * 255), (byte)(d.r * 255), (byte)(d.g * 255), (byte)(d.b * 255));\r
249                 }\r
250                 public static implicit operator System.Windows.Media.SolidColorBrush(Color d)\r
251                 {\r
252                         return new SolidColorBrush { Color = d };\r
253                 }\r
254         }\r
255 \r
256         partial struct Stroke\r
257         {\r
258                 public void apply(System.Windows.Shapes.Shape target)\r
259                 {\r
260                         target.Stroke = this;\r
261                         //target.StrokeDashArray\r
262                         target.StrokeThickness = thick;\r
263                 }\r
264                 public static implicit operator SolidColorBrush(Stroke d)\r
265                 {\r
266                         return new SolidColorBrush { Color = d.color };\r
267                 }\r
268         }\r
269 \r
270         partial class Line\r
271         {\r
272                 public Line clone()\r
273                 {\r
274                         return (Line)MemberwiseClone();\r
275                 }\r
276                 public static implicit operator System.Windows.Shapes.Line(Line d)\r
277                 {\r
278                         var tmp =  new System.Windows.Shapes.Line() { X1 = d.begin.x, Y1 = d.begin.y, X2 = d.end.x, Y2 = d.end.y };\r
279                         if (d.stroke.thick == 0.0) tmp.Stroke = d.fill;\r
280                         else d.stroke.apply(tmp);\r
281                         return tmp;\r
282                 }\r
283                 public UIElement toNative() { return this; }\r
284         }\r
285 \r
286         partial class Rectangle\r
287         {\r
288                 public Rectangle clone()\r
289                 {\r
290                         return (Rectangle)MemberwiseClone();\r
291                 }\r
292                 public static implicit operator System.Windows.Rect(Rectangle d)\r
293                 {\r
294                         return new System.Windows.Rect(d.v1.x, d.v1.y, d.v2.x, d.v2.y);\r
295                 }\r
296                 public static implicit operator System.Windows.Shapes.Rectangle(Rectangle d)\r
297                 {\r
298                         var tmp = new System.Windows.Shapes.Rectangle { Width = d.width, Height = d.height, Fill = d.fill };\r
299                         d.stroke.apply(tmp);\r
300                         System.Windows.Controls.Canvas.SetLeft(tmp, d.left);\r
301                         System.Windows.Controls.Canvas.SetTop(tmp, d.top);\r
302                         return tmp;\r
303                 }\r
304                 public UIElement toNative() { return this; }\r
305         }\r
306 \r
307         partial class Ellipse\r
308         {\r
309                 public Ellipse clone()\r
310                 {\r
311                         return (Ellipse)MemberwiseClone();\r
312                 }\r
313                 public static implicit operator System.Windows.Shapes.Ellipse(Ellipse d)\r
314                 {\r
315                         var tmp = new System.Windows.Shapes.Ellipse { Width = d.width, Height = d.height, Fill = d.fill };\r
316                         d.stroke.apply(tmp);\r
317                         System.Windows.Controls.Canvas.SetLeft(tmp, d.left);\r
318                         System.Windows.Controls.Canvas.SetTop(tmp, d.top);\r
319                         return tmp;\r
320                 }\r
321                 public UIElement toNative() { return this; }\r
322         }\r
323 \r
324         partial class Polygon\r
325         {\r
326                 public Polygon clone()\r
327                 {\r
328                         return (Polygon)MemberwiseClone();\r
329                 }\r
330                 public static implicit operator System.Windows.Shapes.Polygon(Polygon d)\r
331                 {\r
332                         var tmp = new System.Windows.Shapes.Polygon { Fill = d.fill };\r
333                         d.stroke.apply(tmp);\r
334                         foreach (Point p in d.vertices)\r
335                         {\r
336                                 tmp.Points.Add(p);\r
337                         }\r
338                         System.Windows.Controls.Canvas.SetLeft(tmp, d.datum.x);\r
339                         System.Windows.Controls.Canvas.SetTop(tmp, d.datum.y);\r
340                         return tmp;\r
341                 }\r
342                 public UIElement toNative() { return this; }\r
343         }\r
344         \r
345         partial class Letters\r
346         {\r
347                 #region static initializer\r
348                 internal static System.Collections.Generic.Dictionary<int, System.Windows.FontWeight> FONT_WEIGHT_BRIDGE;\r
349                 internal static System.Collections.Generic.Dictionary<Font.Style, System.Windows.FontStyle> FONT_STYLE_BRIDGE;\r
350                 internal static System.Collections.Generic.Dictionary<Letters.HorizontalAlign, TextAlignment> LETTERS_H_ALIGN_BRIDGE;\r
351                 static Letters()\r
352                 {\r
353                         FONT_WEIGHT_BRIDGE = new System.Collections.Generic.Dictionary<int, System.Windows.FontWeight>();\r
354                         FONT_WEIGHT_BRIDGE.Add((int)Font.Weight.normal, System.Windows.FontWeights.Normal);\r
355                         FONT_WEIGHT_BRIDGE.Add((int)Font.Weight.bold, System.Windows.FontWeights.Bold);\r
356                         FONT_STYLE_BRIDGE = new System.Collections.Generic.Dictionary<Font.Style, System.Windows.FontStyle>();\r
357                         FONT_STYLE_BRIDGE.Add(Font.Style.normal, System.Windows.FontStyles.Normal);\r
358                         FONT_STYLE_BRIDGE.Add(Font.Style.italic, System.Windows.FontStyles.Italic);\r
359                         FONT_STYLE_BRIDGE.Add(Font.Style.oblique, System.Windows.FontStyles.Italic);\r
360                         LETTERS_H_ALIGN_BRIDGE = new System.Collections.Generic.Dictionary<Letters.HorizontalAlign, TextAlignment>();\r
361                         LETTERS_H_ALIGN_BRIDGE.Add(Letters.HorizontalAlign.TEXT_ALIGN_LEFT, TextAlignment.Left);\r
362                         LETTERS_H_ALIGN_BRIDGE.Add(Letters.HorizontalAlign.TEXT_ALIGN_CENTER, TextAlignment.Center);\r
363                         LETTERS_H_ALIGN_BRIDGE.Add(Letters.HorizontalAlign.TEXT_ALIGN_RIGHT, TextAlignment.Right);\r
364                         LETTERS_H_ALIGN_BRIDGE.Add(Letters.HorizontalAlign.NOT_SPECIFIED, TextAlignment.Left);\r
365                 }\r
366                 #endregion\r
367                 public Letters clone()\r
368                 {\r
369                         return (Letters)MemberwiseClone();\r
370                 }\r
371                 public static implicit operator System.Windows.Controls.TextBlock(Letters d)\r
372                 {\r
373                         //var zapi_shape = new System.Windows.Documents.Glyphs();\r
374                         var tmp = new System.Windows.Controls.TextBlock {\r
375                                 Text = d.str, Width = 500, Height = 500,\r
376                                 FontSize = d.font.size,\r
377                                 //tmp.FontFamily = ,\r
378                                 FontStyle = FONT_STYLE_BRIDGE[d.font.style],\r
379                                 FontWeight = FONT_WEIGHT_BRIDGE[d.font.weight],\r
380                                 TextAlignment = LETTERS_H_ALIGN_BRIDGE[d.align],\r
381                                 Foreground = d.fill\r
382                         };\r
383                         double left = 0;\r
384                         switch (d.align)\r
385                         {\r
386                                 case Letters.HorizontalAlign.TEXT_ALIGN_LEFT: break;\r
387                                 case Letters.HorizontalAlign.TEXT_ALIGN_CENTER: left = tmp.Width / 2; break;\r
388                                 case Letters.HorizontalAlign.TEXT_ALIGN_RIGHT: left = tmp.Width; break;\r
389                         }\r
390                         System.Windows.Controls.Canvas.SetLeft(tmp, d.datum.x - left);\r
391                         System.Windows.Controls.Canvas.SetTop(tmp, d.datum.y - d.font.size);\r
392                         return tmp;\r
393                 }\r
394                 public UIElement toNative() { return this; }\r
395         }\r
396 \r
397         partial class Image\r
398         {\r
399                 internal void initialize__(int wid, int hei)\r
400                 {\r
401                         Canvas.default_api_canvas.Dispatcher.BeginInvoke(new Canvas.TwoIntProcedure(create__), wid, hei);\r
402                         //buffer = new WriteableBitmap(wid, hei);\r
403                 }\r
404                 internal void create__(int wid, int hei)\r
405                 {\r
406                         buffer = new WriteableBitmap(wid, hei);\r
407                 }\r
408                 delegate void FieldFunc1(System.Func<int, int, System.Windows.Media.Color> func);\r
409                 delegate void FieldFunc2(System.Func<int, int, System.Windows.Media.Color, System.Windows.Media.Color> func);\r
410                 public void field__(System.Func<int, int, System.Windows.Media.Color> func)\r
411                 {\r
412                         Canvas.default_api_canvas.Dispatcher.BeginInvoke(new FieldFunc1(field___), func);\r
413                         //buffer.ForEach(func);\r
414                 }\r
415                 public void field__(System.Func<int, int, System.Windows.Media.Color, System.Windows.Media.Color> func)\r
416                 {\r
417                         Canvas.default_api_canvas.Dispatcher.BeginInvoke(new FieldFunc2(field___), func);\r
418                         //buffer.ForEach(func);\r
419                 }\r
420                 public void field___(System.Func<int, int, System.Windows.Media.Color> func)\r
421                 {\r
422                         buffer.ForEach(func);\r
423                 }\r
424                 public void field___(System.Func<int, int, System.Windows.Media.Color, System.Windows.Media.Color> func)\r
425                 {\r
426                         buffer.ForEach(func);\r
427                 }\r
428 \r
429                 public Image clone()\r
430                 {\r
431                         return (Image)MemberwiseClone();\r
432                 }\r
433                 public static implicit operator System.Windows.Controls.Image(Image d)\r
434                 {\r
435                         var tmp = new System.Windows.Controls.Image();\r
436                         tmp.Source = d.buffer;\r
437                         System.Windows.Controls.Canvas.SetLeft(tmp, d.datum.x);\r
438                         System.Windows.Controls.Canvas.SetTop(tmp, d.datum.y);\r
439                         return tmp;\r
440                 }\r
441                 public UIElement toNative() { return this; }\r
442         }\r
443 \r
444         #endregion\r
445 \r
446 \r
447 }