OSDN Git Service

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