]> O.S.I.I.S - jp/crow.git/commitdiff
3d interfaces
authorjpbruyere <jp.bruyere@hotmail.com>
Fri, 13 Jan 2017 22:36:14 +0000 (23:36 +0100)
committerjpbruyere <jp.bruyere@hotmail.com>
Fri, 13 Jan 2017 22:36:14 +0000 (23:36 +0100)
15 files changed:
Templates/CheckBox.template
Tests/BasicTests.cs
Tests/CrowWindow.cs [new file with mode: 0644]
Tests/Hello3D.cs [new file with mode: 0644]
Tests/HelloCube.cs
Tests/HelloWorld.cs
Tests/InterfaceControler.cs [new file with mode: 0644]
Tests/OpenGL/Extensions.cs [new file with mode: 0644]
Tests/OpenTKGameWindow.cs [deleted file]
Tests/Tests.csproj
Tests/UIEditor.cs
src/GraphicObjects/GraphicObject.cs
src/GraphicObjects/Label.cs
src/GraphicObjects/TextRun.cs
src/Interface.cs

index 070f8e2e2fa546dc18830ed86e18c31d670819ae..a9a62a4a6240ab4e40859b1335325d8bc5f8b6aa 100755 (executable)
@@ -2,5 +2,5 @@
 <HorizontalStack Style="Control" Background="{./Background}">
        <Image Style="Icon" Path="#Crow.Images.Icons.checkbox.svg"
                SvgSub="{./IsChecked}"/>
-       <Label Font="{./Font}" Text="{./Caption}"/>
+       <Label Font="{./Font}" Text="{./Caption}" Foreground="{./Foreground}"/>
 </HorizontalStack>
\ No newline at end of file
index 22007eb8279a7eeee62435921c28a19306d9b257..8b9f1afb58e3c058f4002f78db44e27dbe40807c 100644 (file)
@@ -10,7 +10,7 @@ using System.Diagnostics;
 
 namespace Tests
 {
-       class BasicTests : OpenTKGameWindow
+       class BasicTests : CrowWindow
        {
                public BasicTests ()
                        : base(800, 600,"test: press <F3> to toogle test files")
@@ -129,7 +129,7 @@ namespace Tests
                        testFiles = testFiles.Concat (Directory.GetFiles (@"Interfaces/Unsorted", "*.crow")).ToArray ();
 
                        object tc = Color.AirForceBlueRaf;
-                       CrowInterface.LoadInterface(testFiles[idx]).DataSource = this;
+                       Load(testFiles[idx]).DataSource = this;
                }
                void KeyboardKeyDown1 (object sender, OpenTK.Input.KeyboardKeyEventArgs e)
                {
@@ -141,19 +141,19 @@ namespace Tests
                                NotifyValueChanged ("TestList", TestList);
                                return;
                        } else if (e.Key == OpenTK.Input.Key.F4) {
-                               GraphicObject w = CrowInterface.LoadInterface ("Interfaces/TemplatedContainer/testWindow.goml");
+                               GraphicObject w = Load ("Interfaces/TemplatedContainer/testWindow.goml");
                                w.DataSource = this;
                                return;
                        } else if (e.Key == OpenTK.Input.Key.F5) {
-                               GraphicObject w = CrowInterface.LoadInterface ("Interfaces/TemplatedContainer/testWindow2.goml");
+                               GraphicObject w = Load ("Interfaces/TemplatedContainer/testWindow2.goml");
                                w.DataSource = this;
                                return;
                        }else if (e.Key == OpenTK.Input.Key.F6) {
-                               GraphicObject w = CrowInterface.LoadInterface ("Interfaces/Divers/0.crow");
+                               GraphicObject w = Load ("Interfaces/Divers/0.crow");
                                w.DataSource = this;
                                return;
                        }else if (e.Key == OpenTK.Input.Key.F7) {
-                               GraphicObject w = CrowInterface.LoadInterface ("Interfaces/Divers/perfMeasures.crow");
+                               GraphicObject w = Load ("Interfaces/Divers/perfMeasures.crow");
                                w.DataSource = this;
                                return;
                        } else if (e.Key == OpenTK.Input.Key.F2)
@@ -162,61 +162,61 @@ namespace Tests
                                idx++;
                        else
                                return;
-               
+
                        try {
-                               CrowInterface.ClearInterface ();
+                               ClearInterface ();
 
                                if (idx == testFiles.Length)
                                        idx = 0;
                                else if (idx < 0)
                                        idx = testFiles.Length - 1;
-                               
+
                                this.Title = testFiles [idx] + ". Press <F3> to cycle examples.";
 
-                               GraphicObject obj = CrowInterface.LoadInterface(testFiles[idx]);
+                               GraphicObject obj = Load (testFiles[idx]);
                                obj.DataSource = this;
                        } catch (Exception ex) {
                                Debug.WriteLine (ex.Message + ex.InnerException);
                        }
                }
-               void Tv_SelectedItemChanged (object sender, SelectionChangeEventArgs e)
-               {
-                       FileInfo fi = e.NewValue as FileInfo;
-                       if (fi == null)
-                               return;
-                       if (fi.Extension == ".crow" || fi.Extension == ".goml") {
-                               Instantiator i = new Instantiator(fi.FullName);
-                               lock (CrowInterface.UpdateMutex) {
-                                       (CrowInterface.FindByName ("crowContainer") as Container).SetChild
-                                       (i.CreateInstance(CrowInterface));
-                                       //CurSources = i.GetImlSourcesCode();
-                               }
-                       }
-               }
-               void onImlSourceChanged(Object sender, TextChangeEventArgs e){
-                       Instantiator i;
-                       try {
-                               i = Instantiator.CreateFromImlFragment (e.Text);
-                       } catch (Exception ex) {
-                               Debug.WriteLine (ex);
-                               return;
-                       }
-                       lock (CrowInterface.UpdateMutex) {
-                               (CrowInterface.FindByName ("crowContainer") as Container).SetChild
-                               (i.CreateInstance(CrowInterface));
-                       }
-               }
+//             void Tv_SelectedItemChanged (object sender, SelectionChangeEventArgs e)
+//             {
+//                     FileInfo fi = e.NewValue as FileInfo;
+//                     if (fi == null)
+//                             return;
+//                     if (fi.Extension == ".crow" || fi.Extension == ".goml") {
+//                             Instantiator i = new Instantiator(fi.FullName);
+//                             lock (ifaceControl.CrowInterface.UpdateMutex) {
+//                                     (ifaceControl.CrowInterface.FindByName ("crowContainer") as Container).SetChild
+//                                     (i.CreateInstance(ifaceControl.CrowInterface));
+//                                     //CurSources = i.GetImlSourcesCode();
+//                             }
+//                     }
+//             }
+//             void onImlSourceChanged(Object sender, TextChangeEventArgs e){
+//                     Instantiator i;
+//                     try {
+//                             i = Instantiator.CreateFromImlFragment (e.Text);
+//                     } catch (Exception ex) {
+//                             Debug.WriteLine (ex);
+//                             return;
+//                     }
+//                     lock (ifaceControl.CrowInterface.UpdateMutex) {
+//                             (ifaceControl.CrowInterface.FindByName ("crowContainer") as Container).SetChild
+//                             (i.CreateInstance(ifaceControl.CrowInterface));
+//                     }
+//             }
                void onButClick(object send, MouseButtonEventArgs e)
                {
                        Console.WriteLine ("button clicked:" + send.ToString());
                }
-               void onAddTabButClick(object sender, MouseButtonEventArgs e){
-
-                       TabView tv = CrowInterface.FindByName("tabview1") as TabView;
-                       if (tv == null)
-                               return;
-                       tv.AddChild (new TabItem () { Caption = "NewTab" });
-               }
+//             void onAddTabButClick(object sender, MouseButtonEventArgs e){
+//
+//                     TabView tv = ifaceControl.CrowInterface.FindByName("tabview1") as TabView;
+//                     if (tv == null)
+//                             return;
+//                     tv.AddChild (new TabItem () { Caption = "NewTab" });
+//             }
                [STAThread]
                static void Main ()
                {
diff --git a/Tests/CrowWindow.cs b/Tests/CrowWindow.cs
new file mode 100644 (file)
index 0000000..2521174
--- /dev/null
@@ -0,0 +1,350 @@
+//
+//  OpenTKGameWindow.cs
+//
+//  Author:
+//       Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
+//
+//  Copyright (c) 2016 jp
+//
+//  This program is free software: you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation, either version 3 of the License, or
+//  (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+using System;
+using System.Threading;
+using OpenTK;
+using OpenTK.Graphics.OpenGL;
+using System.Collections.Generic;
+
+namespace Crow
+{
+       public class CrowWindow : GameWindow, IValueChange
+    {
+               #region IValueChange implementation
+               public event EventHandler<ValueChangeEventArgs> ValueChanged;
+               public virtual void NotifyValueChanged(string MemberName, object _value)
+               {
+                       if (ValueChanged != null)
+                               ValueChanged.Invoke(this, new ValueChangeEventArgs(MemberName, _value));
+               }
+               #endregion
+
+               #region FPS
+               int frameCpt = 0;
+               int _fps = 0;
+
+               public int fps {
+                       get { return _fps; }
+                       set {
+                               if (_fps == value)
+                                       return;
+
+                               _fps = value;
+                               #if MEASURE_TIME
+                               if (_fps > fpsMax) {
+                                       fpsMax = _fps;
+                                       ValueChanged.Raise(this, new ValueChangeEventArgs ("fpsMax", fpsMax));
+                               } else if (_fps < fpsMin) {
+                                       fpsMin = _fps;
+                                       ValueChanged.Raise(this, new ValueChangeEventArgs ("fpsMin", fpsMin));
+                               }
+                               #endif
+                               if (frameCpt % 3 == 0)
+                                       ValueChanged.Raise(this, new ValueChangeEventArgs ("fps", _fps));
+                               #if MEASURE_TIME
+//                             foreach (PerformanceMeasure m in PerfMeasures)
+//                                     m.NotifyChanges();
+                               #endif
+                       }
+               }
+
+               #if MEASURE_TIME
+               public PerformanceMeasure glDrawMeasure = new PerformanceMeasure("OpenGL Draw", 10);
+
+               public int fpsMin = int.MaxValue;
+               public int fpsMax = 0;
+
+               void resetFps ()
+               {
+                       fpsMin = int.MaxValue;
+                       fpsMax = 0;
+                       _fps = 0;
+               }
+               #endif
+
+               #endregion
+
+               #region ctor
+               public CrowWindow(int _width = 800, int _height = 600, string _title="Crow",
+                       int colors = 32, int depth = 24, int stencil = 0, int samples = 1,
+                       int major=3, int minor=3)
+                       : this(_width, _height, new OpenTK.Graphics.GraphicsMode(colors, depth, stencil, samples),
+                               _title,GameWindowFlags.Default,DisplayDevice.Default,
+                               major,minor,OpenTK.Graphics.GraphicsContextFlags.Default)
+               {
+               }
+               public CrowWindow (int width, int height, OpenTK.Graphics.GraphicsMode mode, string title, GameWindowFlags options, DisplayDevice device, int major, int minor, OpenTK.Graphics.GraphicsContextFlags flags)
+                       : base(width,height,mode,title,options,device,major,minor,flags)
+               {
+               }
+
+               #endregion
+
+               protected Shader shader;
+               public List<InterfaceControler> ifaceControl = new List<InterfaceControler>();
+               int focusedIdx = -1, activeIdx = -2;
+
+               void addInterfaceControler(InterfaceControler ifaceControler)
+               {
+                       ifaceControler.CrowInterface.Quit += Quit;
+                       ifaceControler.CrowInterface.MouseCursorChanged += CrowInterface_MouseCursorChanged;
+
+                       ifaceControl.Add (ifaceControler);
+               }
+               void openGLDraw(){
+                       //save GL states
+                       bool blend, depthTest, cullFace;
+                       GL.GetBoolean (GetPName.Blend, out blend);
+                       GL.GetBoolean (GetPName.DepthTest, out depthTest);
+                       GL.GetBoolean (GetPName.CullFace, out cullFace);
+                       GL.Enable (EnableCap.Blend);
+                       GL.Disable (EnableCap.DepthTest);
+                       GL.Disable (EnableCap.CullFace);
+
+                       #if MEASURE_TIME
+                       glDrawMeasure.StartCycle();
+                       #endif
+
+                       shader.Enable ();
+                       for (int i = 0; i < ifaceControl.Count; i++) {
+                               shader.SetMVP (ifaceControl [i].InterfaceMVP);
+                               ifaceControl [i].OpenGLDraw ();
+                       }
+
+                       #if MEASURE_TIME
+                       glDrawMeasure.StopCycle();
+                       #endif
+
+                       //restore GL states
+                       if (!blend)
+                               GL.Disable (EnableCap.Blend);
+                       if (depthTest)
+                               GL.Enable (EnableCap.DepthTest);
+                       if (cullFace)
+                               GL.Enable (EnableCap.CullFace);
+               }
+
+               public void Quit (object sender, EventArgs e)
+               {
+                       this.Exit ();
+               }
+               void CrowInterface_MouseCursorChanged (object sender, MouseCursorChangedEventArgs e)
+               {
+                       this.Cursor = new MouseCursor(
+                               (int)e.NewCursor.Xhot,
+                               (int)e.NewCursor.Yhot,
+                               (int)e.NewCursor.Width,
+                               (int)e.NewCursor.Height,
+                               e.NewCursor.data);
+               }
+
+               #region Events
+               //those events are raised only if mouse isn't in a graphic object
+               public event EventHandler<OpenTK.Input.MouseWheelEventArgs> MouseWheelChanged;
+               public event EventHandler<OpenTK.Input.MouseButtonEventArgs> MouseButtonUp;
+               public event EventHandler<OpenTK.Input.MouseButtonEventArgs> MouseButtonDown;
+               public event EventHandler<OpenTK.Input.MouseButtonEventArgs> MouseClick;
+               public event EventHandler<OpenTK.Input.MouseMoveEventArgs> MouseMove;
+               public event EventHandler<OpenTK.Input.KeyboardKeyEventArgs> KeyboardKeyDown;
+               public event EventHandler<OpenTK.Input.KeyboardKeyEventArgs> KeyboardKeyUp;
+
+               #endregion
+
+               public ProjectiveIFaceControler Add3DInterface(int width, int height, Matrix4 ifaceModelMat){
+                       ProjectiveIFaceControler tmp = new ProjectiveIFaceControler (new Rectangle (0, 0, width, height), ifaceModelMat);
+                       ifaceControl.Add (tmp);
+                       return tmp;
+               }
+               public GraphicObject AddWidget (GraphicObject g, int interfaceIdx = 0){
+                       if (ifaceControl.Count == 0)//create default orthogonal interface
+                               addInterfaceControler (new InterfaceControler (
+                                       new Rectangle (0, 0, this.ClientRectangle.Width, this.ClientRectangle.Height)));
+                       ifaceControl [interfaceIdx].CrowInterface.AddWidget (g);
+                       return g;
+               }
+               public GraphicObject Load (string path, int interfaceIdx = 0){
+                       if (ifaceControl.Count == 0)//create default orthogonal interface
+                               addInterfaceControler (new InterfaceControler (
+                                                       new Rectangle (0, 0, this.ClientRectangle.Width, this.ClientRectangle.Height)));
+                       return ifaceControl [interfaceIdx].CrowInterface.LoadInterface (path);
+               }
+               public void ClearInterface (int interfaceIdx = 0){
+                       ifaceControl [interfaceIdx].CrowInterface.ClearInterface ();
+               }
+               /// <summary>Override this method for your OpenGL rendering calls</summary>
+               public virtual void OnRender(FrameEventArgs e)
+               {
+               }
+               /// <summary>Override this method to customize clear method between frames</summary>
+               public virtual void GLClear()
+               {
+                       GL.Clear (ClearBufferMask.ColorBufferBit|ClearBufferMask.DepthBufferBit);
+               }
+
+               #region Game win overrides
+               protected override void OnLoad(EventArgs e)
+               {
+                       base.OnLoad(e);
+
+                       this.KeyPress += new EventHandler<OpenTK.KeyPressEventArgs>(OpenTKGameWindow_KeyPress);
+                       Keyboard.KeyDown += new EventHandler<OpenTK.Input.KeyboardKeyEventArgs>(Keyboard_KeyDown);
+                       Keyboard.KeyUp += new EventHandler<OpenTK.Input.KeyboardKeyEventArgs>(Keyboard_KeyUp);
+                       Mouse.WheelChanged += new EventHandler<OpenTK.Input.MouseWheelEventArgs>(Mouse_WheelChanged);
+                       Mouse.ButtonDown += new EventHandler<OpenTK.Input.MouseButtonEventArgs>(Mouse_ButtonDown);
+                       Mouse.ButtonUp += new EventHandler<OpenTK.Input.MouseButtonEventArgs>(Mouse_ButtonUp);
+                       Mouse.Move += new EventHandler<OpenTK.Input.MouseMoveEventArgs>(Mouse_Move);
+
+                       #if DEBUG
+                       Console.WriteLine("\n\n*************************************");
+                       Console.WriteLine("GL version: " + GL.GetString (StringName.Version));
+                       Console.WriteLine("GL vendor: " + GL.GetString (StringName.Vendor));
+                       Console.WriteLine("GLSL version: " + GL.GetString (StringName.ShadingLanguageVersion));
+                       Console.WriteLine("*************************************\n");
+                       #endif
+
+                       shader = new Shader ();
+                       shader.Enable ();
+
+                       GL.ClearColor(0.0f, 0.0f, 0.0f, 0.0f);
+               }
+               protected override void OnUpdateFrame(FrameEventArgs e)
+               {
+                       base.OnUpdateFrame(e);
+                       fps = (int)RenderFrequency;
+
+                       #if MEASURE_TIME
+                       if (frameCpt > 500) {
+                               resetFps ();
+                               frameCpt = 0;
+//                             #if DEBUG
+//                             GC.Collect();
+//                             GC.WaitForPendingFinalizers();
+//                             NotifyValueChanged("memory", GC.GetTotalMemory (false).ToString());
+//                             #endif
+                       }
+                       #endif
+
+                       frameCpt++;
+               }
+               protected override void OnRenderFrame(FrameEventArgs e)
+               {
+                       GLClear ();
+
+                       base.OnRenderFrame(e);
+
+                       OnRender (e);
+                       openGLDraw ();
+
+
+                       SwapBuffers ();
+               }
+               protected override void OnResize(EventArgs e)
+               {
+                       base.OnResize (e);
+                       for (int i = 0; i < ifaceControl.Count; i++) {
+                               ifaceControl[i].ProcessResize(
+                                       new Rectangle(
+                                               0,
+                                               0,
+                                               this.ClientRectangle.Width,
+                                               this.ClientRectangle.Height));
+                       }
+               }
+               #endregion
+
+               #region Mouse and Keyboard Handling
+               void update_mouseButtonStates(ref MouseState e, OpenTK.Input.MouseState otk_e){
+                       for (int i = 0; i < MouseState.MaxButtons; i++) {
+                               if (otk_e.IsButtonDown ((OpenTK.Input.MouseButton)i))
+                                       e.EnableBit (i);
+                       }
+               }
+               protected virtual void Mouse_Move(object sender, OpenTK.Input.MouseMoveEventArgs otk_e)
+        {
+                       if (activeIdx == -2) {
+                               focusedIdx = -1;
+                               for (int i = 0; i < ifaceControl.Count; i++) {
+                                       if (ifaceControl [i].ProcessMouseMove (otk_e.X, otk_e.Y)) {
+                                               focusedIdx = i;
+                                               return;
+                                       }
+                               }
+                       } else if (focusedIdx >= 0) {
+                               ifaceControl [focusedIdx].ProcessMouseMove (otk_e.X, otk_e.Y);
+                               return;
+                       }
+                       if (focusedIdx < 0)
+                               MouseMove.Raise (sender, otk_e);
+        }
+               protected virtual void Mouse_ButtonUp(object sender, OpenTK.Input.MouseButtonEventArgs otk_e)
+        {
+                       activeIdx = -2;
+                       if (focusedIdx >= 0) {
+                               if (ifaceControl [focusedIdx].ProcessMouseButtonUp ((int)otk_e.Button))
+                                       return;
+                       }
+                       MouseButtonUp.Raise (sender, otk_e);
+        }
+               protected virtual void Mouse_ButtonDown(object sender, OpenTK.Input.MouseButtonEventArgs otk_e)
+               {
+                       activeIdx = focusedIdx;
+                       if (focusedIdx >= 0) {
+                               if (ifaceControl [focusedIdx].ProcessMouseButtonDown ((int)otk_e.Button))
+                                       return;
+                       }
+                       MouseButtonDown.Raise (sender, otk_e);
+        }
+               protected virtual void Mouse_WheelChanged(object sender, OpenTK.Input.MouseWheelEventArgs otk_e)
+        {
+                       if (focusedIdx >= 0) {
+                               if (ifaceControl [focusedIdx].ProcessMouseWheelChanged (otk_e.DeltaPrecise))
+                                       return;
+                       }
+                       MouseWheelChanged.Raise (sender, otk_e);
+        }
+
+               protected virtual void Keyboard_KeyDown(object sender, OpenTK.Input.KeyboardKeyEventArgs otk_e)
+               {
+                       if (focusedIdx >= 0) {
+                               if (ifaceControl [focusedIdx].ProcessKeyDown((int)otk_e.Key))
+                                       return;
+                       }
+                       KeyboardKeyDown.Raise (this, otk_e);
+        }
+               protected virtual void Keyboard_KeyUp(object sender, OpenTK.Input.KeyboardKeyEventArgs otk_e)
+               {
+                       if (focusedIdx >= 0) {
+                               if (ifaceControl [focusedIdx].ProcessKeyUp((int)otk_e.Key))
+                                       return;
+                       }
+                       KeyboardKeyUp.Raise (this, otk_e);
+               }
+               protected virtual void OpenTKGameWindow_KeyPress (object sender, OpenTK.KeyPressEventArgs e)
+               {
+                       if (focusedIdx >= 0) {
+                               if (ifaceControl [focusedIdx].ProcessKeyPress (e.KeyChar))
+                                       return;
+                       }
+                       //TODO:create keyboardkeypress evt
+               }
+        #endregion
+    }
+}
diff --git a/Tests/Hello3D.cs b/Tests/Hello3D.cs
new file mode 100644 (file)
index 0000000..c03a5ce
--- /dev/null
@@ -0,0 +1,149 @@
+//
+//  HelloCube.cs
+//
+//  Author:
+//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+//  Copyright (c) 2016 jp
+//
+//  This program is free software: you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation, either version 3 of the License, or
+//  (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+using System;
+using OpenTK;
+using OpenTK.Graphics.OpenGL;
+using Crow;
+
+namespace Tests
+{
+       class Hello3D : CrowWindow
+       {
+               [STAThread]
+               static void Main ()
+               {
+                       Hello3D win = new Hello3D ();
+                       win.Run (30);
+               }
+
+               public Hello3D ()
+                       : base(800, 600,"Crow Test with OpenTK")
+               {
+               }
+
+               public Matrix4 modelview, projection;
+               public int[] viewport = new int[4];
+               public Vector3 vEyeTarget = new Vector3(0f, 0f, 0f);
+               public Vector3 vEye;
+               public Vector3 vLookInit = Vector3.Normalize(new Vector3(-1.0f, -1.0f, 1.0f));
+               public Vector3 vLook;  // Camera vLook Vector
+               public float zNear = 0.001f, zFar = 300.0f;
+               public float fovY = (float)Math.PI / 4;
+               public float eyeDist = 10.2f;
+               public float viewZangle, viewXangle;
+               public const float MoveSpeed = 0.02f;
+               public const float RotationSpeed = 0.005f;
+               public const float ZoomSpeed = 0.22f;
+
+               vaoMesh cube;
+               Texture texture;
+               ProjectiveIFaceControler iface3D;
+
+               void initGL(){
+                       GL.Enable (EnableCap.CullFace);
+                       GL.Enable (EnableCap.Blend);
+                       GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);
+
+                       cube = vaoMesh.CreateCube ();
+                       texture = new Texture ("image/textest.png");
+               }
+
+               protected override void OnLoad (EventArgs e)
+               {
+                       base.OnLoad (e);
+
+                       MouseMove += HelloCube_MouseMove;
+                       MouseWheelChanged += Hello3D_MouseWheelChanged;
+
+                       iface3D = Add3DInterface (2048, 2048,
+                               Matrix4.CreateScale (6f) *
+                               Matrix4.CreateRotationX (MathHelper.PiOver2) *
+                               Matrix4.CreateTranslation (Vector3.UnitY * -1.1f));
+                       Load (@"Interfaces/Divers/0.crow").DataSource = this;
+                       initGL ();
+                       shader.Enable ();
+               }
+
+               protected override void OnResize (EventArgs e)
+               {
+                       base.OnResize (e);
+                       UpdateViewMatrix ();
+               }
+
+               public override void OnRender (FrameEventArgs e)
+               {                       
+                       base.OnRender (e);
+
+                       shader.SetMVP(modelview * projection);
+
+                       GL.BindTexture (TextureTarget.Texture2D, texture);
+                       cube.Render (BeginMode.Triangles);
+                       GL.BindTexture (TextureTarget.Texture2D, 0);
+               }
+
+               public void UpdateViewMatrix()
+               {
+                       Rectangle r = this.ClientRectangle;
+                       GL.Viewport( r.X, r.Y, r.Width, r.Height);
+                       projection = Matrix4.CreatePerspectiveFieldOfView (fovY, r.Width / (float)r.Height, zNear, zFar);
+                       vLook = vLookInit.Transform(
+                               Matrix4.CreateRotationX (viewXangle)*
+                               Matrix4.CreateRotationZ (viewZangle));
+                       vLook.Normalize();
+                       vEye = vEyeTarget + vLook * eyeDist;
+                       modelview = Matrix4.LookAt(vEye, vEyeTarget, Vector3.UnitZ);
+                       GL.GetInteger(GetPName.Viewport, viewport);
+
+                       iface3D.UpdateView (projection, modelview, viewport, vEye);
+               }
+
+               void HelloCube_MouseMove(object sender, OpenTK.Input.MouseMoveEventArgs otk_e)
+               {
+                       if (otk_e.Mouse.MiddleButton == OpenTK.Input.ButtonState.Pressed) {
+                               viewZangle -= (float)otk_e.XDelta * RotationSpeed;
+                               viewXangle -= (float)otk_e.YDelta * RotationSpeed;
+                               UpdateViewMatrix ();
+                       } else if (otk_e.Mouse.LeftButton == OpenTK.Input.ButtonState.Pressed) {
+                               return;
+                       } else if (otk_e.Mouse.RightButton == OpenTK.Input.ButtonState.Pressed) {
+                               Vector2 v2Look = vLook.Xy.Normalized ();
+                               Vector2 disp = v2Look.PerpendicularLeft * otk_e.XDelta * MoveSpeed +
+                                       v2Look * otk_e.YDelta * MoveSpeed;
+                               vEyeTarget += new Vector3 (disp.X, disp.Y, 0);
+                               UpdateViewMatrix ();
+                       }
+               }
+               void Hello3D_MouseWheelChanged (object sender, OpenTK.Input.MouseWheelEventArgs e)
+               {
+                       float speed = ZoomSpeed;
+                       if (Keyboard[OpenTK.Input.Key.ControlLeft])
+                               speed *= 20.0f;
+
+                       eyeDist -= e.Delta * speed;
+                       if (eyeDist < zNear)
+                               eyeDist = zNear;
+                       else if (eyeDist > zFar)
+                               eyeDist = zFar;
+                       UpdateViewMatrix ();
+               }
+       }
+}
\ No newline at end of file
index e45e8d309ce0e92665c86e7d7f4b9ce2ed012008..d9223f5adadf46d1869988512256ce1a1484679c 100644 (file)
@@ -26,7 +26,7 @@ using Crow;
 
 namespace Tests
 {
-       class HelloCube : OpenTKGameWindow
+       class HelloCube : CrowWindow
        {
                [STAThread]
                static void Main ()
@@ -63,7 +63,7 @@ namespace Tests
                {
                        base.OnLoad (e);
 
-                       CrowInterface.AddWidget(
+                       AddWidget(
                                new Window ()
                                {
                                        Title = "Hello World"
index 223623934200a193e8c69df2cf5e88f320274f7e..a38c7974d55d09889b5f8a8057d552d5f4eeb103 100644 (file)
@@ -3,7 +3,7 @@ using Crow;
 
 namespace Tests
 {
-       class HelloWorld : OpenTKGameWindow
+       class HelloWorld : CrowWindow
        {
                public HelloWorld ()
                        : base(800, 600,"Crow Test with OpenTK")
@@ -14,7 +14,7 @@ namespace Tests
                {
                        base.OnLoad (e);
 
-                       CrowInterface.AddWidget(new Label("Hello World"));
+                       AddWidget(new Label("Hello World"));
                }
 
                [STAThread]
diff --git a/Tests/InterfaceControler.cs b/Tests/InterfaceControler.cs
new file mode 100644 (file)
index 0000000..6cb13b2
--- /dev/null
@@ -0,0 +1,220 @@
+//
+//  InterfaceControler.cs
+//
+//  Author:
+//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+//  Copyright (c) 2017 jp
+//
+//  This program is free software: you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation, either version 3 of the License, or
+//  (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+using System;
+using OpenTK;
+using OpenTK.Graphics.OpenGL;
+using System.Threading;
+using System.Collections.Generic;
+
+namespace Crow
+{
+       public class ProjectiveIFaceControler : InterfaceControler {
+               Matrix4 modelview;
+               int[] viewport = new int[4];
+               Vector3 vEyePosition;
+
+               public Matrix4 ifaceModelMat;
+               Point localMousePos;
+
+               public ProjectiveIFaceControler(Rectangle ifaceBounds, Matrix4 _ifaceModelMat)
+                       : base(ifaceBounds){
+                       ifaceModelMat = _ifaceModelMat;
+               }
+
+               public override Matrix4 InterfaceMVP {
+                       get { return ifaceModelMat * modelview * projection; }
+               }
+
+               public override void initGL(){                  
+                       quad = new Crow.vaoMesh (0, 0, 0, 1, 1, 1, -1);
+                       //ifaceModelMat = Matrix4.CreateRotationX(MathHelper.PiOver2) * Matrix4.CreateTranslation(Vector3.UnitY);
+                       CrowInterface.ProcessResize(iRect);
+                       createContext ();
+                       //CrowInterface.ProcessResize (iRect);
+               }
+               public override void ProcessResize (Rectangle newSize)
+               {
+               }
+
+               public void UpdateView (Matrix4 _projection, Matrix4 _modelview, int[] _viewport, Vector3 _vEyePosition)
+               {
+                       projection = _projection;
+                       modelview = _modelview;
+                       viewport = _viewport;
+                       vEyePosition = _vEyePosition;
+               }
+               public override bool ProcessMouseMove (int x, int y)
+               {
+                       Matrix4 mv = ifaceModelMat * modelview;
+                       Vector3 vMouse = Extensions.UnProject(ref projection, ref mv, viewport, new Vector2 (x, y)).Xyz;
+                       Vector3 vE = vEyePosition.Transform (ifaceModelMat.Inverted());
+                       Vector3 vMouseRay = Vector3.Normalize(vMouse - vE);
+                       float a = vE.Z / vMouseRay.Z;
+                       vMouse = vE - vMouseRay * a;
+                       //vMouse = vMouse.Transform (interfaceModelView.Inverted());
+                       localMousePos = new Point ((int)Math.Truncate ((vMouse.X + 0.5f) * iRect.Width),
+                               iRect.Height - (int)Math.Truncate ((vMouse.Y + 0.5f) * iRect.Height));
+                       mouseIsInInterface = localMousePos.X.IsInBetween (0, iRect.Width) & localMousePos.Y.IsInBetween (0, iRect.Height);
+
+                       return mouseIsInInterface ? CrowInterface.ProcessMouseMove (localMousePos.X, localMousePos.Y) : false;
+               }
+       }
+       public class InterfaceControler {
+               public Interface CrowInterface;
+               public int texID;
+               public vaoMesh quad;
+               public Rectangle iRect = new Rectangle(0,0,2048,2048);
+               public bool mouseIsInInterface = false;
+
+               protected Matrix4 projection;
+               public virtual Matrix4 InterfaceMVP {
+                       get { return projection; }
+               }
+
+               #if MEASURE_TIME
+               public List<PerformanceMeasure> PerfMeasures;
+               public PerformanceMeasure glDrawMeasure = new PerformanceMeasure("OpenGL Draw", 10);
+               #endif
+
+               #region CTOR
+               public InterfaceControler(Rectangle ifaceBounds){
+                       iRect = ifaceBounds;
+
+                       CrowInterface = new Interface ();
+
+                       #if MEASURE_TIME
+                       PerfMeasures = new List<PerformanceMeasure> (
+                               new PerformanceMeasure[] {
+                                       this.CrowInterface.updateMeasure,
+                                       this.CrowInterface.layoutingMeasure,
+                                       this.CrowInterface.clippingMeasure,
+                                       this.CrowInterface.drawingMeasure,
+                                       this.glDrawMeasure
+                               }
+                       );
+                       #endif
+
+                       Thread t = new Thread (interfaceThread);
+                       t.IsBackground = true;
+                       t.Start ();
+
+                       initGL ();
+               }
+               #endregion
+
+               void interfaceThread()
+               {
+                       while (CrowInterface.ClientRectangle.Size.Width == 0)
+                               Thread.Sleep (5);
+
+                       while (true) {
+                               CrowInterface.Update ();
+                               //Thread.Sleep (1);
+                       }
+               }
+
+               #region Mouse And Keyboard handling
+               public virtual void ProcessResize(Rectangle newSize){
+                       iRect = newSize;
+                       CrowInterface.ProcessResize(newSize);
+                       createContext ();
+                       GL.Viewport (0, 0, newSize.Width, newSize.Height);//TODO:find a better place for this
+               }
+               public virtual bool ProcessMouseMove(int x, int y){
+                       return CrowInterface.ProcessMouseMove (x, y);
+               }
+               public virtual bool ProcessMouseButtonUp(int button)
+               {
+                       return CrowInterface.ProcessMouseButtonUp (button);
+               }
+               public virtual bool ProcessMouseButtonDown(int button)
+               {
+                       return CrowInterface.ProcessMouseButtonDown (button);
+               }
+               public virtual bool ProcessMouseWheelChanged(float delta)
+               {
+                       return CrowInterface.ProcessMouseWheelChanged (delta);
+               }
+               public virtual bool ProcessKeyDown(int Key){
+                       return CrowInterface.ProcessKeyDown(Key);
+               }
+               public virtual bool ProcessKeyUp(int Key){
+                       return CrowInterface.ProcessKeyUp(Key);
+               }
+               public virtual bool ProcessKeyPress(char Key){
+                       return CrowInterface.ProcessKeyPress(Key);
+               }
+               #endregion
+
+               #region graphic context
+               public virtual void initGL(){                   
+                       projection = OpenTK.Matrix4.CreateOrthographicOffCenter (-0.5f, 0.5f, -0.5f, 0.5f, 1, -1);
+                       quad = new Crow.vaoMesh (0, 0, 0, 1, 1, 1, -1);
+                       createContext ();
+               }
+               /// <summary>Create the texture for the interface redering</summary>
+               public virtual void createContext()
+               {
+                       if (GL.IsTexture(texID))
+                               GL.DeleteTexture (texID);
+                       GL.GenTextures(1, out texID);
+                       GL.ActiveTexture (TextureUnit.Texture0);
+                       GL.BindTexture(TextureTarget.Texture2D, texID);
+
+                       GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba,
+                               iRect.Width, iRect.Height, 0,
+                               OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, CrowInterface.bmp);
+
+                       GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
+                       GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
+
+                       GL.BindTexture(TextureTarget.Texture2D, 0);
+               }
+               /// <summary>Rendering of the interface</summary>
+               public virtual void OpenGLDraw()
+               {
+                       #if MEASURE_TIME
+                       glDrawMeasure.StartCycle();
+                       #endif
+
+                       GL.ActiveTexture (TextureUnit.Texture0);
+                       GL.BindTexture (TextureTarget.Texture2D, texID);
+                       if (Monitor.TryEnter(CrowInterface.RenderMutex)) {
+                               if (CrowInterface.IsDirty) {
+                                       GL.TexSubImage2D (TextureTarget.Texture2D, 0,
+                                               CrowInterface.DirtyRect.Left, CrowInterface.DirtyRect.Top,
+                                               CrowInterface.DirtyRect.Width, CrowInterface.DirtyRect.Height,
+                                               OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, CrowInterface.dirtyBmp);
+                                       CrowInterface.IsDirty = false;
+                               }
+                               Monitor.Exit (CrowInterface.RenderMutex);
+                       }
+                       quad.Render (BeginMode.TriangleStrip);
+                       GL.BindTexture(TextureTarget.Texture2D, 0);
+
+                       #if MEASURE_TIME
+                       glDrawMeasure.StopCycle();
+                       #endif
+               }
+               #endregion
+       }
+}
+
diff --git a/Tests/OpenGL/Extensions.cs b/Tests/OpenGL/Extensions.cs
new file mode 100644 (file)
index 0000000..17fe608
--- /dev/null
@@ -0,0 +1,64 @@
+//
+//  Extensions.cs
+//
+//  Author:
+//       Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+//  Copyright (c) 2017 jp
+//
+//  This program is free software: you can redistribute it and/or modify
+//  it under the terms of the GNU General Public License as published by
+//  the Free Software Foundation, either version 3 of the License, or
+//  (at your option) any later version.
+//
+//  This program is distributed in the hope that it will be useful,
+//  but WITHOUT ANY WARRANTY; without even the implied warranty of
+//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+//  GNU General Public License for more details.
+//
+//  You should have received a copy of the GNU General Public License
+//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
+using System;
+using OpenTK;
+using Crow;
+
+namespace Crow
+{
+       public static class Extensions {
+               public static Vector4 ToVector4(this Color c){
+                       float[] f = c.floatArray;
+                       return new Vector4 (f [0], f [1], f [2], f [3]);
+               }
+               public static Vector3 Transform(this Vector3 v, Matrix4 m){
+                       return Vector4.Transform(new Vector4(v, 1), m).Xyz;
+               }
+               public static bool IsInBetween(this int v, int min, int max){
+                       return v >= min & v <= max;
+               }
+               public static Vector4 UnProject(ref Matrix4 projection, ref Matrix4 view, int[] viewport, Vector2 mouse)
+               {
+                       Vector4 vec;
+
+                       vec.X = 2.0f * mouse.X / (float)viewport[2] - 1;
+                       vec.Y = -(2.0f * mouse.Y / (float)viewport[3] - 1);
+                       vec.Z = 0f;
+                       vec.W = 1.0f;
+
+                       Matrix4 viewInv = Matrix4.Invert(view);
+                       Matrix4 projInv = Matrix4.Invert(projection);
+
+                       Vector4.Transform(ref vec, ref projInv, out vec);
+                       Vector4.Transform(ref vec, ref viewInv, out vec);
+
+                       if (vec.W > float.Epsilon || vec.W < float.Epsilon)
+                       {
+                               vec.X /= vec.W;
+                               vec.Y /= vec.W;
+                               vec.Z /= vec.W;
+                       }
+
+                       return vec;
+               }
+       }
+}
+
diff --git a/Tests/OpenTKGameWindow.cs b/Tests/OpenTKGameWindow.cs
deleted file mode 100644 (file)
index 1f10307..0000000
+++ /dev/null
@@ -1,358 +0,0 @@
-//
-//  OpenTKGameWindow.cs
-//
-//  Author:
-//       Jean-Philippe Bruyère <jp_bruyere@hotmail.com>
-//
-//  Copyright (c) 2016 jp
-//
-//  This program is free software: you can redistribute it and/or modify
-//  it under the terms of the GNU General Public License as published by
-//  the Free Software Foundation, either version 3 of the License, or
-//  (at your option) any later version.
-//
-//  This program is distributed in the hope that it will be useful,
-//  but WITHOUT ANY WARRANTY; without even the implied warranty of
-//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-//  GNU General Public License for more details.
-//
-//  You should have received a copy of the GNU General Public License
-//  along with this program.  If not, see <http://www.gnu.org/licenses/>.
-using System;
-using System.Threading;
-using OpenTK;
-using OpenTK.Graphics.OpenGL;
-using System.Collections.Generic;
-
-namespace Crow
-{
-       public class OpenTKGameWindow : GameWindow, IValueChange
-    {
-               #region IValueChange implementation
-               public event EventHandler<ValueChangeEventArgs> ValueChanged;
-               public virtual void NotifyValueChanged(string MemberName, object _value)
-               {
-                       if (ValueChanged != null)                               
-                               ValueChanged.Invoke(this, new ValueChangeEventArgs(MemberName, _value));
-               }
-               #endregion
-
-               public Interface CrowInterface;
-
-               #region FPS
-               int frameCpt = 0;
-               int _fps = 0;
-
-               public int fps {
-                       get { return _fps; }
-                       set {
-                               if (_fps == value)
-                                       return;
-
-                               _fps = value;
-
-                               if (_fps > fpsMax) {
-                                       fpsMax = _fps;
-                                       ValueChanged.Raise(this, new ValueChangeEventArgs ("fpsMax", fpsMax));
-                               } else if (_fps < fpsMin) {
-                                       fpsMin = _fps;
-                                       ValueChanged.Raise(this, new ValueChangeEventArgs ("fpsMin", fpsMin));
-                               }
-                               if (frameCpt % 3 == 0)
-                                       ValueChanged.Raise(this, new ValueChangeEventArgs ("fps", _fps));
-                               #if MEASURE_TIME
-                               foreach (PerformanceMeasure m in PerfMeasures)
-                                       m.NotifyChanges();
-                               #endif
-                       }
-               }
-
-               public int fpsMin = int.MaxValue;
-               public int fpsMax = 0;
-
-               void resetFps ()
-               {
-                       fpsMin = int.MaxValue;
-                       fpsMax = 0;
-                       _fps = 0;
-               }
-               public string update = "";
-               public string drawing = "";
-               public string layouting = "";
-               public string clipping = "";
-               #if MEASURE_TIME
-               public PerformanceMeasure glDrawMeasure = new PerformanceMeasure("OpenGL Draw", 10);
-               #endif
-
-               #endregion
-
-               #region ctor
-               public OpenTKGameWindow(int _width = 800, int _height = 600, string _title="Crow",
-                       int colors = 32, int depth = 24, int stencil = 0, int samples = 1,
-                       int major=3, int minor=3)
-                       : this(_width, _height, new OpenTK.Graphics.GraphicsMode(colors, depth, stencil, samples),
-                               _title,GameWindowFlags.Default,DisplayDevice.Default,
-                               major,minor,OpenTK.Graphics.GraphicsContextFlags.Default)
-               {
-               }
-               public OpenTKGameWindow (int width, int height, OpenTK.Graphics.GraphicsMode mode, string title, GameWindowFlags options, DisplayDevice device, int major, int minor, OpenTK.Graphics.GraphicsContextFlags flags)
-                       : base(width,height,mode,title,options,device,major,minor,flags)
-               {
-                       CrowInterface = new Interface ();
-
-                       #if MEASURE_TIME
-                       PerfMeasures = new List<PerformanceMeasure> (
-                               new PerformanceMeasure[] {
-                                       this.CrowInterface.updateMeasure,
-                                       this.CrowInterface.layoutingMeasure,
-                                       this.CrowInterface.clippingMeasure,
-                                       this.CrowInterface.drawingMeasure,
-                                       this.glDrawMeasure
-                               }
-                       );
-                       #endif
-
-                       Thread t = new Thread (interfaceThread);
-                       t.IsBackground = true;
-                       t.Start ();
-               }
-
-               #endregion
-
-               #if MEASURE_TIME
-               public List<PerformanceMeasure> PerfMeasures;
-               #endif
-
-               void interfaceThread()
-               {
-                       CrowInterface.Quit += Quit;
-                       CrowInterface.MouseCursorChanged += CrowInterface_MouseCursorChanged;
-                       while (CrowInterface.ClientRectangle.Size.Width == 0)
-                               Thread.Sleep (5);
-                       
-                       while (true) {
-                               CrowInterface.Update ();
-                               //Thread.Sleep (1);
-                       }
-               }
-
-               public void Quit (object sender, EventArgs e)
-               {
-                       this.Exit ();
-               }
-               void CrowInterface_MouseCursorChanged (object sender, MouseCursorChangedEventArgs e)
-               {
-                       this.Cursor = new MouseCursor(
-                               (int)e.NewCursor.Xhot,
-                               (int)e.NewCursor.Yhot,
-                               (int)e.NewCursor.Width,
-                               (int)e.NewCursor.Height,
-                               e.NewCursor.data);
-               }
-
-               #region Events
-               //those events are raised only if mouse isn't in a graphic object
-               public event EventHandler<OpenTK.Input.MouseWheelEventArgs> MouseWheelChanged;
-               public event EventHandler<OpenTK.Input.MouseButtonEventArgs> MouseButtonUp;
-               public event EventHandler<OpenTK.Input.MouseButtonEventArgs> MouseButtonDown;
-               public event EventHandler<OpenTK.Input.MouseButtonEventArgs> MouseClick;
-               public event EventHandler<OpenTK.Input.MouseMoveEventArgs> MouseMove;
-               public event EventHandler<OpenTK.Input.KeyboardKeyEventArgs> KeyboardKeyDown;
-               public event EventHandler<OpenTK.Input.KeyboardKeyEventArgs> KeyboardKeyUp;
-
-               #endregion
-
-               #region graphic context
-               public int texID;
-               public Shader shader;
-               public vaoMesh quad;
-               public Matrix4 projection;
-
-               void createContext()
-               {
-                       #region Create texture
-                       if (GL.IsTexture(texID))
-                               GL.DeleteTexture (texID);
-                       GL.GenTextures(1, out texID);
-                       GL.ActiveTexture (TextureUnit.Texture0);
-                       GL.BindTexture(TextureTarget.Texture2D, texID);
-
-                       GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba,
-                               ClientRectangle.Width, ClientRectangle.Height, 0,
-                               OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, CrowInterface.bmp);
-
-                       GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Linear);
-                       GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Linear);
-
-                       GL.BindTexture(TextureTarget.Texture2D, 0);
-                       #endregion
-               }
-               void OpenGLDraw()
-               {
-                       #if MEASURE_TIME
-                       glDrawMeasure.StartCycle();
-                       #endif
-                       bool blend, depthTest;
-                       GL.GetBoolean (GetPName.Blend, out blend);
-                       GL.GetBoolean (GetPName.DepthTest, out depthTest);
-                       GL.Enable (EnableCap.Blend);
-                       GL.Disable (EnableCap.DepthTest);
-
-                       shader.Enable ();
-                       shader.SetMVP (projection);
-                       GL.ActiveTexture (TextureUnit.Texture0);
-                       GL.BindTexture (TextureTarget.Texture2D, texID);
-                       if (Monitor.TryEnter(CrowInterface.RenderMutex)) {
-                               if (CrowInterface.IsDirty) {
-                                       GL.TexSubImage2D (TextureTarget.Texture2D, 0,
-                                               CrowInterface.DirtyRect.Left, CrowInterface.DirtyRect.Top,
-                                               CrowInterface.DirtyRect.Width, CrowInterface.DirtyRect.Height,
-                                               OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, CrowInterface.dirtyBmp);
-                                       CrowInterface.IsDirty = false;
-                               }
-                               Monitor.Exit (CrowInterface.RenderMutex);
-                       }
-                       quad.Render (BeginMode.TriangleStrip);
-                       GL.BindTexture(TextureTarget.Texture2D, 0);
-
-                       if (!blend)
-                               GL.Disable (EnableCap.Blend);
-                       if (depthTest)
-                               GL.Enable (EnableCap.DepthTest);
-                       #if MEASURE_TIME
-                       glDrawMeasure.StopCycle();
-                       #endif
-               }
-               #endregion
-
-               /// <summary>
-               /// Override this method for your OpenGL rendering calls
-               /// </summary>
-               public virtual void OnRender(FrameEventArgs e)
-               {
-               }
-               /// <summary>
-               /// Override this method to customize clear method between frames
-               /// </summary>
-               public virtual void GLClear()
-               {
-                       GL.Clear (ClearBufferMask.ColorBufferBit|ClearBufferMask.DepthBufferBit);
-               }
-
-               #region Game win overrides
-               protected override void OnLoad(EventArgs e)
-               {
-                       base.OnLoad(e);
-
-                       this.KeyPress += new EventHandler<OpenTK.KeyPressEventArgs>(OpenTKGameWindow_KeyPress);
-                       Keyboard.KeyDown += new EventHandler<OpenTK.Input.KeyboardKeyEventArgs>(Keyboard_KeyDown);
-                       Keyboard.KeyUp += new EventHandler<OpenTK.Input.KeyboardKeyEventArgs>(Keyboard_KeyUp);
-                       Mouse.WheelChanged += new EventHandler<OpenTK.Input.MouseWheelEventArgs>(Mouse_WheelChanged);
-                       Mouse.ButtonDown += new EventHandler<OpenTK.Input.MouseButtonEventArgs>(Mouse_ButtonDown);
-                       Mouse.ButtonUp += new EventHandler<OpenTK.Input.MouseButtonEventArgs>(Mouse_ButtonUp);
-                       Mouse.Move += new EventHandler<OpenTK.Input.MouseMoveEventArgs>(Mouse_Move);
-
-                       GL.ClearColor(0.0f, 0.0f, 0.0f, 0.0f);
-
-                       Console.WriteLine("\n\n*************************************");
-                       Console.WriteLine("GL version: " + GL.GetString (StringName.Version));
-                       Console.WriteLine("GL vendor: " + GL.GetString (StringName.Vendor));
-                       Console.WriteLine("GLSL version: " + GL.GetString (StringName.ShadingLanguageVersion));
-                       Console.WriteLine("*************************************\n");
-
-                       projection = OpenTK.Matrix4.CreateOrthographicOffCenter (-0.5f, 0.5f, -0.5f, 0.5f, 1, -1);
-
-                       shader = new Shader ();
-                       quad = new Crow.vaoMesh (0, 0, 0, 1, 1, 1, -1);
-               }
-
-               protected override void OnUpdateFrame(FrameEventArgs e)
-               {
-                       base.OnUpdateFrame(e);
-                       fps = (int)RenderFrequency;
-
-
-                       if (frameCpt > 500) {
-                               resetFps ();
-                               frameCpt = 0;
-//                             #if DEBUG
-//                             GC.Collect();
-//                             GC.WaitForPendingFinalizers();
-//                             NotifyValueChanged("memory", GC.GetTotalMemory (false).ToString());
-//                             #endif
-                       }
-                       frameCpt++;
-               }
-               protected override void OnRenderFrame(FrameEventArgs e)
-               {
-                       GLClear ();
-
-                       base.OnRenderFrame(e);
-
-                       OnRender (e);
-                       OpenGLDraw ();
-
-                       SwapBuffers ();
-               }
-
-               protected override void OnResize(EventArgs e)
-               {
-                       base.OnResize (e);
-                       CrowInterface.ProcessResize(
-                               new Rectangle(
-                               0,
-                               0,
-                               this.ClientRectangle.Width,
-                               this.ClientRectangle.Height));
-                       createContext ();
-                       GL.Viewport (0, 0, ClientRectangle.Width, ClientRectangle.Height);
-               }
-               #endregion
-
-               #region Mouse Handling
-               void update_mouseButtonStates(ref MouseState e, OpenTK.Input.MouseState otk_e){
-                       for (int i = 0; i < MouseState.MaxButtons; i++) {
-                               if (otk_e.IsButtonDown ((OpenTK.Input.MouseButton)i))
-                                       e.EnableBit (i);
-                       }
-               }
-               void Mouse_Move(object sender, OpenTK.Input.MouseMoveEventArgs otk_e)
-        {
-                       if (!CrowInterface.ProcessMouseMove (otk_e.X, otk_e.Y))
-                               MouseMove.Raise (sender, otk_e);
-        }
-               void Mouse_ButtonUp(object sender, OpenTK.Input.MouseButtonEventArgs otk_e)
-        {
-                       if (!CrowInterface.ProcessMouseButtonUp ((int)otk_e.Button))
-                               MouseButtonUp.Raise (sender, otk_e);
-        }
-               void Mouse_ButtonDown(object sender, OpenTK.Input.MouseButtonEventArgs otk_e)
-               {
-                       if (!CrowInterface.ProcessMouseButtonDown ((int)otk_e.Button))
-                               MouseButtonDown.Raise (sender, otk_e);
-        }
-               void Mouse_WheelChanged(object sender, OpenTK.Input.MouseWheelEventArgs otk_e)
-        {
-                       if (!CrowInterface.ProcessMouseWheelChanged (otk_e.DeltaPrecise))
-                               MouseWheelChanged.Raise (sender, otk_e);
-        }
-               #endregion
-
-               #region keyboard Handling
-               void Keyboard_KeyDown(object sender, OpenTK.Input.KeyboardKeyEventArgs otk_e)
-               {
-                       if (!CrowInterface.ProcessKeyDown((int)otk_e.Key))
-                               KeyboardKeyDown.Raise (this, otk_e);
-        }
-               void Keyboard_KeyUp(object sender, OpenTK.Input.KeyboardKeyEventArgs otk_e)
-               {
-                       if (!CrowInterface.ProcessKeyUp((int)otk_e.Key))
-                               KeyboardKeyUp.Raise (this, otk_e);
-               }
-               void OpenTKGameWindow_KeyPress (object sender, OpenTK.KeyPressEventArgs e)
-               {
-                       CrowInterface.ProcessKeyPress (e.KeyChar);
-               }
-        #endregion
-    }
-}
index a95a034a60c92b8d77cc7ef2be9f1cb1af679bb6..4e19b4d8e09f09d7bf30f10ad7e1ea7c51a3344d 100644 (file)
@@ -8,7 +8,7 @@
     <OutputType>Exe</OutputType>
     <RootNamespace>Tests</RootNamespace>
     <AssemblyName>Tests</AssemblyName>
-    <StartupObject>Tests.BasicTests</StartupObject>
+    <StartupObject>Tests.Hello3D</StartupObject>
     <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
     <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
     <ReleaseVersion>0.5</ReleaseVersion>
     <Compile Include="BasicTests.cs" />
     <Compile Include="OpenGL\Shader.cs" />
     <Compile Include="OpenGL\vaoMesh.cs" />
-    <Compile Include="OpenTKGameWindow.cs" />
     <Compile Include="OpenGL\Texture.cs" />
     <Compile Include="HelloWorld.cs" />
     <Compile Include="HelloCube.cs" />
     <Compile Include="UIEditor.cs" />
+    <Compile Include="CrowWindow.cs" />
+    <Compile Include="Hello3D.cs" />
+    <Compile Include="OpenGL\Extensions.cs" />
+    <Compile Include="InterfaceControler.cs" />
   </ItemGroup>
   <ItemGroup>
     <None Include="image\u.svg">
index b08584d45a768c3af9e99c9fd9ad3ae5bd1bb9c2..2c03bdbb318230cf9f3e4ec8cee2d77289fb1848 100644 (file)
@@ -26,7 +26,7 @@ using Crow;
 
 namespace Tests
 {
-       class UIEditor : OpenTKGameWindow
+       class UIEditor : CrowWindow
        {
                [STAThread]
                static void Main ()
@@ -44,7 +44,7 @@ namespace Tests
                {
                        base.OnLoad (e);
 
-                       CrowInterface.AddWidget(
+                       AddWidget(
                                new Window ()
                                {
                                        Title = "Hello World"
index 253328327c0c830be7c7666a330583dc9c3daf77..e0f1ebfd37cdc68dc8b22e85b0d32962c8b47fda 100644 (file)
@@ -634,7 +634,7 @@ namespace Crow
 
                        List<Style> styling = new List<Style>();
 
-                       //Search for a style mathing :
+                       //Search for a style matching :
                        //1: Full class name, with full namespace
                        //2: class name
                        //3: style may have been registered with their ressource ID minus .style extention
@@ -1062,7 +1062,7 @@ namespace Crow
                        using (ImageSurface draw =
                 new ImageSurface(bmp, Format.Argb32, Slot.Width, Slot.Height, stride)) {
                                using (Context gr = new Context (draw)) {
-                                       gr.Antialias = Antialias.Subpixel;
+                                       gr.Antialias = Interface.Antialias;
                                        onDraw (gr);
                                }
                                draw.Flush ();
index 2f35c223de2259e51132d855804a7dad13b278cc..e55a4b18ebc7499f0d025afd8936f813aeb0a5a3 100644 (file)
@@ -468,9 +468,7 @@ namespace Crow
                        gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight);
                        gr.SetFontSize (Font.Size);
                        gr.FontOptions = Interface.FontRenderingOptions;
-
-                       gr.Antialias = Antialias.Subpixel;
-
+                       gr.Antialias = Interface.Antialias;
 
                        rText = new Rectangle(new Size(
                                measureRawSize(LayoutingType.Width), measureRawSize(LayoutingType.Height)));
index 6b6f7999240c5566a8c3f5cf7a57c9c145cacd6a..3702c8806d45e4a517b2904327c6a632980902a5 100644 (file)
@@ -167,8 +167,7 @@ namespace Crow
                        gr.SelectFontFace (Font.Name, Font.Slant, Font.Wheight);
                        gr.SetFontSize (Font.Size);
                        gr.FontOptions = Interface.FontRenderingOptions;
-
-                       gr.Antialias = Antialias.Subpixel;
+                       gr.Antialias = Interface.Antialias;
 
                        rText = new Rectangle (new Size (
                                measureRawSize (LayoutingType.Width), measureRawSize (LayoutingType.Height)));
index 6196c3136c2bfbc791d6a0e62da127aa65def2f5..89ee1b7eb60a005f50ed2908a04f7a5d16d59d69 100644 (file)
@@ -40,6 +40,8 @@ namespace Crow
        ///     - rendering and layouting queues and logic.
        ///     - helpers to load XML interfaces files
        ///     - global constants and variables of CROW
+       ///     - Keyboard and Mouse logic
+       ///     - the resulting bitmap of the interface
        /// </summary>
        public class Interface : ILayoutable
        {
@@ -62,51 +64,94 @@ namespace Crow
                #endregion
 
                #region Static and constants
-               public static int DoubleClick = 200;//ms
-               internal Stopwatch clickTimer = new Stopwatch();
-               internal GraphicObject eligibleForDoubleClick = null;
-               public static int TabSize = 4;
-               public static string LineBreak = "\r\n";
-               //TODO: shold be declared in graphicObject
+               /// <summary>If true, mouse focus is given when mouse is over control</summary>
                public static bool FocusOnHover = false;
+               /// <summary> Threshold to catch borders for sizing </summary>
+               public static int BorderThreshold = 5;
+               /// <summary>Double click threshold in milisecond</summary>
+               public static int DoubleClick = 200;//max duration between two mouse_down evt for a dbl clk in milisec.
                /// <summary> Time to wait in millisecond before starting repeat loop</summary>
                public static int DeviceRepeatDelay = 700;
                /// <summary> Time interval in millisecond between device event repeat</summary>
                public static int DeviceRepeatInterval = 40;
+               /// <summary>Tabulation size in Text controls</summary>
+               public static int TabSize = 4;
                public static bool ReplaceTabsWithSpace = false;
+               public static string LineBreak = "\r\n";
                /// <summary> Allow rendering of interface in development environment </summary>
                public static bool DesignerMode = false;
-               /// <summary> Threshold to catch borders for sizing </summary>
-               public static int BorderThreshold = 5;
                /// <summary> Disable caching for a widget if this threshold is reached </summary>
                public const int MaxCacheSize = 2048;
+               /// <summary> Above this count, the layouting is discard from the current
+               /// update cycle and requeued for the next</summary>
+               public const int MaxLayoutingTries = 3;
                /// <summary> Above this count, the layouting is discard for the widget and it
                /// will not be rendered on screen </summary>
-               public const int MaxLayoutingTries = 3;
                public const int MaxDiscardCount = 5;
                /// <summary> Global font rendering settings for Cairo </summary>
                public static FontOptions FontRenderingOptions;
-               #endregion
+               /// <summary> Global font rendering settings for Cairo </summary>
+               public static Antialias Antialias = Antialias.Subpixel;
 
+               /// <summary>
+               /// Each control need a ref to the root interface containing it, if not set in GraphicObject.currentInterface,
+               /// the ref of this one will be stored in GraphicObject.currentInterface
+               /// </summary>
                internal static Interface CurrentInterface;
+               internal Stopwatch clickTimer = new Stopwatch();
+               internal GraphicObject eligibleForDoubleClick = null;
+               #endregion
 
+               #region Events
+               public event EventHandler<MouseCursorChangedEventArgs> MouseCursorChanged;
+               public event EventHandler Quit;
+               #endregion
+
+               #region Public Fields
+               /// <summary>Graphic Tree of this interface</summary>
+               public List<GraphicObject> GraphicTree = new List<GraphicObject>();
+               /// <summary>Interface's resulting bitmap</summary>
+               public byte[] bmp;
+               /// <summary>resulting bitmap limited to last redrawn part</summary>
+               public byte[] dirtyBmp;
+               /// <summary>True when host has to repaint Interface</summary>
+               public bool IsDirty = false;
+               /// <summary>Coordinate of the dirty bmp on the original bmp</summary>
+               public Rectangle DirtyRect;
+               /// <summary>Locked for each layouting operation</summary>
+               public object LayoutMutex = new object();
+               /// <summary>Sync mutex between host and Crow for rendering operations (bmp, dirtyBmp,...)</summary>
+               public object RenderMutex = new object();
+               /// <summary>Global lock of the update cycle</summary>
+               public object UpdateMutex = new object();
+               //TODO:share resource instances
+               /// <summary>
+               /// Store loaded resources instances shared among controls to reduce memory footprint
+               /// </summary>
                public Dictionary<string,object> Ressources = new Dictionary<string, object>();
+               /// <summary>The Main layouting queue.</summary>
                public Queue<LayoutingQueueItem> LayoutingQueue = new Queue<LayoutingQueueItem> ();
+               /// <summary>Store discarded lqi between two updates</summary>
                public Queue<LayoutingQueueItem> DiscardQueue;
-               public Queue<LayoutingQueueItem> ProcessedLayoutingQueue;
+               /// <summary>Main drawing queue, holding layouted controls</summary>
                public Queue<GraphicObject> DrawingQueue = new Queue<GraphicObject>();
                public string Clipboard;//TODO:use object instead for complex copy paste
-               public void EnqueueForRepaint(GraphicObject g)
-               {
-                       lock (DrawingQueue) {
-                               if (g.IsQueueForRedraw)
-                                       return;
-                               DrawingQueue.Enqueue (g);
-                               g.IsQueueForRedraw = true;
-                       }
-               }
-               //fast compiled IML instantiators
+               /// <summary>each IML and fragments (such as inline Templates) are compiled as a Dynamic Method stored here
+               /// on the first instance creation of a IML item.
+               /// </summary>
                public static Dictionary<String, Instantiator> Instantiators = new Dictionary<string, Instantiator>();
+               #endregion
+
+               #region Private Fields
+               /// <summary>Client rectangle in the host context</summary>
+               Rectangle clientRectangle;
+               /// <summary>Clipping rectangles on the root context</summary>
+               Rectangles clipping = new Rectangles();
+               /// <summary>Main Cairo context</summary>
+               Context ctx;
+               /// <summary>Main Cairo surface</summary>
+               Surface surf;
+               #endregion
 
                #region Default values and Style loading
                /// Default values of properties from GraphicObjects are retrieve from XML Attributes.
@@ -114,9 +159,11 @@ namespace Crow
                /// and injected as a dynamic method referenced in the DefaultValuesLoader Dictionnary.
                /// The compilation is done on the first object instancing, and is also done for custom widgets
                public delegate void LoaderInvoker(object instance);
+               /// <summary>Store one loader per StyleKey</summary>
                public static Dictionary<String, LoaderInvoker> DefaultValuesLoader = new Dictionary<string, LoaderInvoker>();
+               /// <summary>Store dictionnary of member/value per StyleKey</summary>
                public static Dictionary<string, Style> Styling;
-               /// <summary> parse all styling data's and build global Styling Dictionary </summary>
+               /// <summary> parse all styling data's during application startup and build global Styling Dictionary </summary>
                static void loadStyling() {
                        Styling = new Dictionary<string, Style> ();
 
@@ -149,7 +196,12 @@ namespace Crow
                #endregion
 
                #region Templates
-               public static Dictionary<String, string> DefaultTemplates = new Dictionary<string, string>();
+               /// <summary>Store one default templates resource ID per class.
+               /// Resource ID must be 'fullClassName.template' (not case sensitive)
+               /// Those found in application assembly have priority to the default Crow's one
+               /// </summary>
+               public static Dictionary<string, string> DefaultTemplates = new Dictionary<string, string>();
+               /// <summary>Finds available default templates at startup</summary>
                static void findAvailableTemplates(){
                        searchTemplatesIn (Assembly.GetEntryAssembly ());
                        searchTemplatesIn (Assembly.GetExecutingAssembly ());
@@ -167,6 +219,10 @@ namespace Crow
                #endregion
 
                #region Load/Save
+               /// <summary>Open file or find a resource from path string</summary>
+               /// <returns>A file or resource stream</returns>
+               /// <param name="path">This could be a normal file path, or an embedded ressource ID
+               /// Resource ID's must be prefixed with '#' character</param>
                public static Stream GetStreamFromPath (string path)
                {
                        Stream stream = null;
@@ -189,18 +245,19 @@ namespace Crow
                        return stream;
                }
 
-
-               public static void Save<T> (string file, T graphicObject)
+               /// <summary>Create an instance of a GraphicObject and add it to the GraphicTree
+               /// of this Interface</summary>
+               public GraphicObject LoadInterface (string path)
                {
-                       XmlSerializerNamespaces xn = new XmlSerializerNamespaces ();
-                       xn.Add ("", "");
-                       XmlSerializer xs = new XmlSerializer (typeof(T));
+                       lock (UpdateMutex) {
+                               GraphicObject tmp = Load (path);
+                               AddWidget (tmp);
 
-                       xs = new XmlSerializer (typeof(T));
-                       using (Stream s = new FileStream (file, FileMode.Create)) {
-                               xs.Serialize (s, graphicObject, xn);
+                               return tmp;
                        }
                }
+               /// <summary>Create an instance of a GraphicObject linked to this interface but
+               /// not added to the GraphicTree</summary>
                public GraphicObject Load (string path)
                {
                        try {
@@ -209,56 +266,40 @@ namespace Crow
                                throw new Exception ("Error loading <" + path + ">:", ex);
                        }
                }
-               /// <summary>
-               /// fetch it from cache or create it
-               /// </summary>
+               /// <summary>Fetch it from cache or create it</summary>
                public static Instantiator GetInstantiator(string path){
                        if (!Instantiators.ContainsKey(path))
                                Instantiators [path] = new Instantiator(path);
                        return Instantiators [path];
                }
+               /// <summary>Item templates have additional properties for recursivity and
+               /// custom display per item type</summary>
                public static ItemTemplate GetItemTemplate(string path){
                        if (!Instantiators.ContainsKey(path))
                                Instantiators [path] = new ItemTemplate(path);
                        return Instantiators [path] as ItemTemplate;
                }
-               public GraphicObject LoadInterface (string path)
+               //TODO: .Net xml serialisation is no longer used, it has been replaced with instantiators
+               public static void Save<T> (string file, T graphicObject)
                {
-                       lock (UpdateMutex) {
-                               GraphicObject tmp = Load (path);
-                               AddWidget (tmp);
+                       XmlSerializerNamespaces xn = new XmlSerializerNamespaces ();
+                       xn.Add ("", "");
+                       XmlSerializer xs = new XmlSerializer (typeof(T));
 
-                               return tmp;
+                       xs = new XmlSerializer (typeof(T));
+                       using (Stream s = new FileStream (file, FileMode.Create)) {
+                               xs.Serialize (s, graphicObject, xn);
                        }
                }
                #endregion
 
-               #if MEASURE_TIME
-               public PerformanceMeasure clippingMeasure = new PerformanceMeasure("Clipping", 100);
-               public PerformanceMeasure layoutingMeasure = new PerformanceMeasure("Layouting", 100);
-               public PerformanceMeasure updateMeasure = new PerformanceMeasure("Update", 100);
-               public PerformanceMeasure drawingMeasure = new PerformanceMeasure("Drawing", 100);
-               #endif
-
-               public List<GraphicObject> GraphicTree = new List<GraphicObject>();
-
-               Rectangles _redrawClip = new Rectangles();
-
-               Context ctx;
-               Surface surf;
-               public byte[] bmp;
-               public byte[] dirtyBmp;
-               public bool IsDirty = false;
-               public Rectangle DirtyRect;
-               public object LayoutMutex = new object();
-               public object RenderMutex = new object();
-               public object UpdateMutex = new object();
-
                #region focus
                GraphicObject _activeWidget;    //button is pressed on widget
                GraphicObject _hoverWidget;             //mouse is over
                GraphicObject _focusedWidget;   //has keyboard (or other perif) focus
 
+               /// <summary>Widget is focused and button is down or another perif action is occuring
+               /// , it can not lose focus while Active</summary>
                public GraphicObject activeWidget
                {
                        get { return _activeWidget; }
@@ -284,6 +325,7 @@ namespace Crow
                                        #endif
                        }
                }
+               /// <summary>Pointer is over the widget</summary>
                public GraphicObject HoverWidget
                {
                        get { return _hoverWidget; }
@@ -299,6 +341,7 @@ namespace Crow
                                #endif
                        }
                }
+               /// <summary>Widget has the keyboard or mouse focus</summary>
                public GraphicObject FocusedWidget {
                        get { return _focusedWidget; }
                        set {
@@ -313,18 +356,27 @@ namespace Crow
                }
                #endregion
 
-               #if DEBUG_LAYOUTING
-               public List<LQIList> LQIsTries = new List<LQIList>();
-               public LQIList curLQIsTries = new LQIList();
-               public List<LQIList> LQIs = new List<LQIList>();
-               public LQIList curLQIs = new LQIList();
-//             public static LayoutingQueueItem[] MultipleRunsLQIs {
-//                     get { return curUpdateLQIs.Where(l=>l.LayoutingTries>2 || l.DiscardCount > 0).ToArray(); }
-//             }
-               public LayoutingQueueItem currentLQI;
-               #else
-               public List<LQIList> LQIs = null;//still create the var for CrowIDE
-               #endif
+
+               #region UPDATE Loops
+               /// <summary>Enqueue Graphic object for Repaint, DrawingQueue is locked because
+               /// GraphObj's property Set methods could trigger an update from another thread</summary>
+               public void EnqueueForRepaint(GraphicObject g)
+               {
+                       lock (DrawingQueue) {
+                               if (g.IsQueueForRedraw)
+                                       return;
+                               DrawingQueue.Enqueue (g);
+                               g.IsQueueForRedraw = true;
+                       }
+               }
+               /// <summary>Main Update loop, executed in this interface thread, lock the UpdateMutex
+               /// Steps:
+               ///     - execute device Repeat events
+               ///     - Layouting
+               ///     - Clipping
+               ///     - Drawing
+               /// Result: the Interface bitmap is drawn in memory (byte[] bmp) and a dirtyRect and bitmap are available
+               /// </summary>
                public void Update(){
                        if (mouseRepeatCount > 0) {
                                int mc = mouseRepeatCount;
@@ -369,6 +421,9 @@ namespace Crow
 
                        Monitor.Exit (UpdateMutex);
                }
+               /// <summary>Layouting loop, this is the first step of the udpate and process registered
+               /// Layouting queue items. Failing LQI's are requeued in this cycle until MaxTry is reached which
+               /// trigger an enqueue for the next Update Cycle</summary>
                void processLayouting(){
                        #if MEASURE_TIME
                        layoutingMeasure.StartCycle();
@@ -393,6 +448,9 @@ namespace Crow
                        layoutingMeasure.StopCycle();
                        #endif
                }
+               /// <summary>Degueue Widget to clip from DrawingQueue and register the last painted slot and the new one
+               /// Clipping rectangles are added at each level of the tree from leef to root, that's the way for the painting
+               /// operation to known if it should go down in the tree for further graphic updates and repaints</summary>
                void clippingRegistration(){
                        #if MEASURE_TIME
                        clippingMeasure.StartCycle();
@@ -410,6 +468,8 @@ namespace Crow
                        clippingMeasure.StopCycle();
                        #endif
                }
+               /// <summary>Clipping Rectangles drive the drawing process. For compositing, each object under a clip rectangle should be
+               /// repainted. If it contains also clip rectangles, its cache will be update, or if not cached a full redraw will take place</summary>
                void processDrawing(){
                        #if MEASURE_TIME
                        drawingMeasure.StartCycle();
@@ -469,11 +529,10 @@ namespace Crow
                        drawingMeasure.StopCycle();
                        #endif
                }
+               #endregion
 
-               public Rectangles clipping {
-                       get { return _redrawClip; }
-                       set { _redrawClip = value; }
-               }
+               #region GraphicTree handling
+               /// <summary>Add widget to the Graphic tree of this interface and register it for layouting</summary>
                public void AddWidget(GraphicObject g)
                {
                        g.Parent = this;
@@ -481,11 +540,13 @@ namespace Crow
                        g.RegisteredLayoutings = LayoutingType.None;
                        g.RegisterForLayouting (LayoutingType.Sizing | LayoutingType.ArrangeChildren);
                }
+               /// <summary>Set visible state of widget to false and remove if from the graphic tree</summary>
                public void DeleteWidget(GraphicObject g)
                {
                        g.Visible = false;//trick to ensure clip is added to refresh zone
                        GraphicTree.Remove (g);
                }
+               /// <summary> Put widget on top of other root widgets</summary>
                public void PutOnTop(GraphicObject g)
                {
                        if (GraphicTree.IndexOf(g) > 0)
@@ -514,6 +575,7 @@ namespace Crow
                        curLQIs = new LQIList();
                        #endif
                }
+               /// <summary>Search a Graphic object in the tree named 'nameToFind'</summary>
                public GraphicObject FindByName (string nameToFind)
                {
                        foreach (GraphicObject w in GraphicTree) {
@@ -523,8 +585,7 @@ namespace Crow
                        }
                        return null;
                }
-
-
+               #endregion
 
                public void ProcessResize(Rectangle bounds){
                        lock (UpdateMutex) {
@@ -541,15 +602,11 @@ namespace Crow
                        }
                }
 
+               #region Mouse and Keyboard Handling
                XCursor cursor = XCursor.Default;
+
                public MouseState Mouse;
                public KeyboardState Keyboard;
-               Rectangle clientRectangle;
-
-               public event EventHandler<MouseCursorChangedEventArgs> MouseCursorChanged;
-               public event EventHandler Quit;
-
-               #region Mouse Handling
 
                public XCursor MouseCursor {
                        set {
@@ -559,6 +616,8 @@ namespace Crow
                                MouseCursorChanged.Raise (this,new MouseCursorChangedEventArgs(cursor));
                        }
                }
+               /// <summary>Processes mouse move events from the root container</summary>
+               /// <returns><c>true</c>if mouse is in the interface</returns>
                public bool ProcessMouseMove(int x, int y)
                {
                        int deltaX = x - Mouse.X;
@@ -683,9 +742,6 @@ namespace Crow
                        HoverWidget.onMouseWheel (this, e);
                        return true;
                }
-               #endregion
-
-               #region Keyboard
                public bool ProcessKeyDown(int Key){
                        Keyboard.SetKeyState((Crow.Key)Key,true);
                        if (_focusedWidget == null)
@@ -786,6 +842,25 @@ namespace Crow
                }
                public Rectangle getSlot () { return ClientRectangle; }
                #endregion
+
+               #if MEASURE_TIME
+               public PerformanceMeasure clippingMeasure = new PerformanceMeasure("Clipping", 100);
+               public PerformanceMeasure layoutingMeasure = new PerformanceMeasure("Layouting", 100);
+               public PerformanceMeasure updateMeasure = new PerformanceMeasure("Update", 100);
+               public PerformanceMeasure drawingMeasure = new PerformanceMeasure("Drawing", 100);
+               #endif
+               #if DEBUG_LAYOUTING
+               public List<LQIList> LQIsTries = new List<LQIList>();
+               public LQIList curLQIsTries = new LQIList();
+               public List<LQIList> LQIs = new List<LQIList>();
+               public LQIList curLQIs = new LQIList();
+               //              public static LayoutingQueueItem[] MultipleRunsLQIs {
+               //                      get { return curUpdateLQIs.Where(l=>l.LayoutingTries>2 || l.DiscardCount > 0).ToArray(); }
+               //              }
+               public LayoutingQueueItem currentLQI;
+               #else
+               public List<LQIList> LQIs = null;//still create the var for CrowIDE
+               #endif
        }
 }