From: jpbruyere Date: Thu, 1 Jun 2017 17:56:26 +0000 (+0200) Subject: first render cycle with native c libcrow X-Git-Url: https://git.osiis.dedyn.io/?a=commitdiff_plain;h=84b2304ff1ee1d89149163da40fe27cc60797a79;p=jp%2Fcrow.git first render cycle with native c libcrow --- diff --git a/src/Crow.Native/LibCrow.cs b/src/Crow.Native/LibCrow.cs index 3b031adf..5496f19f 100644 --- a/src/Crow.Native/LibCrow.cs +++ b/src/Crow.Native/LibCrow.cs @@ -33,13 +33,17 @@ namespace Crow.Native #region PINVOKE const string lib = "libcrow"; [DllImport(lib, CallingConvention = CallingConvention.Cdecl)] - unsafe internal static extern IntPtr crow_context_create (); + internal static extern IntPtr crow_context_create (); [DllImport(lib, CallingConvention = CallingConvention.Cdecl)] - unsafe internal static extern void crow_context_destroy (IntPtr ctx); + internal static extern void crow_context_destroy (IntPtr ctx); [DllImport(lib, CallingConvention = CallingConvention.Cdecl)] - unsafe internal static extern void crow_context_process_layouting (IntPtr layCtx); + unsafe internal static extern void crow_context_set_root (IntPtr ctx, crow_object_t* root); [DllImport(lib, CallingConvention = CallingConvention.Cdecl)] - unsafe internal static extern void crow_context_process_clipping (IntPtr ctx); + internal static extern void crow_context_process_layouting (IntPtr ctx); + [DllImport(lib, CallingConvention = CallingConvention.Cdecl)] + internal static extern void crow_context_process_clipping (IntPtr ctx); + [DllImport(lib, CallingConvention = CallingConvention.Cdecl)] + internal static extern void crow_context_process_drawing (IntPtr ctx, IntPtr cairoCtx); [DllImport(lib)] unsafe internal static extern crow_object_t* crow_object_create(); @@ -50,7 +54,13 @@ namespace Crow.Native [DllImport(lib, CallingConvention = CallingConvention.Cdecl)] unsafe internal static extern byte crow_object_do_layout (crow_object_t* go, LayoutingType layout); [DllImport(lib, CallingConvention = CallingConvention.Cdecl)] - unsafe internal static extern void crow_object_register_layouting (crow_object_t* go, LayoutingType layout); + unsafe internal static extern byte crow_object_register_layouting (crow_object_t* go, LayoutingType layout); + + + [DllImport(lib, CallingConvention = CallingConvention.Cdecl)] + unsafe internal static extern void crow_object_child_add (crow_object_t* parent, crow_object_t* child); + [DllImport(lib, CallingConvention = CallingConvention.Cdecl)] + unsafe internal static extern void crow_object_child_remove (crow_object_t* parent, crow_object_t* child); #endregion } } diff --git a/src/Crow.Native/crow_object_t.cs b/src/Crow.Native/crow_object_t.cs index 5d8fb1b7..e6f5b492 100644 --- a/src/Crow.Native/crow_object_t.cs +++ b/src/Crow.Native/crow_object_t.cs @@ -41,6 +41,8 @@ namespace Crow.Native { public int ChildrenCount; public crow_object_t* Parent; public crow_object_t** Children; + public crow_object_t* LargestChild; + public crow_object_t* TallestChild; public int Left; public int Top; public Measure Width; @@ -48,17 +50,19 @@ namespace Crow.Native { public int Margin; public Size MinimumSize; public Size MaximumSize; + public IntPtr Background; public byte Visible; /// if true, content has to be recreated public byte IsDirty; public byte InClippingPool; + public byte CacheEnabled; public IntPtr Clipping; public LayoutingType RegisteredLayoutings; + public Size ContentSize; /// /// Current size and position computed during layouting pass /// public Rectangle Slot; - public Size ContentSize; /// /// keep last slot components for each layouting pass to track /// changes and trigger update of other component accordingly @@ -80,7 +84,7 @@ namespace Crow.Native { public IntPtr OnLayoutChanged; public IntPtr OnChildLayoutChanged; public IntPtr ChildrenLayoutingConstraints; + public IntPtr UpdateCache; public IntPtr OnDraw; - } } \ No newline at end of file diff --git a/src/GraphicObjects/FileDialog.cs b/src/GraphicObjects/FileDialog.cs index 8182e021..1abdac17 100644 --- a/src/GraphicObjects/FileDialog.cs +++ b/src/GraphicObjects/FileDialog.cs @@ -124,7 +124,7 @@ namespace Crow unloadDialog ((sender as GraphicObject).CurrentInterface); } void unloadDialog(Interface host){ - host.DeleteWidget (this); + host.RemoveChild (this); } } } diff --git a/src/GraphicObjects/GraphicObject.cs b/src/GraphicObjects/GraphicObject.cs index 9907810c..5486030e 100644 --- a/src/GraphicObjects/GraphicObject.cs +++ b/src/GraphicObjects/GraphicObject.cs @@ -63,18 +63,20 @@ namespace Crow #region CTOR public GraphicObject () { + initLibcrow (); + #if DEBUG + uid = currentUid; + currentUid++; + #endif + } + protected virtual void initLibcrow (){ unsafe { nativeHnd = LibCrow.crow_object_create (); LibCrow.crow_object_set_type (nativeHnd, CrowType.Simple); nativeHnd->Context = Interface.CurrentInterface.layoutingCtx; + nativeHnd->IsDirty = 1; //nativeHnd->OnLayoutChanged = Marshal.GetFunctionPointerForDelegate((LayoutChangedCallBack)OnLayoutChanges); } - #if DEBUG - uid = currentUid; - currentUid++; - #endif - } - internal protected GraphicObject (bool isInterface){ } #endregion @@ -102,7 +104,6 @@ namespace Crow bool isActive = false; bool mouseRepeat; bool isEnabled = true; - bool cacheEnabled = false; bool clipToClientRect = true; protected object dataSource; string style; @@ -144,10 +145,10 @@ namespace Crow DataSourceChangeEventArgs e = new DataSourceChangeEventArgs (parent, value); lock (this) { parent = value; - if (parent == null) - nativeHnd->Parent = null; - else - nativeHnd->Parent = value.nativeHnd; +// if (parent == null) +// nativeHnd->Parent = null; +// else +// nativeHnd->Parent = value.nativeHnd; } onParentChanged (this, e); @@ -240,13 +241,16 @@ namespace Crow /// speeding up rendering of complex object. Default is enabled. /// [XmlAttributeAttribute][DefaultValue(true)] - public virtual bool CacheEnabled { - get { return cacheEnabled; } + unsafe public virtual bool CacheEnabled { + get { return nativeHnd->CacheEnabled>0; } set { - if (cacheEnabled == value) + if (CacheEnabled == value) return; - cacheEnabled = value; - NotifyValueChanged ("CacheEnabled", cacheEnabled); + if (value) + nativeHnd->CacheEnabled = 1; + else + nativeHnd->CacheEnabled = 0; + NotifyValueChanged ("CacheEnabled", CacheEnabled); } } /// @@ -467,21 +471,26 @@ namespace Crow } bool clearBackground = false; [XmlAttributeAttribute()][DefaultValue("Transparent")] - public virtual Fill Background { + unsafe public virtual Fill Background { get { return background; } set { if (background == value) return; clearBackground = false; + if (nativeHnd->Background != IntPtr.Zero) { + Cairo.NativeMethods.cairo_pattern_destroy (nativeHnd->Background); + nativeHnd->Background = IntPtr.Zero; + } if (value == null) return; background = value; + SolidColor sc = value as SolidColor; + if (sc != null) { + nativeHnd->Background = Cairo.NativeMethods.cairo_pattern_create_rgba ( + sc.color.R, sc.color.G, sc.color.B, sc.color.A); + } NotifyValueChanged ("Background", background); RegisterForRedraw (); - if (background is SolidColor) { - if ((Background as SolidColor).Equals (Color.Clear)) - clearBackground = true; - } } } [XmlAttributeAttribute()][DefaultValue("White")] @@ -1122,12 +1131,12 @@ namespace Crow if (nativeHnd->Slot.Height < 0 || nativeHnd->Slot.Width < 0 || parent == null) return; lock (this) { - if (cacheEnabled) { + if (CacheEnabled) { if (nativeHnd->Slot.Width > Interface.MaxCacheSize || nativeHnd->Slot.Height > Interface.MaxCacheSize) - cacheEnabled = false; + CacheEnabled = false; } - if (cacheEnabled) { + if (CacheEnabled) { if (IsDirty) RecreateCache (); diff --git a/src/GraphicObjects/Group.cs b/src/GraphicObjects/Group.cs index d42da81d..5b8e5ab0 100644 --- a/src/GraphicObjects/Group.cs +++ b/src/GraphicObjects/Group.cs @@ -31,6 +31,7 @@ using System.Xml.Serialization; using Cairo; using System.Diagnostics; using System.Reflection; +using Crow.Native; namespace Crow @@ -42,6 +43,16 @@ namespace Crow : base(){} #endregion + protected override void initLibcrow () + { + unsafe { + nativeHnd = LibCrow.crow_object_create (); + LibCrow.crow_object_set_type (nativeHnd, CrowType.Group); + nativeHnd->IsDirty = 1; + nativeHnd->Context = Interface.CurrentInterface.layoutingCtx; + } + } + #region EVENT HANDLERS public event EventHandler ChildrenCleared; #endregion @@ -63,6 +74,9 @@ namespace Crow } public virtual void AddChild(GraphicObject g){ lock (children) { + unsafe { + LibCrow.crow_object_child_add (this.nativeHnd, g.nativeHnd); + } g.Parent = this; Children.Add (g); } diff --git a/src/GraphicObjects/MessageBox.cs b/src/GraphicObjects/MessageBox.cs index d8ce1dae..5ca69f7a 100644 --- a/src/GraphicObjects/MessageBox.cs +++ b/src/GraphicObjects/MessageBox.cs @@ -135,7 +135,7 @@ namespace Crow lock (Interface.CurrentInterface.UpdateMutex) { MessageBox mb = new MessageBox (); mb.Initialize (); - mb.CurrentInterface.AddWidget (mb); + mb.CurrentInterface.AddChild (mb); mb.MsgType = msgBoxType; mb.Message = message; if (!string.IsNullOrEmpty(okMsg)) diff --git a/src/GraphicObjects/Popper.cs b/src/GraphicObjects/Popper.cs index 18e615b5..62906228 100644 --- a/src/GraphicObjects/Popper.cs +++ b/src/GraphicObjects/Popper.cs @@ -225,10 +225,10 @@ namespace Crow if (Content != null) { Content.Visible = true; if (Content.Parent == null) - CurrentInterface.AddWidget (Content, true); + CurrentInterface.AddChild (Content); if (Content.LogicalParent != this) Content.LogicalParent = this; - CurrentInterface.PutOnTop (Content, true); + //CurrentInterface.PutOnTop (Content, true); _content_LayoutChanged (this, new LayoutingEventArgs (LayoutingType.Sizing)); } Popped.Raise (this, e); diff --git a/src/GraphicObjects/Window.cs b/src/GraphicObjects/Window.cs index 4b002f8b..817c6dc2 100644 --- a/src/GraphicObjects/Window.cs +++ b/src/GraphicObjects/Window.cs @@ -151,8 +151,8 @@ namespace Crow return; alwaysOnTop = value; - if (alwaysOnTop && Parent != null) - CurrentInterface.PutOnTop (this); +// if (alwaysOnTop && Parent != null) +// CurrentInterface.PutOnTop (this); NotifyValueChanged ("AlwaysOnTop", alwaysOnTop); } @@ -391,7 +391,7 @@ namespace Crow protected void close(){ Closing.Raise (this, null); - CurrentInterface.DeleteWidget (this); + CurrentInterface.RemoveChild (this); } } } diff --git a/src/Interface.cs b/src/Interface.cs index 390ecd66..77f822f0 100644 --- a/src/Interface.cs +++ b/src/Interface.cs @@ -50,7 +50,7 @@ namespace Crow /// - Keyboard and Mouse logic /// - the resulting bitmap of the interface /// - public class Interface : GraphicObject + public class Interface : Group { #region CTOR static Interface(){ @@ -64,14 +64,21 @@ namespace Crow FontRenderingOptions.HintStyle = HintStyle.Medium; FontRenderingOptions.SubpixelOrder = SubpixelOrder.Rgb; } - public Interface() : base (true){ + public Interface() : base (){ + CacheEnabled = true; + CultureInfo.DefaultThreadCurrentCulture = System.Globalization.CultureInfo.InvariantCulture; + } + protected override void initLibcrow () + { CurrentInterface = this; layoutingCtx = LibCrow.crow_context_create (); - unsafe { - nativeHnd = LibCrow.crow_object_create (); - } - CultureInfo.DefaultThreadCurrentCulture = System.Globalization.CultureInfo.InvariantCulture; + base.initLibcrow (); + + unsafe { + LibCrow.crow_context_set_root (layoutingCtx, nativeHnd); + //nativeHnd->Background = Cairo.NativeMethods.cairo_pattern_create_rgb (1, 0, 1); + } } #endregion @@ -268,7 +275,7 @@ namespace Crow { lock (UpdateMutex) { GraphicObject tmp = Load (path); - AddWidget (tmp); + AddChild (tmp); return tmp; } @@ -471,7 +478,7 @@ namespace Crow #if MEASURE_TIME clippingMeasure.StartCycle(); #endif - LibCrow.crow_context_process_layouting (layoutingCtx); + LibCrow.crow_context_process_clipping (layoutingCtx); #if MEASURE_TIME clippingMeasure.StopCycle(); #endif @@ -483,62 +490,8 @@ namespace Crow drawingMeasure.StartCycle(); #endif using (surf = new ImageSurface (bmp, Format.Argb32, ClientRectangle.Width, ClientRectangle.Height, ClientRectangle.Width * 4)) { - using (ctx = new Context (surf)){ - if (!clipping.IsEmpty) { - - for (int i = 0; i < clipping.NumRectangles; i++) - ctx.Rectangle(clipping.GetRectangle(i)); - ctx.ClipPreserve(); - ctx.Operator = Operator.Clear; - ctx.Fill(); - ctx.Operator = Operator.Over; - - for (int i = GraphicTree.Count -1; i >= 0 ; i--){ - GraphicObject p = GraphicTree[i]; - if (!p.Visible) - continue; - if (clipping.Contains (p.nativeHnd->Slot) == RegionOverlap.Out) - continue; - - ctx.Save (); - p.Paint (ref ctx); - ctx.Restore (); - } - - #if DEBUG_CLIP_RECTANGLE - clipping.stroke (ctx, Color.Red.AdjustAlpha(0.5)); - #endif - lock (RenderMutex) { -// Array.Copy (bmp, dirtyBmp, bmp.Length); - - IsDirty = true; - if (IsDirty) - DirtyRect += clipping.Extents; - else - DirtyRect = clipping.Extents; - - 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.Max (0, DirtyRect.Width); - DirtyRect.Height = Math.Max (0, DirtyRect.Height); - - if (DirtyRect.Width > 0 && DirtyRect.Height >0) { - dirtyBmp = 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, - dirtyBmp, y * DirtyRect.Width * 4, DirtyRect.Width * 4); - } - - } else - IsDirty = false; - } - clipping.Dispose (); - clipping = new Region (); - } - //surf.WriteToPng (@"/mnt/data/test.png"); + using (ctx = new Context (surf)) { + LibCrow.crow_context_process_drawing (layoutingCtx, ctx.Handle); } } #if MEASURE_TIME @@ -547,100 +500,6 @@ namespace Crow } #endregion - #region GraphicTree handling - /// Add widget to the Graphic tree of this interface and register it for layouting - public void AddWidget(GraphicObject g, bool isOverlay = false) - { - g.Parent = this; - int ptr = 0; - Window newW = g as Window; - if (newW != null) { - while (ptr < GraphicTree.Count) { - Window w = GraphicTree [ptr] as Window; - if (w != null) { - if (newW.AlwaysOnTop || !w.AlwaysOnTop) - break; - } - ptr++; - } - } - - lock (UpdateMutex) - GraphicTree.Insert (ptr, g); - - g.RegisteredLayoutings = LayoutingType.None; - g.RegisterForLayouting (LayoutingType.Sizing | LayoutingType.ArrangeChildren); - } - /// Set visible state of widget to false and remove if from the graphic tree - public void DeleteWidget(GraphicObject g) - { - if (_hoverWidget != null) { - if (g.Contains (_hoverWidget)) - HoverWidget = null; - } - lock (UpdateMutex) { - g.DataSource = null; - g.Visible = false; - GraphicTree.Remove (g); - } - } - /// Put widget on top of other root widgets - public void PutOnTop(GraphicObject g, bool isOverlay = false) - { - int ptr = 0; - Window newW = g as Window; - if (newW != null) { - while (ptr < GraphicTree.Count) { - Window w = GraphicTree [ptr] as Window; - if (w != null) { - if (newW.AlwaysOnTop || !w.AlwaysOnTop) - break; - } - ptr++; - } - } - if (GraphicTree.IndexOf(g) > ptr) - { - lock (UpdateMutex) { - GraphicTree.Remove (g); - GraphicTree.Insert (ptr, g); - } - EnqueueForRepaint (g); - } - } - /// Remove all Graphic objects from top container - public void ClearInterface() - { - lock (UpdateMutex) { - while (GraphicTree.Count > 0) { - //TODO:parent is not reset to null because object will be added - //to ObjectToRedraw list, and without parent, it fails - GraphicObject g = GraphicTree [0]; - g.DataSource = null; - g.Visible = false; - GraphicTree.RemoveAt (0); - } - } - #if DEBUG_LAYOUTING - LQIsTries = new List(); - curLQIsTries = new LQIList(); - LQIs = new List(); - curLQIs = new LQIList(); - #endif - } - - /// Search a Graphic object in the tree named 'nameToFind' - public GraphicObject FindByName (string nameToFind) - { - foreach (GraphicObject w in GraphicTree) { - GraphicObject r = w.FindByName (nameToFind); - if (r != null) - return r; - } - return null; - } - #endregion - public void ProcessResize(Rectangle bounds){ lock (UpdateMutex) { unsafe { @@ -742,8 +601,8 @@ namespace Crow GraphicObject g = GraphicTree [i]; if (g.MouseIsIn (e.Position)) { g.checkHoverWidget (e); - if (g is Window) - PutOnTop (g); +// if (g is Window) +// PutOnTop (g); return true; } } diff --git a/testDrm/TestCrow.cs b/testDrm/TestCrow.cs index 17e3353a..bc6ba00d 100644 --- a/testDrm/TestCrow.cs +++ b/testDrm/TestCrow.cs @@ -62,6 +62,7 @@ namespace testDrm static void Main(){ using (Interface iface = new Interface ()) { + Console.WriteLine ("is dirty: {0}", iface.IsDirty); iface.ProcessResize (new Rectangle (0, 0, 1024, 768)); iface.LoadInterface ("#testDrm.ui.go.crow"); iface.Update (); diff --git a/testDrm/testDrm.csproj b/testDrm/testDrm.csproj index c53ef6c2..2a5c94e2 100644 --- a/testDrm/testDrm.csproj +++ b/testDrm/testDrm.csproj @@ -56,8 +56,6 @@ - - @@ -66,7 +64,6 @@ - @@ -107,4 +104,9 @@ + + + + + \ No newline at end of file diff --git a/testDrm/ui/go.crow b/testDrm/ui/go.crow index 7f42e136..7c5712fc 100755 --- a/testDrm/ui/go.crow +++ b/testDrm/ui/go.crow @@ -1,2 +1,7 @@ - \ No newline at end of file + + + + + + \ No newline at end of file