]> O.S.I.I.S - jp/crow.git/commitdiff
CrowInterface object holding common functions, IGOLibHost removed
authorjpbruyere <jp.bruyere@hotmail.com>
Tue, 23 Feb 2016 17:15:30 +0000 (18:15 +0100)
committerjpbruyere <jp.bruyere@hotmail.com>
Tue, 1 Mar 2016 04:14:01 +0000 (05:14 +0100)
14 files changed:
Crow.csproj
GtkCrow/CrowContainer.cs
OTKCrow/OpenTKGameWindow.cs
Tests/GOLIBTests.cs
src/CompilerServices/CompilerServices.cs
src/GraphicObjects/GraphicObject.cs
src/GraphicObjects/Group.cs
src/GraphicObjects/ILayoutable.cs
src/GraphicObjects/Popper.cs
src/GraphicObjects/Splitter.cs
src/GraphicObjects/TabView.cs
src/GraphicObjects/Window.cs
src/Interface.cs
src/MouseCursorChangedEventArgs.cs [new file with mode: 0644]

index a87b1548bd191106ad5776f560fd2cc01ee460e9..735426e5af9db73746ed8856a283371724da82dd 100644 (file)
     <Compile Include="src\rsvg\Pixbuf.cs" />
     <Compile Include="src\rsvg\RsvgSharp.SizeFuncNative.cs" />
     <Compile Include="src\rsvg\SizeFunc.cs" />
+    <Compile Include="src\MouseCursorChangedEventArgs.cs" />
   </ItemGroup>
   <ItemGroup>
     <Reference Include="System" />
index 0bf17b2fc3207ab26c50fc71ed09d40d5ddb9939..7ea77d033fd1fce101e32e0182863dcb152f06d7 100644 (file)
@@ -30,13 +30,18 @@ using Cairo;
 
 namespace Crow
 {
-       public class OpenTKGameWindow : Gtk.Window, ILayoutable, IGOLibHost
+       public class OpenTKGameWindow : Gtk.Window
     {
+               public Interface CrowInterface;
+
+
                #region ctor
                public OpenTKGameWindow(int _width, int _height, string _title="Crow")
                        : base(Gtk.WindowType.Toplevel)
                {
-                       currentWindow = this;
+                       CrowInterface = new Interface ();
+                       CrowInterface.Quit += Quit;
+
 
                        Decorated = false;
                        this.AddEvents ((int)Gdk.EventMask.PointerMotionMask);
@@ -44,40 +49,41 @@ namespace Crow
                        this.Drawn += Win_Drawn;
                        this.OverrideBackgroundColor (Gtk.StateFlags.Normal, Gdk.RGBA.Zero);
                        this.Visual = Gdk.Global.DefaultRootWindow.Screen.RgbaVisual;
-                       //                      this.AcceptFocus = false;
-                       //                      this.CanFocus = false;
 
                        this.ButtonPressEvent += OpenTKGameWindow_ButtonPressEvent;
                        this.ButtonReleaseEvent += OpenTKGameWindow_ButtonReleaseEvent;
                        this.MotionNotifyEvent += OpenTKGameWindow_MotionNotifyEvent;
                        this.KeyPressEvent += OpenTKGameWindow_KeyPressEvent;
-
                        this.SizeAllocated += OpenTKGameWindow_SizeAllocated;
 
                        this.Show ();
                        this.Maximize ();
 
-                       OnLoad (null);
                        GLib.Idle.Add (new GLib.IdleHandler (idleHandler));
                        GLib.Timeout.Add (10, new GLib.TimeoutHandler (updateHandler));
                        interval.Start ();
                }
+               #endregion
+
 
+
+               #region Timers
                Stopwatch interval = new Stopwatch();
                bool updateHandler(){
-                       update();
+                       CrowInterface.Update();
                        return true;
                }
                bool idleHandler(){
-                       if (isDirty && interval.ElapsedMilliseconds > 1) {
+                       if (CrowInterface.IsDirty && interval.ElapsedMilliseconds > 1) {
                                Debug.WriteLine (interval.ElapsedTicks.ToString ());
-                               QueueDrawArea (DirtyRect.X, DirtyRect.Y, DirtyRect.Width, DirtyRect.Height);
+                               QueueDrawArea (CrowInterface.DirtyRect.X, CrowInterface.DirtyRect.Y, CrowInterface.DirtyRect.Width, CrowInterface.DirtyRect.Height);
                                interval.Restart ();
                        }
                        return true;
                }
                #endregion
 
+<<<<<<< 70bcdc77ff42c74fcd8e6e7dffd4eb6b16f24f39
                public List<GraphicObject> GraphicObjects = new List<GraphicObject>();
                public Color Background = Color.Transparent;
 
@@ -216,310 +222,56 @@ namespace Crow
                Surface surf;
                byte[] bmp;
 
+=======
+               protected void Quit (object sender, EventArgs e)
+               {
+                       Gtk.Application.Quit ();
+               }
+>>>>>>> CrowInterface object holding common functions, IGOLibHost removed
                void Win_Drawn (object o, Gtk.DrawnArgs args)
                {
-                       if (isDirty) {
-                               byte[] tmp = new byte[4 * DirtyRect.Width * DirtyRect.Height];
-                               for (int y = 0; y < DirtyRect.Height; y++) {
-                                       Array.Copy(bmp,
-                                               ((DirtyRect.Top + y) * ClientRectangle.Width * 4) + DirtyRect.Left * 4,
-                                               tmp, y * DirtyRect.Width * 4, DirtyRect.Width *4);
+                       if (CrowInterface.IsDirty) {
+                               byte[] tmp = new byte[4 * CrowInterface.DirtyRect.Width * CrowInterface.DirtyRect.Height];
+                               for (int y = 0; y < CrowInterface.DirtyRect.Height; y++) {
+                                       Array.Copy(CrowInterface.bmp,
+                                               ((CrowInterface.DirtyRect.Top + y) * CrowInterface.ClientRectangle.Width * 4) + CrowInterface.DirtyRect.Left * 4,
+                                               tmp, y * CrowInterface.DirtyRect.Width * 4, CrowInterface.DirtyRect.Width *4);
                                }
-                               using (ImageSurface img = new ImageSurface (tmp, Format.Argb32, DirtyRect.Width, DirtyRect.Height, 4 * DirtyRect.Width)) {
-                                       args.Cr.SetSourceSurface (img, DirtyRect.X, DirtyRect.Y);
+                               using (ImageSurface img = new ImageSurface (tmp, Format.Argb32, CrowInterface.DirtyRect.Width, CrowInterface.DirtyRect.Height, 4 * CrowInterface.DirtyRect.Width)) {
+                                       args.Cr.SetSourceSurface (img, CrowInterface.DirtyRect.X, CrowInterface.DirtyRect.Y);
                                        args.Cr.Paint();
                                }
 
-                               isDirty = false;
+                               CrowInterface.IsDirty = false;
                                return;
                        }
-                       if (bmp == null)
+                       if (CrowInterface.bmp == null)
                                return;
-                       using (ImageSurface img = new ImageSurface (bmp, Format.Argb32, ClientRectangle.Width, ClientRectangle.Height, 4 * ClientRectangle.Width)) {
-                               args.Cr.SetSourceSurface (img, ClientRectangle.X, ClientRectangle.Y);
+                       using (ImageSurface img = new ImageSurface (CrowInterface.bmp, Format.Argb32, CrowInterface.ClientRectangle.Width, CrowInterface.ClientRectangle.Height, 4 * CrowInterface.ClientRectangle.Width)) {
+                               args.Cr.SetSourceSurface (img, CrowInterface.ClientRectangle.X, CrowInterface.ClientRectangle.Y);
                                args.Cr.Paint();
                        }
                }
-
                void Win_DeleteEvent (object o, Gtk.DeleteEventArgs args)
                {
                        Gtk.Application.Quit ();
                }
-
-
                void OpenTKGameWindow_SizeAllocated (object o, Gtk.SizeAllocatedArgs args)
                {
-                       int stride = 4 * ClientRectangle.Width;
-                       int bmpSize = Math.Abs (stride) * ClientRectangle.Height;
-                       bmp = new byte[bmpSize];
-
-                       foreach (GraphicObject g in GraphicObjects)
-                               g.RegisterForLayouting (LayoutingType.All);
-
-                       //_redrawClip.AddRectangle (ClientRectangle);
-               }
-               #endregion
-
-               protected virtual void OnLoad (EventArgs e){
-                       Interface.LoadCursors ();
-               }
-
-               #if MEASURE_TIME
-               public Stopwatch updateTime = new Stopwatch ();
-               public Stopwatch layoutTime = new Stopwatch ();
-               public Stopwatch guTime = new Stopwatch ();
-               public Stopwatch drawingTime = new Stopwatch ();
-               #endif
-
-               bool isDirty = false;
-               Rectangle DirtyRect;
-
-               #region update
-               void update ()
-               {
-                       if (mouseRepeatCount > 0) {
-                               int mc = mouseRepeatCount;
-                               mouseRepeatCount -= mc;
-                               for (int i = 0; i < mc; i++) {
-                                       //FocusedWidget.onMouseClick (this, new MouseButtonEventArgs (Mouse.X, Mouse.Y, MouseButton.Left, true));
-                               }
-                       }
-                       #if MEASURE_TIME
-                       layoutTime.Reset ();
-                       guTime.Reset ();
-                       drawingTime.Reset ();
-                       updateTime.Restart ();
-                       #endif
-
-                       #if MEASURE_TIME
-                       layoutTime.Start ();
-                       #endif
-                       //Debug.WriteLine ("======= Layouting queue start =======");
-
-                       while (Interface.LayoutingQueue.Count > 0) {
-                               LayoutingQueueItem lqi = Interface.LayoutingQueue.Dequeue ();
-                               lqi.ProcessLayouting ();
-                       }
-
-                       #if MEASURE_TIME
-                       layoutTime.Stop ();
-                       #endif
-
-                       //Debug.WriteLine ("otd:" + gobjsToRedraw.Count.ToString () + "-");
-                       //final redraw clips should be added only when layout is completed among parents,
-                       //that's why it take place in a second pass
-                       GraphicObject[] gotr = new GraphicObject[gobjsToRedraw.Count];
-                       gobjsToRedraw.CopyTo (gotr);
-                       gobjsToRedraw.Clear ();
-                       foreach (GraphicObject p in gotr) {
-                               p.IsQueuedForRedraw = false;
-                               p.Parent.RegisterClip (p.LastPaintedSlot);
-                               p.Parent.RegisterClip (p.getSlot());
-                       }
-
-                       #if MEASURE_TIME
-                       updateTime.Stop ();
-                       drawingTime.Start ();
-                       #endif
-
-                       using (surf = new ImageSurface (bmp, Format.Argb32, ClientRectangle.Width, ClientRectangle.Height, ClientRectangle.Width * 4)) {
-                               using (ctx = new Context (surf)){
-
-
-                                       if (clipping.count > 0) {
-                                               //Link.draw (ctx);
-                                               clipping.clearAndClip(ctx);
-
-                                               GraphicObject[] invGOList = new GraphicObject[GraphicObjects.Count];
-                                               GraphicObjects.CopyTo (invGOList, 0);
-                                               invGOList = invGOList.Reverse ().ToArray ();
-
-                                               foreach (GraphicObject p in invGOList) {
-                                                       if (!p.Visible)
-                                                               continue;
-                                                       if (!clipping.intersect (p.Slot))
-                                                               continue;
-                                                       ctx.Save ();
-
-                                                       p.Paint (ref ctx);
-
-                                                       ctx.Restore ();
-                                               }
-
-                                               #if DEBUG_CLIP_RECTANGLE
-                                               clipping.stroke (ctx, Color.Red.AdjustAlpha(0.5));
-                                               #endif
-
-                                               if (isDirty)
-                                                       DirtyRect += clipping.Bounds;
-                                               else
-                                                       DirtyRect = clipping.Bounds;
-                                               isDirty = true;
-
-                                               DirtyRect.Left = Math.Max (0, DirtyRect.Left);
-                                               DirtyRect.Top = Math.Max (0, DirtyRect.Top);
-                                               DirtyRect.Width = Math.Min (ClientRectangle.Width - DirtyRect.Left, DirtyRect.Width);
-                                               DirtyRect.Height = Math.Min (ClientRectangle.Height - DirtyRect.Top, DirtyRect.Height);
-
-                                               clipping.Reset ();
-                                       }
-
-                                       #if MEASURE_TIME
-                                       drawingTime.Stop ();
-                                       #endif
-                                       //surf.WriteToPng (@"/mnt/data/test.png");
-                               }
-                       }
-//                     if (ToolTip.isVisible) {
-//                             ToolTip.panel.processkLayouting();
-//                             if (ToolTip.panel.layoutIsValid)
-//                                     ToolTip.panel.Paint(ref ctx);
-//                     }
-//                     Debug.WriteLine("INTERFACE: layouting: {0} ticks \t graphical update {1} ticks \t drawing {2} ticks",
-//                         layoutTime.ElapsedTicks,
-//                         guTime.ElapsedTicks,
-//                         drawingTime.ElapsedTicks);
-//                     Debug.WriteLine("INTERFACE: layouting: {0} ms \t graphical update {1} ms \t drawing {2} ms",
-//                         layoutTime.ElapsedMilliseconds,
-//                         guTime.ElapsedMilliseconds,
-//                         drawingTime.ElapsedMilliseconds);
-
-//                     Debug.WriteLine("UPDATE: {0} ticks \t, {1} ms",
-//                             updateTime.ElapsedTicks,
-//                             updateTime.ElapsedMilliseconds);
-               }
-               #endregion
-
-               #region loading
-               public GraphicObject LoadInterface (string path)
-               {
-                       GraphicObject tmp = Interface.Load (path, this);
-                       AddWidget (tmp);
-                       return tmp;
-               }
-               #endregion
-
-
-               MouseState mouse;
-               KeyboardState Keyboard;
-
+                       CrowInterface.ProcessResize (new Rectangle (args.Allocation.X, args.Allocation.Y, args.Allocation.Width, args.Allocation.Height));
+               }        
                void OpenTKGameWindow_MotionNotifyEvent (object o, Gtk.MotionNotifyEventArgs args)
                {
-                       int deltaX = (int)args.Event.X - mouse.X;
-                       int deltaY = (int)args.Event.Y - mouse.Y;
-                       MouseMoveEventArgs e = new MouseMoveEventArgs ((int)args.Event.X, (int)args.Event.Y, deltaX, deltaY);
-                       mouse.X = (int)args.Event.X;
-                       mouse.Y = (int)args.Event.Y;
-                       e.Mouse = mouse;
-
-                       if (_activeWidget != null) {
-                               //first, ensure object is still in the graphic tree
-                               if (_activeWidget.HostContainer == null) {
-                                       activeWidget = null;
-                               } else {
-
-                                       //send move evt even if mouse move outside bounds
-                                       _activeWidget.onMouseMove (this, e);
-                                       return;
-                               }
-                       }
-
-                       if (hoverWidget != null) {
-                               //first, ensure object is still in the graphic tree
-                               if (hoverWidget.HostContainer == null) {
-                                       hoverWidget = null;
-                               } else {
-                                       //check topmost graphicobject first
-                                       GraphicObject tmp = hoverWidget;
-                                       GraphicObject topc = null;
-                                       while (tmp is GraphicObject) {
-                                               topc = tmp;
-                                               tmp = tmp.Parent as GraphicObject;
-                                       }
-                                       int idxhw = GraphicObjects.IndexOf (topc);
-                                       if (idxhw != 0) {
-                                               int i = 0;
-                                               while (i < idxhw) {
-                                                       if (GraphicObjects [i].MouseIsIn (e.Position)) {
-                                                               hoverWidget.onMouseLeave (this, e);
-                                                               GraphicObjects [i].checkHoverWidget (e);
-                                                               return;
-                                                       }
-                                                       i++;
-                                               }
-                                       }
-
-
-                                       if (hoverWidget.MouseIsIn (e.Position)) {
-                                               hoverWidget.checkHoverWidget (e);
-                                               return;
-                                       } else {
-                                               hoverWidget.onMouseLeave (this, e);
-                                               //seek upward from last focused graph obj's
-                                               while (hoverWidget.Parent as GraphicObject != null) {
-                                                       hoverWidget = hoverWidget.Parent as GraphicObject;
-                                                       if (hoverWidget.MouseIsIn (e.Position)) {
-                                                               hoverWidget.checkHoverWidget (e);
-                                                               return;
-                                                       } else
-                                                               hoverWidget.onMouseLeave (this, e);
-                                               }
-                                       }
-                               }
-                       }
-
-                       //top level graphic obj's parsing
-                       for (int i = 0; i < GraphicObjects.Count; i++) {
-                               GraphicObject g = GraphicObjects[i];
-                               if (g.MouseIsIn (e.Position)) {
-                                       g.checkHoverWidget (e);
-                                       PutOnTop (g);
-                                       return;
-                               }
-                       }
-                       hoverWidget = null;
-                       //MouseMove.Raise (this, otk_e);
-       }
+                       CrowInterface.ProcessMouseMove ((int)args.Event.X, (int)args.Event.Y);
+        }
 
                void OpenTKGameWindow_ButtonReleaseEvent (object o, Gtk.ButtonReleaseEventArgs args)
                {
-                       MouseButtonEventArgs e = new MouseButtonEventArgs ((int)args.Event.X, (int)args.Event.Y, (Crow.MouseButton)args.Event.Button-1, false);
-                       mouse.DisableBit ((int)args.Event.Button-1);
-                       e.Mouse = mouse;
-
-                       if (_activeWidget == null) {
-                               //MouseButtonUp.Raise (this, otk_e);
-                               return;
-                       }
-
-                       if (mouseRepeatThread != null) {
-                               mouseRepeatOn = false;
-                               mouseRepeatThread.Abort();
-                               mouseRepeatThread.Join ();
-                       }
-
-                       _activeWidget.onMouseUp (this, e);
-                       activeWidget = null;
+                       CrowInterface.ProcessMouseButtonUp ((int)args.Event.Button - 1);
                }
                void OpenTKGameWindow_ButtonPressEvent (object o, Gtk.ButtonPressEventArgs args)
                {
-                       MouseButtonEventArgs e = new MouseButtonEventArgs ((int)args.Event.X, (int)args.Event.Y, (Crow.MouseButton)args.Event.Button - 1, true);
-                       mouse.EnableBit ((int)args.Event.Button - 1);
-                       e.Mouse = mouse;
-
-                       if (hoverWidget == null) {
-                               //MouseButtonDown.Raise (this, otk_e);
-                               return;
-                       }
-
-                       hoverWidget.onMouseDown(hoverWidget,new BubblingMouseButtonEventArg(e));
-
-                       if (FocusedWidget == null)
-                               return;
-                       if (!FocusedWidget.MouseRepeat)
-                               return;
-                       mouseRepeatThread = new Thread (mouseRepeatThreadFunc);
-                       mouseRepeatThread.Start ();
+                       CrowInterface.ProcessMouseButtonDown ((int)args.Event.Button - 1);
                }
 
 //             void Mouse_WheelChanged(object sender, OpenTK.Input.MouseWheelEventArgs otk_e)
@@ -536,19 +288,6 @@ namespace Crow
 //                     hoverWidget.onMouseWheel (this, e);
 //        }
 
-               volatile bool mouseRepeatOn;
-               volatile int mouseRepeatCount;
-               Thread mouseRepeatThread;
-               void mouseRepeatThreadFunc()
-               {
-                       mouseRepeatOn = true;
-                       Thread.Sleep (Interface.DeviceRepeatDelay);
-                       while (mouseRepeatOn) {
-                               mouseRepeatCount++;
-                               Thread.Sleep (Interface.DeviceRepeatInterval);
-                       }
-                       mouseRepeatCount = 0;
-               }
 
 
        #region keyboard Handling
@@ -565,56 +304,9 @@ namespace Crow
 //        }
                void OpenTKGameWindow_KeyPressEvent (object o, Gtk.KeyPressEventArgs args)
                {
-                       if (_focusedWidget == null) {
-//                             KeyboardKeyDown.Raise (this, otk_e);
-                               return;
-                       }
-                       Keyboard.SetKeyState ((Crow.Key)args.Event.KeyValue, true);
-                       KeyboardKeyEventArgs e = new KeyboardKeyEventArgs((Crow.Key)args.Event.KeyValue, false, Keyboard);
-                       _focusedWidget.onKeyDown (o, e);
-               }
 
-       #endregion
-
-               #region ILayoutable implementation
-               public void RegisterClip(Rectangle r){
-                       clipping.AddRectangle (r);
-               }
-               public bool ArrangeChildren { get { return false; }}
-               public int LayoutingTries {
-                       get { throw new NotImplementedException (); }
-                       set { throw new NotImplementedException (); }
-               }
-               public LayoutingType RegisteredLayoutings {
-                       get { return LayoutingType.None; }
-                       set { throw new NotImplementedException (); }
-               }
-               public void RegisterForLayouting (LayoutingType layoutType) { throw new NotImplementedException (); }
-               public bool UpdateLayout (LayoutingType layoutType) { throw new NotImplementedException (); }
-               public Rectangle ContextCoordinates (Rectangle r) => r;
-               public Rectangle ScreenCoordinates (Rectangle r) => r;
-
-               public ILayoutable Parent {
-                       get { return null; }
-                       set { throw new NotImplementedException (); }
-               }
-               public ILayoutable LogicalParent {
-                       get { return null; }
-                       set { throw new NotImplementedException (); }
                }
 
-               public Rectangle ClientRectangle {
-                       get {
-                               int width, height;
-                               this.GetSize (out width, out height);
-                               return new Size(width, height);
-                       }
-               }
-               public IGOLibHost HostContainer {
-                       get { return this; }
-               }
-               public Rectangle getSlot () => ClientRectangle;
-               public Rectangle getBounds () => ClientRectangle;
-               #endregion
+       #endregion
     }
 }
index 111163b46117b3fb134fed0285c1d6900884b737..ae013bd8df73c4e13a9bf8ff09e974184fe7a9da 100644 (file)
@@ -270,12 +270,6 @@ namespace Crow
                }
                #endregion
 
-               #if MEASURE_TIME
-               public Stopwatch updateTime = new Stopwatch ();
-               public Stopwatch layoutTime = new Stopwatch ();
-               public Stopwatch guTime = new Stopwatch ();
-               public Stopwatch drawingTime = new Stopwatch ();
-               #endif
 
                bool isDirty = false;
                Rectangle DirtyRect;
@@ -290,20 +284,11 @@ namespace Crow
                                        FocusedWidget.onMouseClick (this, new MouseButtonEventArgs (Mouse.X, Mouse.Y, MouseButton.Left, true));
                                }
                        }
-                       #if MEASURE_TIME
-                       layoutTime.Reset ();
-                       guTime.Reset ();
-                       drawingTime.Reset ();
-                       updateTime.Restart ();
-                       #endif
 
                        GraphicObject[] invGOList = new GraphicObject[GraphicObjects.Count];
                        GraphicObjects.CopyTo (invGOList, 0);
                        invGOList = invGOList.Reverse ().ToArray ();
 
-                       #if MEASURE_TIME
-                       layoutTime.Start ();
-                       #endif
                        //Debug.WriteLine ("======= Layouting queue start =======");
 
                        while (Interface.LayoutingQueue.Count > 0) {
@@ -311,9 +296,6 @@ namespace Crow
                                lqi.ProcessLayouting ();
                        }
 
-                       #if MEASURE_TIME
-                       layoutTime.Stop ();
-                       #endif
 
                        //Debug.WriteLine ("otd:" + gobjsToRedraw.Count.ToString () + "-");
                        //final redraw clips should be added only when layout is completed among parents,
@@ -327,11 +309,6 @@ namespace Crow
                                p.Parent.RegisterClip (p.getSlot());
                        }
 
-                       #if MEASURE_TIME
-                       updateTime.Stop ();
-                       drawingTime.Start ();
-                       #endif
-
                        using (surf = new ImageSurface (bmp, Format.Argb32, ClientRectangle.Width, ClientRectangle.Height, ClientRectangle.Width * 4)) {
                                using (ctx = new Context (surf)){
 
@@ -364,36 +341,14 @@ namespace Crow
 
                                                DirtyRect.Left = Math.Max (0, DirtyRect.Left);
                                                DirtyRect.Top = Math.Max (0, DirtyRect.Top);
-                                               DirtyRect.Width = Math.Min (ClientRectangle.Width - DirtyRect.Left, DirtyRect.Width);
-                                               DirtyRect.Height = Math.Min (ClientRectangle.Height - DirtyRect.Top, DirtyRect.Height);
+                                               DirtyRect.Width = Math.Min (ClientRectangle.Right, DirtyRect.Width);
+                                               DirtyRect.Height = Math.Min (ClientRectangle.Bottom, DirtyRect.Height);
 
                                                clipping.Reset ();
                                        }
-
-                                       #if MEASURE_TIME
-                                       drawingTime.Stop ();
-                                       #endif
-                                       //surf.WriteToPng (@"/mnt/data/test.png");
                                }
                        }
-//                     if (ToolTip.isVisible) {
-//                             ToolTip.panel.processkLayouting();
-//                             if (ToolTip.panel.layoutIsValid)
-//                                     ToolTip.panel.Paint(ref ctx);
-//                     }
-//                     Debug.WriteLine("INTERFACE: layouting: {0} ticks \t graphical update {1} ticks \t drawing {2} ticks",
-//                         layoutTime.ElapsedTicks,
-//                         guTime.ElapsedTicks,
-//                         drawingTime.ElapsedTicks);
-//                     Debug.WriteLine("INTERFACE: layouting: {0} ms \t graphical update {1} ms \t drawing {2} ms",
-//                         layoutTime.ElapsedMilliseconds,
-//                         guTime.ElapsedMilliseconds,
-//                         drawingTime.ElapsedMilliseconds);
-
-//                     Debug.WriteLine("UPDATE: {0} ticks \t, {1} ms",
-//                             updateTime.ElapsedTicks,
-//                             updateTime.ElapsedMilliseconds);
-               }
+               }                                               
                #endregion
 
                #region loading
index c3622ef473c48b0483071f5637ff69192ec81ebd..8c504a7ba32f57dbeb00e349825350488568e9fe 100644 (file)
@@ -31,6 +31,10 @@ namespace test
                        : base(800, 600,"test: press spacebar to toogle test files")
                {
                        //VSync = VSyncMode.Off;
+                       Interface.CurrentInterface = CrowInterface;
+                       GraphicObject obj = CrowInterface.LoadInterface("Interfaces/" + testFiles[idx]);
+                       obj.DataSource = this;
+
                }
 
                int frameCpt = 0;
@@ -51,14 +55,9 @@ namespace test
                        "0.crow",
                        "testImage.crow",
                        "testOutOfClipUpdate.crow",
-<<<<<<< 328c6d4eab1127cd9799540f253deda66060b68a
-                       "testTreeView.crow",
-                       "testWindow.goml",
-=======
 //                     "test_Listbox.goml",
 //                     "testTreeView.crow",
                        "1.crow",
->>>>>>> GtkCrowContainer test, functionnal, keyboard issue
                        "clip4.crow",
                        "clip3.crow",
                        "clip2.crow",
@@ -113,11 +112,11 @@ namespace test
                                ValueChanged.Raise(this, new ValueChangeEventArgs ("fps", _fps));
                                #if MEASURE_TIME
                                ValueChanged.Raise (this, new ValueChangeEventArgs ("update",
-                                       this.updateTime.ElapsedTicks.ToString () + " ticks"));
+                                       this.CrowInterface.updateTime.ElapsedTicks.ToString () + " ticks"));
                                ValueChanged.Raise (this, new ValueChangeEventArgs ("layouting",
-                                       this.layoutTime.ElapsedTicks.ToString () + " ticks"));
+                                       this.CrowInterface.layoutTime.ElapsedTicks.ToString () + " ticks"));
                                ValueChanged.Raise (this, new ValueChangeEventArgs ("drawing",
-                                       this.drawingTime.ElapsedTicks.ToString () + " ticks"));
+                                       this.CrowInterface.drawingTime.ElapsedTicks.ToString () + " ticks"));
                                #endif
                        }
                }
@@ -191,35 +190,26 @@ namespace test
                        TestList = Color.ColorDic.ToList();
                }
 
-               protected override void OnLoad (EventArgs e)
-               {
-                       base.OnLoad (e);
-                       //this.AddWidget(new test4());
-                       //KeyboardKeyDown += GOLIBTests_KeyboardKeyDown1;;
-
-                       GraphicObject obj = LoadInterface("Interfaces/" + testFiles[idx]);
-                       obj.DataSource = this;
-               }
                void GOLIBTests_KeyboardKeyDown1 (object sender, OpenTK.Input.KeyboardKeyEventArgs e)
                {
                        if (e.Key == OpenTK.Input.Key.Escape) {
-                               this.Quit ();
+                               Quit (null, null);
                                return;
                        } else if (e.Key == OpenTK.Input.Key.L) {
                                TestList.Add ("new string");
                                NotifyValueChanged ("TestList", TestList);
                                return;
                        } else if (e.Key == OpenTK.Input.Key.W) {
-                               GraphicObject w = LoadInterface("Interfaces/testWindow.goml");
+                               GraphicObject w = CrowInterface.LoadInterface("Interfaces/testWindow.goml");
                                w.DataSource = this;
                                return;
                        }
-                       ClearInterface ();
+                       CrowInterface.ClearInterface ();
                        idx++;
                        if (idx == testFiles.Length)
                                idx = 0;
                        this.Title = testFiles [idx];
-                       GraphicObject obj = LoadInterface("Interfaces/" + testFiles[idx]);
+                       GraphicObject obj = CrowInterface.LoadInterface("Interfaces/" + testFiles[idx]);
                        obj.DataSource = this;
                }
 
@@ -246,7 +236,7 @@ namespace test
                }
                void onAddTabButClick(object sender, MouseButtonEventArgs e){
                        
-                       TabView tv = this.FindByName("tabview1") as TabView;
+                       TabView tv = CrowInterface.FindByName("tabview1") as TabView;
                        if (tv == null)
                                return;
                        tv.AddChild (new TabItem () { Caption = "NewTab" });
@@ -270,13 +260,13 @@ namespace test
                }
                void Win_KeyPressEvent (object o, Gtk.KeyPressEventArgs args)
                {
-                       ClearInterface ();
+                       CrowInterface.ClearInterface ();
                        idx++;
                        if (idx == testFiles.Length)
                                idx = 0;
                        this.Title = testFiles [idx];
-                       GraphicObject obj = LoadInterface("Interfaces/" + testFiles[idx]);
-                       obj.DataSource = this;
+                       GraphicObject obj = CrowInterface.LoadInterface("Interfaces/" + testFiles[idx]);
+                       obj.DataSource = this;                  
                }
        }
 }
index 76a38c4965c790fee5660b95a5878c3238eb8320..bdfe362e4ed25d2bf356337174a1088746e86cdb 100644 (file)
@@ -115,7 +115,7 @@ namespace Crow
                                ILayoutable tmp = Target.Instance as ILayoutable;
                                if (string.IsNullOrEmpty (bindingExp [0])) {
                                        //if exp start with '/' => Graphic tree parsing start at top container
-                                       tmp = tmp.HostContainer as ILayoutable;
+                                       tmp = Interface.CurrentInterface as ILayoutable;
                                        ptr++;
                                }
                                while (ptr < bindingExp.Length - 1) {
index 9f1bf81136658171514a8d87011ac58c5613688e..56b50684c41ae0bb513168164ecf85bf5e7bc0e6 100644 (file)
@@ -128,9 +128,7 @@ namespace Crow
                                return cb;
                        }
                }
-               [XmlIgnore]public virtual IGOLibHost HostContainer {
-                       get { return Parent == null ? null : Parent.HostContainer; }
-               }
+
                public virtual Rectangle ContextCoordinates(Rectangle r){
                        GraphicObject go = Parent as GraphicObject;
                        if (go == null)
@@ -374,12 +372,12 @@ namespace Crow
 
                                _isVisible = value;
 
-                               if (HostContainer == null)
+                               if (Interface.CurrentInterface == null)
                                        return;
 
                                //ensure main win doesn't keep hidden childrens ref
-                               if (!_isVisible && this.Contains (HostContainer.hoverWidget))
-                                       HostContainer.hoverWidget = null;
+                               if (!_isVisible && this.Contains (Interface.CurrentInterface.hoverWidget))
+                                       Interface.CurrentInterface.hoverWidget = null;
 
                                if (Parent is GraphicObject)
                                        Parent.RegisterForLayouting (LayoutingType.Sizing);
@@ -645,9 +643,9 @@ namespace Crow
                {
                        if (IsQueuedForRedraw)
                                return;
-                       if (HostContainer == null)
+                       if (Interface.CurrentInterface == null)
                                return;
-                       HostContainer.gobjsToRedraw.Add (this);
+                       Interface.CurrentInterface.gobjsToRedraw.Add (this);
                        IsQueuedForRedraw = true;
                }
 
@@ -957,9 +955,8 @@ namespace Crow
                }
                public virtual void checkHoverWidget(MouseMoveEventArgs e)
                {
-                       IGOLibHost glh = HostContainer;
-                       if (glh.hoverWidget != this) {
-                               glh.hoverWidget = this;
+                       if (Interface.CurrentInterface.hoverWidget != this) {
+                               Interface.CurrentInterface.hoverWidget = this;
                                onMouseEnter (this, e);
                        }
 
@@ -975,14 +972,13 @@ namespace Crow
                        MouseMove.Raise (sender, e);
                }
                public virtual void onMouseDown(object sender, MouseButtonEventArgs e){
-                       IGOLibHost hc = HostContainer;
-                       if (hc.activeWidget == null)
-                               hc.activeWidget = this;
+                       if (Interface.CurrentInterface.activeWidget == null)
+                               Interface.CurrentInterface.activeWidget = this;
                        if (this.Focusable && !Interface.FocusOnHover) {
                                BubblingMouseButtonEventArg be = e as BubblingMouseButtonEventArg;
                                if (be.Focused == null) {
                                        be.Focused = this;
-                                       hc.FocusedWidget = this;
+                                       Interface.CurrentInterface.FocusedWidget = this;
                                }
                        }
                        //bubble event to the top
index 887d9e22add9e31aac443b6254da6f6c3d6afa55..869ec11378a65f7170fb88be6391f0e0ea67dad4 100644 (file)
@@ -305,8 +305,8 @@ namespace Crow
                #region Mouse handling
                public override void checkHoverWidget (MouseMoveEventArgs e)
                {
-                       if (HostContainer.hoverWidget != this) {
-                               HostContainer.hoverWidget = this;
+                       if (Interface.CurrentInterface.hoverWidget != this) {
+                               Interface.CurrentInterface.hoverWidget = this;
                                onMouseEnter (this, e);
                        }
                        for (int i = Children.Count - 1; i >= 0; i--) {
index 51abc25dc0ff7147ff8cd2796d942d3d0fd4c707..a8df3ae0a453c320a361f54bc316b9970c0c3a75 100644 (file)
@@ -17,8 +17,6 @@ namespace Crow
                Rectangle getSlot();
                Rectangle getBounds();
 
-               IGOLibHost HostContainer { get; }
-
                bool ArrangeChildren { get; }
                LayoutingType RegisteredLayoutings { get; set; }
                void RegisterForLayouting(LayoutingType layoutType);
index 4c5ca11c43604325e2fb85b26588c8fa2114e22f..fdbed62cb4539fe76dbdc531d4bfc5ba7ce7c06f 100644 (file)
@@ -174,22 +174,20 @@ namespace Crow
                        
                public virtual void onPop(object sender, EventArgs e)
                {
-                       IGOLibHost tc = HostContainer;
-                       if (tc == null)
+                       if (Interface.CurrentInterface == null)
                                return;
                        if (Content != null) {
                                Content.Visible = true;
                                if (Content.Parent == null)
-                                       tc.AddWidget (Content);
-                               tc.PutOnTop (Content);
+                                       Interface.CurrentInterface.AddWidget (Content);
+                               Interface.CurrentInterface.PutOnTop (Content);
                                _content_LayoutChanged (this, new LayoutingEventArgs (LayoutingType.Sizing));
                        }
                        Pop.Raise (this, e);
                }
                public virtual void onUnpop(object sender, EventArgs e)
                {
-                       IGOLibHost tc = HostContainer;
-                       if (tc == null)
+                       if (Interface.CurrentInterface == null)
                                return;
                        Content.Visible = false;
                        Unpop.Raise (this, e);
index dbda87af71461d459b0edd7d2b40dede63543824..9372f1bc6e3079334ca6072edebb2ebeae9869d1 100644 (file)
@@ -62,14 +62,14 @@ namespace Crow
                {
                        base.onMouseEnter (sender, e);
                        if ((Parent as GenericStack).Orientation == Orientation.Horizontal)
-                               this.HostContainer.MouseCursor = XCursor.H;
+                               Interface.CurrentInterface.MouseCursor = XCursor.H;
                        else
-                               this.HostContainer.MouseCursor = XCursor.V;
+                               Interface.CurrentInterface.MouseCursor = XCursor.V;
                }
                public override void onMouseLeave (object sender, MouseMoveEventArgs e)
                {
                        base.onMouseLeave (sender, e);
-                       this.HostContainer.MouseCursor = XCursor.Default;
+                       Interface.CurrentInterface.MouseCursor = XCursor.Default;
                }
                public override void onMouseMove (object sender, MouseMoveEventArgs e)
                {
index 7bf827d666b6770c6e67f021ddef1798a359a76c..97ac4c6457d9e71ad65efe427ce6d0cb73003f8e 100644 (file)
@@ -183,8 +183,8 @@ namespace Crow
                #region Mouse handling
                public override void checkHoverWidget (MouseMoveEventArgs e)
                {
-                       if (HostContainer.hoverWidget != this) {
-                               HostContainer.hoverWidget = this;
+                       if (Interface.CurrentInterface.hoverWidget != this) {
+                               Interface.CurrentInterface.hoverWidget = this;
                                onMouseEnter (this, e);
                        }
 
index 617670fc0e497842883743fce904e858503cccac..429d42696240bffce80c1b374d732d35a9e2e4c3 100644 (file)
@@ -83,7 +83,7 @@ namespace Crow
                {
                        base.onMouseMove (sender, e);
 
-                       IGOLibHost otkgw = HostContainer;
+                       Interface otkgw = Interface.CurrentInterface;
 
                        if (e.Mouse.IsButtonDown (MouseButton.Left)) {
                                if (!HasFocus)
@@ -210,7 +210,7 @@ namespace Crow
                {
                        base.onMouseLeave (sender, e);
                        currentDirection = Direction.None;
-                       HostContainer.MouseCursor = XCursor.Default;
+                       Interface.CurrentInterface.MouseCursor = XCursor.Default;
                }
 
                protected override void loadTemplate(GraphicObject template = null)
@@ -224,7 +224,7 @@ namespace Crow
                        ILayoutable parent = (sender as GraphicObject).Parent;
                        while(!(parent is Window))
                                parent = parent.Parent;
-                       HostContainer.DeleteWidget (parent as GraphicObject);
+                       Interface.CurrentInterface.DeleteWidget (parent as GraphicObject);
                }
 
                public override void ResolveBindings ()
index 3dd20a25da06fb3abfc0dda1ad78e3f4ed92e3f9..352f2a1a2d594961fc1a4bdc6fe9cafe65f14c11 100644 (file)
@@ -30,11 +30,20 @@ using System.Reflection.Emit;
 using System.CodeDom;
 using Microsoft.CSharp;
 using System.CodeDom.Compiler;
+using System.Threading;
+using Cairo;
 
 namespace Crow
 {
-       public static class Interface
+       public class Interface : ILayoutable
        {
+               #region CTOR
+               static Interface(){
+                       Interface.LoadCursors ();
+               }
+               #endregion
+
+               #region Static and constants
                /// <summary> Used to prevent spurious loading of templates </summary>
                internal static bool XmlSerializerInit = false;
                /// <summary> keep ressource path for debug msg </summary>
@@ -55,10 +64,13 @@ namespace Crow
                public static int BorderThreshold = 5;
                public const int MaxCacheSize = 2048;
                public const int MaxLayoutingTries = 50;
+               #endregion
 
                public static Queue<LayoutingQueueItem> LayoutingQueue = new Queue<LayoutingQueueItem>();
+               #region default values loading helpers
                public delegate void loadDefaultInvoker(object instance);
                public static Dictionary<String, loadDefaultInvoker> DefaultValuesLoader = new Dictionary<string, loadDefaultInvoker>();
+               #endregion
 
                public static void LoadCursors(){
                        //Load cursors
@@ -73,19 +85,6 @@ namespace Crow
                }
 
                #region Load/Save
-
-               public static void Save<T> (string file, T graphicObject)
-               {            
-                       XmlSerializerNamespaces xn = new XmlSerializerNamespaces ();
-                       xn.Add ("", "");
-                       XmlSerializer xs = new XmlSerializer (typeof(T));
-
-                       xs = new XmlSerializer (typeof(T));
-                       using (Stream s = new FileStream (file, FileMode.Create)) {
-                               xs.Serialize (s, graphicObject, xn);
-                       }
-               }
-
                public static Stream GetStreamFromPath (string path)
                {
                        Stream stream = null;
@@ -132,7 +131,17 @@ namespace Crow
                        return t;
                }
 
+               public static void Save<T> (string file, T graphicObject)
+               {
+                       XmlSerializerNamespaces xn = new XmlSerializerNamespaces ();
+                       xn.Add ("", "");
+                       XmlSerializer xs = new XmlSerializer (typeof(T));
 
+                       xs = new XmlSerializer (typeof(T));
+                       using (Stream s = new FileStream (file, FileMode.Create)) {
+                               xs.Serialize (s, graphicObject, xn);
+                       }
+               }
                public static GraphicObject Load (string path, object hostClass = null)
                {
                        Interface.XmlLoaderCount ++;
@@ -144,9 +153,6 @@ namespace Crow
                        Interface.XmlLoaderCount --;
                        return tmp;
                }
-
-
-
                public static GraphicObject Load (Stream stream, Type type, object hostClass = null)
                {
                        #if DEBUG_LOAD
@@ -181,7 +187,438 @@ namespace Crow
                        return result;
                }
 
+               public GraphicObject LoadInterface (string path)
+               {
+                       GraphicObject tmp = Interface.Load (path, this);
+                       AddWidget (tmp);
+                       return tmp;
+               }
+
+               #endregion
+
+               #if MEASURE_TIME
+               public Stopwatch updateTime = new Stopwatch ();
+               public Stopwatch layoutTime = new Stopwatch ();
+               public Stopwatch guTime = new Stopwatch ();
+               public Stopwatch drawingTime = new Stopwatch ();
+               #endif
+
+               public List<GraphicObject> GraphicObjects = new List<GraphicObject>();
+               public Color Background = Color.Transparent;
+
+               internal static Interface currentWindow;
+               public static Interface CurrentInterface;
+
+               Rectangles _redrawClip = new Rectangles();//should find another way to access it from child
+               List<GraphicObject> _gobjsToRedraw = new List<GraphicObject>();
+
+               Context ctx;
+               Surface surf;
+               public byte[] bmp;
+               public bool IsDirty = false;
+               public Rectangle DirtyRect;
+
+               #region focus
+               GraphicObject _activeWidget;    //button is pressed on widget
+               GraphicObject _hoverWidget;             //mouse is over
+               GraphicObject _focusedWidget;   //has keyboard (or other perif) focus
+
+               public GraphicObject activeWidget
+               {
+                       get { return _activeWidget; }
+                       set
+                       {
+                               if (_activeWidget == value)
+                                       return;
+
+                               if (_activeWidget != null)
+                                       _activeWidget.IsActive = false;
+
+                               _activeWidget = value;
+
+                               if (_activeWidget != null)
+                                       _activeWidget.IsActive = true;
+                       }
+               }
+               public GraphicObject hoverWidget
+               {
+                       get { return _hoverWidget; }
+                       set {
+                               if (_hoverWidget == value)
+                                       return;
+                               _hoverWidget = value;
+                       }
+               }
+               public GraphicObject FocusedWidget {
+                       get { return _focusedWidget; }
+                       set {
+                               if (_focusedWidget == value)
+                                       return;
+                               if (_focusedWidget != null)
+                                       _focusedWidget.onUnfocused (this, null);
+                               _focusedWidget = value;
+                               if (_focusedWidget != null)
+                                       _focusedWidget.onFocused (this, null);
+                       }
+               }
+               #endregion
+
+
+               public void Update(){
+                       if (mouseRepeatCount > 0) {
+                               int mc = mouseRepeatCount;
+                               mouseRepeatCount -= mc;
+                               for (int i = 0; i < mc; i++) {
+                                       FocusedWidget.onMouseClick (this, new MouseButtonEventArgs (Mouse.X, Mouse.Y, MouseButton.Left, true));
+                               }
+                       }
+                       #if MEASURE_TIME
+                       layoutTime.Reset ();
+                       guTime.Reset ();
+                       drawingTime.Reset ();
+                       updateTime.Restart ();
+                       #endif
+
+                       GraphicObject[] invGOList = new GraphicObject[GraphicObjects.Count];
+                       GraphicObjects.CopyTo (invGOList, 0);
+                       invGOList = invGOList.Reverse ().ToArray ();
+
+                       #if MEASURE_TIME
+                       layoutTime.Start ();
+                       #endif
+                       //Debug.WriteLine ("======= Layouting queue start =======");
+
+                       while (Interface.LayoutingQueue.Count > 0) {
+                               LayoutingQueueItem lqi = Interface.LayoutingQueue.Dequeue ();
+                               lqi.ProcessLayouting ();
+                       }
+
+                       #if MEASURE_TIME
+                       layoutTime.Stop ();
+                       #endif
+
+                       //Debug.WriteLine ("otd:" + gobjsToRedraw.Count.ToString () + "-");
+                       //final redraw clips should be added only when layout is completed among parents,
+                       //that's why it take place in a second pass
+                       GraphicObject[] gotr = new GraphicObject[gobjsToRedraw.Count];
+                       gobjsToRedraw.CopyTo (gotr);
+                       gobjsToRedraw.Clear ();
+                       foreach (GraphicObject p in gotr) {
+                               p.IsQueuedForRedraw = false;
+                               p.Parent.RegisterClip (p.LastPaintedSlot);
+                               p.Parent.RegisterClip (p.getSlot());
+                       }
+
+                       #if MEASURE_TIME
+                       updateTime.Stop ();
+                       drawingTime.Start ();
+                       #endif
+
+                       using (surf = new ImageSurface (bmp, Format.Argb32, ClientRectangle.Width, ClientRectangle.Height, ClientRectangle.Width * 4)) {
+                               using (ctx = new Context (surf)){
+
+
+                                       if (clipping.count > 0) {
+                                               //Link.draw (ctx);
+                                               clipping.clearAndClip(ctx);
+
+                                               foreach (GraphicObject p in invGOList) {
+                                                       if (!p.Visible)
+                                                               continue;
+                                                       if (!clipping.intersect (p.Slot))
+                                                               continue;
+                                                       ctx.Save ();
+
+                                                       p.Paint (ref ctx);
+
+                                                       ctx.Restore ();
+                                               }
+
+                                               #if DEBUG_CLIP_RECTANGLE
+                                               clipping.stroke (ctx, Color.Red.AdjustAlpha(0.5));
+                                               #endif
+
+                                               if (IsDirty)
+                                                       DirtyRect += clipping.Bounds;
+                                               else
+                                                       DirtyRect = clipping.Bounds;
+                                               IsDirty = true;
+
+                                               DirtyRect.Left = Math.Max (0, DirtyRect.Left);
+                                               DirtyRect.Top = Math.Max (0, DirtyRect.Top);
+                                               DirtyRect.Width = Math.Min (ClientRectangle.Width - DirtyRect.Left, DirtyRect.Width);
+                                               DirtyRect.Height = Math.Min (ClientRectangle.Height - DirtyRect.Top, DirtyRect.Height);
+
+                                               clipping.Reset ();
+                                       }
+
+                                       #if MEASURE_TIME
+                                       drawingTime.Stop ();
+                                       #endif
+                                       //surf.WriteToPng (@"/mnt/data/test.png");
+                               }
+                       }
+                       //                      if (ToolTip.isVisible) {
+                       //                              ToolTip.panel.processkLayouting();
+                       //                              if (ToolTip.panel.layoutIsValid)
+                       //                                      ToolTip.panel.Paint(ref ctx);
+                       //                      }
+                       //                      Debug.WriteLine("INTERFACE: layouting: {0} ticks \t graphical update {1} ticks \t drawing {2} ticks",
+                       //                          layoutTime.ElapsedTicks,
+                       //                          guTime.ElapsedTicks,
+                       //                          drawingTime.ElapsedTicks);
+                       //                      Debug.WriteLine("INTERFACE: layouting: {0} ms \t graphical update {1} ms \t drawing {2} ms",
+                       //                          layoutTime.ElapsedMilliseconds,
+                       //                          guTime.ElapsedMilliseconds,
+                       //                          drawingTime.ElapsedMilliseconds);
+
+                       //                      Debug.WriteLine("UPDATE: {0} ticks \t, {1} ms",
+                       //                              updateTime.ElapsedTicks,
+                       //                              updateTime.ElapsedMilliseconds);
+               }
+               public Rectangles clipping {
+                       get { return _redrawClip; }
+                       set { _redrawClip = value; }
+               }
+               public List<GraphicObject> gobjsToRedraw {
+                       get { return _gobjsToRedraw; }
+                       set { _gobjsToRedraw = value; }
+               }
+               public void AddWidget(GraphicObject g)
+               {
+                       g.Parent = this;
+                       GraphicObjects.Insert (0, g);
+
+                       g.RegisterForLayouting (LayoutingType.Sizing);
+               }
+               public void DeleteWidget(GraphicObject g)
+               {
+                       g.Visible = false;//trick to ensure clip is added to refresh zone
+                       g.ClearBinding();
+                       GraphicObjects.Remove (g);
+               }
+               public void PutOnTop(GraphicObject g)
+               {
+                       if (GraphicObjects.IndexOf(g) > 0)
+                       {
+                               GraphicObjects.Remove(g);
+                               GraphicObjects.Insert(0, g);
+                               //g.registerClipRect ();
+                       }
+               }
+               /// <summary> Remove all Graphic objects from top container </summary>
+               public void ClearInterface()
+               {
+                       int i = 0;
+                       while (GraphicObjects.Count>0) {
+                               //TODO:parent is not reset to null because object will be added
+                               //to ObjectToRedraw list, and without parent, it fails
+                               GraphicObject g = GraphicObjects [i];
+                               g.Visible = false;
+                               g.ClearBinding ();
+                               GraphicObjects.RemoveAt (0);
+                       }
+               }
+               public GraphicObject FindByName (string nameToFind)
+               {
+                       foreach (GraphicObject w in GraphicObjects) {
+                               GraphicObject r = w.FindByName (nameToFind);
+                               if (r != null)
+                                       return r;
+                       }
+                       return null;
+               }
+               public void ProcessResize(Rectangle bounds){
+                       clientRectangle = bounds;
+
+                       int stride = 4 * ClientRectangle.Width;
+                       int bmpSize = Math.Abs (stride) * ClientRectangle.Height;
+                       bmp = new byte[bmpSize];
+
+                       foreach (GraphicObject g in GraphicObjects)
+                               g.RegisterForLayouting (LayoutingType.All);
+               }
+
+               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 {
+                               if (value == cursor)
+                                       return;
+                               cursor = value;
+                               MouseCursorChanged.Raise (this,new MouseCursorChangedEventArgs(value));
+                       }
+               }
+               public bool ProcessMouseMove(int x, int y)
+               {
+                       int deltaX = x - Mouse.X;
+                       int deltaY = y - Mouse.Y;
+                       Mouse.X = x;
+                       Mouse.Y = y;
+                       MouseMoveEventArgs e = new MouseMoveEventArgs (x, y, deltaX, deltaY);
+                       e.Mouse = Mouse;
+
+                       if (_activeWidget != null) {
+                               //TODO, ensure object is still in the graphic tree
+                               //send move evt even if mouse move outside bounds
+                               _activeWidget.onMouseMove (this, e);
+                               return true;
+                       }
+
+                       if (hoverWidget != null) {
+                               //TODO, ensure object is still in the graphic tree
+                               //check topmost graphicobject first
+                               GraphicObject tmp = hoverWidget;
+                               GraphicObject topc = null;
+                               while (tmp is GraphicObject) {
+                                       topc = tmp;
+                                       tmp = tmp.Parent as GraphicObject;
+                               }
+                               int idxhw = GraphicObjects.IndexOf (topc);
+                               if (idxhw != 0) {
+                                       int i = 0;
+                                       while (i < idxhw) {
+                                               if (GraphicObjects [i].MouseIsIn (e.Position)) {
+                                                       hoverWidget.onMouseLeave (this, e);
+                                                       GraphicObjects [i].checkHoverWidget (e);
+                                                       return true;
+                                               }
+                                               i++;
+                                       }
+                               }
+
+
+                               if (hoverWidget.MouseIsIn (e.Position)) {
+                                       hoverWidget.checkHoverWidget (e);
+                                       return true;
+                               } else {
+                                       hoverWidget.onMouseLeave (this, e);
+                                       //seek upward from last focused graph obj's
+                                       while (hoverWidget.Parent as GraphicObject != null) {
+                                               hoverWidget = hoverWidget.Parent as GraphicObject;
+                                               if (hoverWidget.MouseIsIn (e.Position)) {
+                                                       hoverWidget.checkHoverWidget (e);
+                                                       return true;
+                                               } else
+                                                       hoverWidget.onMouseLeave (this, e);
+                                       }
+                               }
+                       }
+
+                       //top level graphic obj's parsing
+                       for (int i = 0; i < GraphicObjects.Count; i++) {
+                               GraphicObject g = GraphicObjects[i];
+                               if (g.MouseIsIn (e.Position)) {
+                                       g.checkHoverWidget (e);
+                                       PutOnTop (g);
+                                       return true;
+                               }
+                       }
+                       hoverWidget = null;
+                       return false;
+               }
+               public bool ProcessMouseButtonUp(int button)
+               {
+                       Mouse.DisableBit (button);
+                       MouseButtonEventArgs e = new MouseButtonEventArgs () { Mouse = Mouse };
+
+                       if (_activeWidget == null)
+                               return false;
+
+                       if (mouseRepeatThread != null) {
+                               mouseRepeatOn = false;
+                               mouseRepeatThread.Abort();
+                               mouseRepeatThread.Join ();
+                       }
+
+                       _activeWidget.onMouseUp (this, e);
+                       activeWidget = null;
+                       return true;
+               }
+               public bool ProcessMouseButtonDown(int button)
+               {
+                       Mouse.EnableBit (button);
+                       MouseButtonEventArgs e = new MouseButtonEventArgs () { Mouse = Mouse };
+
+                       if (hoverWidget == null)
+                               return false;
+
+                       hoverWidget.onMouseDown(hoverWidget,new BubblingMouseButtonEventArg(e));
+
+                       if (FocusedWidget == null)
+                               return true;
+                       if (!FocusedWidget.MouseRepeat)
+                               return true;
+                       mouseRepeatThread = new Thread (mouseRepeatThreadFunc);
+                       mouseRepeatThread.Start ();
+                       return true;
+               }
+//             public bool ProcessMouseWheelChanged(int delta)
+//             {
+//                     if (hoverWidget == null)
+//                             return false;
+//                     hoverWidget.onMouseWheel (this, e);
+//                     return true;
+//             }
+
+               volatile bool mouseRepeatOn;
+               volatile int mouseRepeatCount;
+               Thread mouseRepeatThread;
+               void mouseRepeatThreadFunc()
+               {
+                       mouseRepeatOn = true;
+                       Thread.Sleep (Interface.DeviceRepeatDelay);
+                       while (mouseRepeatOn) {
+                               mouseRepeatCount++;
+                               Thread.Sleep (Interface.DeviceRepeatInterval);
+                       }
+                       mouseRepeatCount = 0;
+               }
+               #endregion
 
+               #region ILayoutable implementation
+               public void RegisterClip(Rectangle r){
+                       clipping.AddRectangle (r);
+               }
+               public bool ArrangeChildren { get { return false; }}
+               public int LayoutingTries {
+                       get { throw new NotImplementedException (); }
+                       set { throw new NotImplementedException (); }
+               }
+               public LayoutingType RegisteredLayoutings {
+                       get { return LayoutingType.None; }
+                       set { throw new NotImplementedException (); }
+               }
+               public void RegisterForLayouting (LayoutingType layoutType) { throw new NotImplementedException (); }
+               public bool UpdateLayout (LayoutingType layoutType) { throw new NotImplementedException (); }
+               public Rectangle ContextCoordinates (Rectangle r) => r;
+               public Rectangle ScreenCoordinates (Rectangle r) => r;
+
+               public ILayoutable Parent {
+                       get { return null; }
+                       set { throw new NotImplementedException (); }
+               }
+               public ILayoutable LogicalParent {
+                       get { return null; }
+                       set { throw new NotImplementedException (); }
+               }
+
+               public Rectangle ClientRectangle {
+                       get { return clientRectangle; }
+               }
+               public Interface HostContainer {
+                       get { return this; }
+               }
+               public Rectangle getSlot () => ClientRectangle;
+               public Rectangle getBounds () => ClientRectangle;
                #endregion
        }
 }
diff --git a/src/MouseCursorChangedEventArgs.cs b/src/MouseCursorChangedEventArgs.cs
new file mode 100644 (file)
index 0000000..b39d4a5
--- /dev/null
@@ -0,0 +1,33 @@
+//
+//  MouseCursorChangedEventArg.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;
+
+namespace Crow
+{
+       public class MouseCursorChangedEventArgs : EventArgs
+       {
+               public XCursor NewCursor;
+               public MouseCursorChangedEventArgs (XCursor NewCursor) : base()
+               {
+                       NewCursor = NewCursor;
+               }
+       }
+}