]> O.S.I.I.S - jp/crow.git/commitdiff
first render cycle with native c libcrow
authorjpbruyere <jp.bruyere@hotmail.com>
Thu, 1 Jun 2017 17:56:26 +0000 (19:56 +0200)
committerjpbruyere <jp.bruyere@hotmail.com>
Thu, 1 Jun 2017 17:56:26 +0000 (19:56 +0200)
12 files changed:
src/Crow.Native/LibCrow.cs
src/Crow.Native/crow_object_t.cs
src/GraphicObjects/FileDialog.cs
src/GraphicObjects/GraphicObject.cs
src/GraphicObjects/Group.cs
src/GraphicObjects/MessageBox.cs
src/GraphicObjects/Popper.cs
src/GraphicObjects/Window.cs
src/Interface.cs
testDrm/TestCrow.cs
testDrm/testDrm.csproj
testDrm/ui/go.crow

index 3b031adf23b9aa319f103cc78f75c632f140de2a..5496f19f67a9fb715dae94fb93246ce9e1d88b8e 100644 (file)
@@ -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              
        }
 }
index 5d8fb1b7632a025d95c69d2f4354ea8750246adb..e6f5b49295228a022413c3984c5acbef92142c2c 100644 (file)
@@ -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;
                /// <summary>if true, content has to be recreated</summary>
                public byte IsDirty;
                public byte InClippingPool;
+               public byte CacheEnabled;
                public IntPtr Clipping;
                public LayoutingType RegisteredLayoutings;
+               public Size ContentSize;
                /// <summary>
                /// Current size and position computed during layouting pass
                /// </summary>
                public Rectangle Slot;
-               public Size ContentSize;
                /// <summary>
                /// 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
index 8182e02166dc3818125e32a4d09b6942e8a3ebbd..1abdac177bbbc3d045bdf392a33ab63cd590bd2d 100644 (file)
@@ -124,7 +124,7 @@ namespace Crow
                        unloadDialog ((sender as GraphicObject).CurrentInterface);
                }
                void unloadDialog(Interface host){
-                       host.DeleteWidget (this);
+                       host.RemoveChild (this);
                }
        }
 }
index 9907810c1f97a16f63ea1fe93ff3cee130f5ac8a..5486030e0639aa2f5d6d220671548513afe0705c 100644 (file)
@@ -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.
                /// </summary>
                [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);
                        }
                }
                /// <summary>
@@ -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 ();
 
index d42da81d2d028642f42a46f78e1d643ee282cbd3..5b8e5ab0e60162f446d458fed5cbaa56662013af 100644 (file)
@@ -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<EventArgs> 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);
                        }
index d8ce1dae7d401b327d0a3ad08f9157ece9a4e722..5ca69f7aa1984fddb8a659410aff670c1ebebfe7 100644 (file)
@@ -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))
index 18e615b5415b8acadfd25a4a13d765d26ce2108f..62906228f4b0cda34ca5cfdf341fbfffe7670921 100644 (file)
@@ -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);
index 4b002f8b39cdcd6fa8c43cb81745e9e98737b8d7..817c6dc2556029a8b1d0d2246cc0c6eacc4efdfb 100644 (file)
@@ -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);
                }
        }
 }
index 390ecd660586b83c9f1c83a0a436f51f1c551974..77f822f06271ba7b2e17598717208afcc772b5c0 100644 (file)
@@ -50,7 +50,7 @@ namespace Crow
        ///     - Keyboard and Mouse logic
        ///     - the resulting bitmap of the interface
        /// </summary>
-       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
-               /// <summary>Add widget to the Graphic tree of this interface and register it for layouting</summary>
-               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);
-               }
-               /// <summary>Set visible state of widget to false and remove if from the graphic tree</summary>
-               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);
-                       }
-               }
-               /// <summary> Put widget on top of other root widgets</summary>
-               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);
-                       }
-               }
-               /// <summary> Remove all Graphic objects from top container </summary>
-               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<LQIList>();
-                       curLQIsTries = new LQIList();
-                       LQIs = new List<LQIList>();
-                       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) {
-                               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;
                                        }
                                }
index 17e3353a933e7b2e568abf311175fdb8684687b5..bc6ba00d11a4d794a64c6c9ad4cbe9002189c72b 100644 (file)
@@ -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 ();
index c53ef6c297049694da874f1768d21b7ad5b983e9..2a5c94e2fc481fb30a1eda5ce848ab9e5f76b845 100644 (file)
@@ -56,8 +56,6 @@
     <Compile Include="src\Linux\Bindings\Udev.cs" />
     <Compile Include="src\Linux\Signal.cs" />
     <Compile Include="src\Application.cs" />
-    <Compile Include="Main.cs" />
-    <Compile Include="tests.cs" />
     <Compile Include="testLibInput.cs" />
     <Compile Include="src\EVDEV\Device.cs" />
     <Compile Include="src\Linux\Bindings\EvdevClass.cs" />
@@ -66,7 +64,6 @@
     <Compile Include="src\Linux\DRIControler.cs" />
     <Compile Include="testCairo.cs" />
     <Compile Include="TestCrow.cs" />
-    <Compile Include="Showcase.cs" />
   </ItemGroup>
   <ItemGroup>
     <Reference Include="System" />
     <EmbeddedResource Include="ui\go.crow" />
     <EmbeddedResource Include="ui\showcase.crow" />
   </ItemGroup>
+  <ItemGroup>
+    <None Include="Main.cs" />
+    <None Include="tests.cs" />
+    <None Include="Showcase.cs" />
+  </ItemGroup>
 </Project>
\ No newline at end of file
index 7f42e136cb08eb34e21091c8acebacc88702bc95..7c5712fc5f284550bae213caa16936bc852eee05 100755 (executable)
@@ -1,2 +1,7 @@
 <?xml version="1.0"?>
-<GraphicObject Width="Stretched" Height="Stretched" Background="Mantis"/>
\ No newline at end of file
+<Group Margin="50" Width="Stretched" Height="Stretched" Background="DimGray">
+       <Group Margin="100" Background="Jet" Width="Stretched" Height="Stretched">
+               <GraphicObject Margin="50" Width="Stretched" Height="100" Background="Mantis"/>
+               <GraphicObject Margin="50" Width="Stretched" Height="100" Background="Maize" VerticalAlignment="Bottom"/>
+       </Group>
+</Group>
\ No newline at end of file