]> O.S.I.I.S - jp/crow.git/commitdiff
unshown post process slot handling, GetClientRectangleForChild added to the ILayoutab...
authorJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Thu, 9 Sep 2021 17:34:45 +0000 (17:34 +0000)
committerJean-Philippe Bruyère <jp_bruyere@hotmail.com>
Thu, 9 Sep 2021 17:34:45 +0000 (17:34 +0000)
15 files changed:
Crow/Crow.csproj
Crow/sgKey.snk [new file with mode: 0644]
Crow/src/Interface.cs
Crow/src/Widgets/EnumSelector.cs
Crow/src/Widgets/GenericStack.cs
Crow/src/Widgets/Grid.cs
Crow/src/Widgets/Group.cs
Crow/src/Widgets/ILayoutable.cs
Crow/src/Widgets/Table.cs
Crow/src/Widgets/TableRow.cs
Crow/src/Widgets/Widget.cs
Crow/src/Widgets/Window.cs
Directory.Build.props
Samples/common/src/Editor.cs
Samples/common/ui/Interfaces/Experimental/testGrid.crow [new file with mode: 0644]

index e778a55be86dfb01cc1e07e9773a1defa724eedb..3b054bb463e721149891ee148c7a4b866f06d12d 100644 (file)
@@ -2,7 +2,7 @@
 <Project Sdk="Microsoft.NET.Sdk">
        <PropertyGroup>
 <!--           <TargetFrameworks>netstandard2.0</TargetFrameworks>-->
-               <TargetFrameworks>netstandard2.1</TargetFrameworks>
+               <TargetFramework>netstandard2.1</TargetFramework>
                
                <AssemblyVersion>$(CrowVersion)</AssemblyVersion>
                <PackageVersion>$(CrowPackageVersion)</PackageVersion>
diff --git a/Crow/sgKey.snk b/Crow/sgKey.snk
new file mode 100644 (file)
index 0000000..9c8ae24
Binary files /dev/null and b/Crow/sgKey.snk differ
index 632c9bbf66cd58c428cbc76868ee5d2ed1cbe2f7..4bc338966c6c434fd984d441a6bcd5efaabb982e 100644 (file)
@@ -33,15 +33,15 @@ namespace Crow
        ///     - global static constants and variables of CROW
        ///     - Keyboard and Mouse logic
        ///     - the resulting bitmap of the interface
-       /// 
+       ///
        /// the master branch and the nuget package includes an OpenTK renderer which allows
        /// the creation of multiple threaded interfaces.
-       /// 
+       ///
        /// If you intend to create another renderer (GDK, vulkan, etc) the minimal step is to
        /// put an interface instance as member of your root object and call (optionally in another thread) the update function
        /// at regular interval. Then you have to call
        /// mouse, keyboard and resize functions of the interface when those events occurs in the host app.
-       /// 
+       ///
        /// The resulting surface (a byte array in the OpenTK renderer) is made available and protected with the
        /// RenderMutex of the interface.
        /// </remarks>
@@ -61,6 +61,13 @@ namespace Crow
                #endregion
 
                internal static List<Assembly> crowAssemblies = new List<Assembly> ();
+               /// <summary>
+               /// Add Assembly that may contains CROW ui stuf like widgets or iml.
+               /// Styling fond in that assembly are automatically loaded on addition;
+               /// This assembly will be searched for embedded ressource resolution, extension methods, and custom widgets.
+               /// For those assembly to be added by simple name, see 'CrowAssemblyNames'.
+               /// </summary>
+               /// <param name="a">The assembly to add.</param>
                public void AddCrowAssembly (Assembly a) {
                        lock (UpdateMutex) {
                                if (crowAssemblies.Contains (a))
@@ -69,6 +76,10 @@ namespace Crow
                                loadStylingFromAssembly (a);
                        }
                }
+               /// <summary>
+               /// Remove Assembly from the CrowAssembly list. See 'AddCrowAssembly' for details.
+               /// </summary>
+               /// <param name="a"></param>
                public void RemoveCrowAssembly (Assembly a) {
                        lock (UpdateMutex) {
                                if (!crowAssemblies.Contains (a))
@@ -94,9 +105,12 @@ namespace Crow
                        FontRenderingOptions.HintMetrics = HintMetrics.On;
                        FontRenderingOptions.HintStyle = HintStyle.Full;
                        FontRenderingOptions.SubpixelOrder = SubpixelOrder.Default;
-
-                       
                }
+               /// <summary>
+               /// Each time this array is set, the resolved Assemblies will be
+               /// added to the CrowAssemblies list, see 'AddCrowAssembly' for details.
+               /// </summary>
+               /// <value></value>
                public static string [] CrowAssemblyNames {
                        set {
                                if (value == null)
@@ -117,7 +131,7 @@ namespace Crow
                                                crowAssemblies.Add (a);
                                } catch {
 
-                               }                                                                                       
+                               }
                        }*/
                        foreach (string assemblyName in crowAssemblyNames) {
                                try {
@@ -126,21 +140,37 @@ namespace Crow
                                        Console.ForegroundColor = ConsoleColor.Red;
                                        Console.WriteLine ($"Unable to preload CrowAssembly: {assemblyName}: {ex}");
                                        Console.ResetColor();
-                               }                                                                                       
+                               }
                        }
 
                }
-
+               /// <summary>
+               /// Create a new Crow Interface by providing an existing valid GLFW window handle.
+               /// UI thread will not be started, and the main surface will not be initialized.
+               /// This is used to give crow support to existing glfw application by providing
+               /// a custom suface creation, and a custom update thread.
+               /// </summary>
+               /// <param name="width">the width of the window</param>
+               /// <param name="height">the height of the window</param>
+               /// <param name="glfwWindowHandle">A valid GLFW window handle</param>
+               /// <returns></returns>
                public Interface (int width, int height, IntPtr glfwWindowHandle) : this (width, height, false, false)
                {
                        hWin = glfwWindowHandle;
                        PerformanceMeasure.InitMeasures ();
                }
-#if VKVG               
+#if VKVG
                public const bool HaveVkvgBackend = true;
 #else
                public const bool HaveVkvgBackend = false;
 #endif
+               /// <summary>
+               /// Create a standard Crow interface
+               /// </summary>
+               /// <param name="width">the width of the native window</param>
+               /// <param name="height">the height of the native window</param>
+               /// <param name="startUIThread">If 'yes' start the ui update (InterfaceThread method) in a dedicated thread</param>
+               /// <param name="createSurface">If 'yes', create the main rendering surface on the native window</param>
                public Interface (int width = 800, int height = 600, bool startUIThread = true, bool createSurface = true)
                {
                        CultureInfo.DefaultThreadCurrentCulture = CultureInfo.InvariantCulture;
@@ -219,7 +249,7 @@ namespace Crow
                        hWin = Glfw3.CreateWindow (clientRectangle.Width, clientRectangle.Height, "win name", MonitorHandle.Zero, IntPtr.Zero);
                        if (hWin == IntPtr.Zero)
                                throw new Exception ("[GLFW3] Unable to create vulkan Window");
-                       ownWindow = true;                       
+                       ownWindow = true;
 
                        registerGlfwCallbacks ();
 
@@ -257,7 +287,7 @@ namespace Crow
 #else
                        surf = new ImageSurface (Format.Argb32, r.Width, r.Height);
 #endif
-               }               
+               }
                public Surface CreateSurface (ref Rectangle r) {
 #if (VKVG)
                        return new Surface (vkvgDevice, r.Width, r.Height);
@@ -270,13 +300,13 @@ namespace Crow
                        return new Surface (vkvgDevice, width, height);
 #else
                        return surf.CreateSimilar (Content.ColorAlpha, width, height);
-#endif     
+#endif
                }
                public Surface CreateSurface (IntPtr existingSurfaceHandle) {
 #if (VKVG)
                        return new Surface (vkvgDevice, existingSurfaceHandle);
 #else
-                       return Surface.Lookup (existingSurfaceHandle, false);                        
+                       return Surface.Lookup (existingSurfaceHandle, false);
 #endif
                }
                public Surface CreateSurfaceForData (IntPtr data, int width, int height) {
@@ -311,7 +341,7 @@ namespace Crow
                                Glfw.Image icon = new Glfw.Image ((uint)stbi.Width, (uint)stbi.Height, image);
                                Glfw3.SetWindowIcon (hWin, 1, ref icon);
                                icon.Dispose();
-                               
+
 #else
                                using (StbImage stbi = new StbImage (stream)) {
                                        byte[] image = new byte [stbi.Size];
@@ -387,8 +417,8 @@ namespace Crow
                };
 
                #endregion
-               
-               public string WindowTitle {                     
+
+               public string WindowTitle {
                        set => Glfw3.SetWindowTitle (hWin, value);
                }
 
@@ -428,9 +458,9 @@ namespace Crow
                        disposeContextMenus ();
                        initDictionaries ();
                        loadStyling ();
-                       loadThemeFiles ();                                      
+                       loadThemeFiles ();
                        initContextMenus ();
-               }               
+               }
                /// <summary>
                /// call Init() then enter the running loop performing ProcessEvents until running==false.
                /// </summary>
@@ -441,7 +471,7 @@ namespace Crow
                                Glfw3.PollEvents ();
                                UpdateFrame ();
                        }
-                       
+
                        Terminate ();
                }
                public virtual void Terminate () {}
@@ -598,7 +628,7 @@ namespace Crow
                /// <summary>Sync mutex between host and Crow for rendering operations (bmp, dirtyBmp,...)</summary>
                public object RenderMutex = new object();
                /// <summary>Global lock of the update cycle</summary>
-               public object UpdateMutex = new object();               
+               public object UpdateMutex = new object();
                /// <summary>Global lock of the clipping queue</summary>
                public object ClippingMutex = new object();
                //TODO:share resource instances
@@ -620,7 +650,7 @@ namespace Crow
                /// <summary>each IML and fragments (such as inline Templates) are compiled as a Dynamic Method stored here
                /// on the first instance creation of a IML item.
                /// </summary>
-               public Dictionary<String, Instantiator> Instantiators;          
+               public Dictionary<String, Instantiator> Instantiators;
                /// <summary>
                /// default templates dic by metadata token
                /// </summary>
@@ -645,7 +675,7 @@ namespace Crow
                        lock (UpdateMutex) {
                                if (DragImage == null)
                                        return;
-                               clipping.UnionRectangle (lastDragImageBounds);                          
+                               clipping.UnionRectangle (lastDragImageBounds);
                                DragImage.Dispose();
                                DragImage = null;
                                DragImageBounds = lastDragImageBounds = default;
@@ -699,7 +729,7 @@ namespace Crow
                        loadThemeStyle ();
                        loadStylingFromAssembly (Assembly.GetEntryAssembly ());
                        foreach (Assembly a in crowAssemblies)
-                               loadStylingFromAssembly (a);                    
+                               loadStylingFromAssembly (a);
                        loadStylingFromAssembly (Assembly.GetExecutingAssembly ());
                }
                /// <summary> Search for .style resources in assembly </summary>
@@ -709,7 +739,7 @@ namespace Crow
                        foreach (string s in assembly
                                .GetManifestResourceNames ()
                                .Where (r => r.EndsWith (".style", StringComparison.OrdinalIgnoreCase))) {
-                               using (StyleReader sr = new StyleReader (assembly.GetManifestResourceStream (s))) 
+                               using (StyleReader sr = new StyleReader (assembly.GetManifestResourceStream (s)))
                                        sr.Parse (StylingConstants, Styling, s);
                        }
                }
@@ -749,7 +779,7 @@ namespace Crow
                        Styling = new Dictionary<string, Style> (initCapacity);
                        DefaultValuesLoader = new Dictionary<string, LoaderInvoker> (initCapacity);
                        Instantiators = new Dictionary<string, Instantiator> (initCapacity);
-                       DefaultTemplates = new Dictionary<string, Instantiator> (initCapacity);                 
+                       DefaultTemplates = new Dictionary<string, Instantiator> (initCapacity);
                        ItemTemplates = new Dictionary<string, ItemTemplate> (initCapacity);
                }
                void loadThemeFiles () {
@@ -864,11 +894,11 @@ namespace Crow
                                        if (tryGetResource (AppDomain.CurrentDomain.GetAssemblies ()
                                                .FirstOrDefault (aa => aa.GetName ().Name == $"{assemblyNames[0]}.{assemblyNames[1]}"), resId, out stream))
                                                return stream;
-                               foreach (Assembly ca in crowAssemblies) 
+                               foreach (Assembly ca in crowAssemblies)
                                        if (tryGetResource (ca, resId, out stream))
                                                return stream;
                                throw new Exception ("Resource not found: " + path);
-                       } 
+                       }
                        if (!File.Exists (path))
                                throw new FileNotFoundException ($"File not found: {path}", path);
                        return new FileStream (path, FileMode.Open, FileAccess.Read);
@@ -898,7 +928,7 @@ namespace Crow
                /// </summary>
                /// <returns>return the new instantiator</returns>
                /// <param name="imlFragment">a valid IML string</param>
-               public Instantiator CreateITorFromIMLFragment (string imlFragment) {                    
+               public Instantiator CreateITorFromIMLFragment (string imlFragment) {
                        return Instantiator.CreateFromImlFragment (this, imlFragment);
                }
                /// <summary>
@@ -1034,7 +1064,7 @@ namespace Crow
                                }
                                _focusedWidget = value;
 
-                               NotifyValueChanged ("FocusedWidget", _focusedWidget);                           
+                               NotifyValueChanged ("FocusedWidget", _focusedWidget);
                                if (_focusedWidget != null)
                                        _focusedWidget.HasFocus = true;
                        }
@@ -1047,7 +1077,7 @@ namespace Crow
                /// Once in that queue, that means that the layouting of obj and childs have succeed,
                /// the next step when dequeued will be clipping registration</summary>
                public void EnqueueForRepaint(Widget g)
-               {                       
+               {
                        lock (ClippingMutex) {
                                if (g.IsQueueForClipping)
                                        return;
@@ -1086,7 +1116,7 @@ namespace Crow
 
                        if (!Monitor.TryEnter (UpdateMutex))
                                return;
-                       
+
                        DbgLogger.StartEvent (DbgEvtType.Update);
                        PerformanceMeasure.Begin (PerformanceMeasure.Kind.Update);
 
@@ -1105,7 +1135,7 @@ namespace Crow
 
                                if (!clipping.IsEmpty) {
                                        if (ctx == null) {
-                                               using (ctx = new Context (surf)) 
+                                               using (ctx = new Context (surf))
                                                        processDrawing (ctx);
                                        }else
                                                processDrawing (ctx);
@@ -1116,8 +1146,8 @@ namespace Crow
                                        if (!vkCtx.render ())
                                                ProcessResize (new Rectangle (0,0,(int)vkCtx.width, (int)vkCtx.height));
                                }
-#endif                 
-                               
+#endif
+
                        } finally {
 
                                PerformanceMeasure.End (PerformanceMeasure.Kind.Update);
@@ -1130,7 +1160,7 @@ namespace Crow
                }
 #if VKVG
                void resizeVulkanContext () {
-                       
+
 
 
                }
@@ -1191,8 +1221,8 @@ namespace Crow
 
                        ctx.ClipPreserve ();
                        ctx.Operator = Operator.Clear;
-                       ctx.Fill ();                    
-                       ctx.Operator = Operator.Over;                   
+                       ctx.Fill ();
+                       ctx.Operator = Operator.Over;
                }
                bool solidBackground = false;
                public bool SolidBackground {
@@ -1210,10 +1240,10 @@ namespace Crow
                /// repainted. If it contains also clip rectangles, its cache will be update, or if not cached a full redraw will take place</summary>
                protected virtual void processDrawing(Context ctx){
                        DbgLogger.StartEvent (DbgEvtType.ProcessDrawing);
-                       
-                       PerformanceMeasure.Begin (PerformanceMeasure.Kind.Drawing);                             
 
-#if VKVG                               
+                       PerformanceMeasure.Begin (PerformanceMeasure.Kind.Drawing);
+
+#if VKVG
                        clear (ctx);
 #else
                        ctx.PushGroup ();
@@ -1221,7 +1251,7 @@ namespace Crow
                        if (SolidBackground)
                                clear (ctx);
 #endif
-                       
+
                        for (int i = GraphicTree.Count -1; i >= 0 ; i--){
                                Widget p = GraphicTree[i];
                                if (!p.IsVisible)
@@ -1234,7 +1264,7 @@ namespace Crow
                                ctx.Restore ();
                        }
 
-                       
+
                        if (lastDragImageBounds != DragImageBounds) {
                                DirtyRect += lastDragImageBounds;
                                ctx.Save ();
@@ -1245,7 +1275,7 @@ namespace Crow
                                DirtyRect += DragImageBounds;
                                IsDirty = true;
                        }
-       
+
 
 #if DEBUG_CLIP_RECTANGLE
                        ctx.LineWidth = 1;
@@ -1253,7 +1283,7 @@ namespace Crow
                        for (int i = 0; i < clipping.NumRectangles; i++)
                                ctx.Rectangle(clipping.GetRectangle(i));
                        ctx.Stroke ();
-                       
+
 #endif
 
 #if VKVG
@@ -1268,18 +1298,18 @@ namespace Crow
 
                        surf.Flush ();
 #endif
-                       
+
                        clipping.Reset ();
 
                        PerformanceMeasure.End (PerformanceMeasure.Kind.Drawing);
                        IsDirty = true;
-                       
+
 #if !VKVG
                        drawTextCursor (ctx);
 #endif
 
                        debugHighlightFocus (ctx);
-                       
+
                        DbgLogger.EndEvent (DbgEvtType.ProcessDrawing, true);
                }
                #endregion
@@ -1359,14 +1389,14 @@ namespace Crow
                                                break;
                                        if (newW.AlwaysOnTop || !w.AlwaysOnTop)
                                                break;
-                                       
+
                                        ptr++;
                                }
                        }
 
                        lock (UpdateMutex)
                                GraphicTree.Insert (ptr, g);
-                       
+
                        g.RegisterForLayouting (LayoutingType.Sizing | LayoutingType.ArrangeChildren);
 
                        return g;
@@ -1449,7 +1479,7 @@ namespace Crow
 
                /// <summary>
                /// Resize the interface. This function should be called by the host
-               /// when window resize event occurs. 
+               /// when window resize event occurs.
                /// </summary>
                /// <param name="bounds">bounding box of the interface</param>
                public virtual void ProcessResize(Rectangle bounds){
@@ -1574,7 +1604,7 @@ namespace Crow
                public MouseCursor MouseCursor {
                        get => cursor;
                        set {
-                       
+
                                if (value == cursor)
                                        return;
                                cursor = value;
@@ -1597,13 +1627,13 @@ namespace Crow
                                default:
                                        currentCursor = XCursor.Create (this, cursor);
                                        break;
-                               }                                
-                               
+                               }
+
                                currentCursor.Set (hWin);
                                //MouseCursorChanged.Raise (this,new MouseCursorChangedEventArgs(cursor));
                        }
                }
-               
+
                Point stickyMouseDelta = default;
                internal Widget stickedWidget = null;
 
@@ -1663,11 +1693,11 @@ namespace Crow
                                if (HoverOrDropTarget != null) {
                                        resetTooltip ();
 
-                                       //check topmost graphicobject first                             
+                                       //check topmost graphicobject first
                                        Widget topContainer = HoverOrDropTarget;
                                        while (topContainer.LogicalParent is Widget w)
-                                               topContainer = w;                                       
-                                       
+                                               topContainer = w;
+
                                        int indexOfTopContainer = GraphicTree.IndexOf (topContainer);
                                        if (indexOfTopContainer != 0) {
                                                for (int i = 0; i < indexOfTopContainer; i++) {//check all top containers that are at a higher level
@@ -1704,7 +1734,7 @@ namespace Crow
                                        } else {
                                                if (DragAndDropInProgress && dragndropHover == DragAndDropOperation.DropTarget)
                                                        DragAndDropOperation.DropTarget.onDragLeave (this, DragAndDropOperation);
-                                               //seek upward from last focused graph obj's     
+                                               //seek upward from last focused graph obj's
                                                while (HoverOrDropTarget.FocusParent != null) {
                                                        if (!DragAndDropInProgress)
                                                                HoverWidget.onMouseLeave (this, e);
@@ -1716,7 +1746,7 @@ namespace Crow
                                                                else
                                                                        HoverWidget.onMouseMove (this, e);
                                                                return true;
-                                                       }                                               
+                                                       }
                                                }
                                        }
                                }
@@ -1762,7 +1792,7 @@ namespace Crow
 
                                lastMouseDownEvent = new MouseButtonEventArgs (MousePosition.X, MousePosition.Y, button, InputAction.Press);
 
-                               if (HoverWidget == null) 
+                               if (HoverWidget == null)
                                        return false;
 
                                HoverWidget.onMouseDown (this, lastMouseDownEvent);
@@ -1787,7 +1817,7 @@ namespace Crow
                                mouseRepeatTimer.Reset ();
                                lastMouseDownEvent = null;
 
-                               if (DragAndDropInProgress) {                            
+                               if (DragAndDropInProgress) {
                                        if (DragAndDropOperation.DropTarget != null)
                                                DragAndDropOperation.DragSource.onDrop (this, DragAndDropOperation);
                                        else
@@ -1805,7 +1835,7 @@ namespace Crow
 
                                _activeWidget.onMouseUp (_activeWidget, new MouseButtonEventArgs (MousePosition.X, MousePosition.Y, button, InputAction.Release));
 
-                               if (_activeWidget == null) {                                    
+                               if (_activeWidget == null) {
                                        DbgLogger.SetMsg (DbgEvtType.MouseUp, "[BUG]Mystery reset of _activeWidget");
                                        return true;
                                }
@@ -1819,7 +1849,7 @@ namespace Crow
                                //                      if (!lastActive.MouseIsIn (Mouse.Position)) {
                                //                              ProcessMouseMove (Mouse.X, Mouse.Y);
                                //                      }
-                               
+
                                return true;
                        } finally {
                                DbgLogger.EndEvent (DbgEvtType.MouseUp);
@@ -1879,7 +1909,7 @@ namespace Crow
                <HorizontalStack Height='Fit'>
                        <Label Text='TotalWidgetActive:' Width='50%'/>
                        <Label Text='{TotalWidgetActive}' TextAlignment='Right'/>
-               </HorizontalStack>              
+               </HorizontalStack>
                <HorizontalStack Height='Fit'>
                        <Label Text='TotalWidgetInGraphicTree:' Width='50%'/>
                        <Label Text='{TotalWidgetInGraphicTree}' TextAlignment='Right'/>
@@ -1889,7 +1919,7 @@ namespace Crow
                                ").DataSource = this;
                        }
 #endif
-                       
+
                        //Keyboard.SetKeyState((Crow.Key)Key,true);
                        lastKeyDownEvt = new KeyEventArgs (key, true);
 
@@ -1965,8 +1995,8 @@ namespace Crow
                }
                void ToolTipContainer_LayoutChanged (object sender, LayoutingEventArgs e)
                {
-                       Widget ttc = sender as Widget;                          
-                                       
+                       Widget ttc = sender as Widget;
+
                        //tooltip container datasource is the widget triggering the tooltip
                        Rectangle r = ttc?.DataSource is Widget w ? ScreenCoordinates (w.Slot) : ClientRectangle;
 
@@ -2037,7 +2067,7 @@ namespace Crow
                                ctxMenuContainer.BubbleMouseEvent = DeviceEventType.None;
                                ctxMenuContainer.LogicalParent = go;
                                ctxMenuContainer.DataSource = go;
-                               
+
 
                                PutOnTop (ctxMenuContainer, true);
                        }
@@ -2046,7 +2076,7 @@ namespace Crow
 
                        //OnMouseMove (MousePosition.X, MousePosition.Y);
                        HoverWidget = ctxMenuContainer;
-                       ctxMenuContainer.onMouseEnter (ctxMenuContainer, new MouseMoveEventArgs (MousePosition.X, MousePosition.Y, 0, 0));                                              
+                       ctxMenuContainer.onMouseEnter (ctxMenuContainer, new MouseMoveEventArgs (MousePosition.X, MousePosition.Y, 0, 0));
                }
                #endregion
 
@@ -2100,7 +2130,8 @@ namespace Crow
                        set { throw new NotImplementedException (); }
                }
 
-               public Rectangle ClientRectangle => clientRectangle; 
+               public Rectangle ClientRectangle => clientRectangle;
+               public Rectangle GetClientRectangleForChild (ILayoutable child) => clientRectangle;
                public Interface HostContainer => this;
 
                public Rectangle getSlot () => ClientRectangle;
index aa77839e4ea6630d17d6486a79dae2d72790b7dc..c61e97f285a55ca61f93a8a4eba54f13b89985c7 100644 (file)
@@ -39,7 +39,7 @@ namespace Crow
                Enum enumValue;
                UInt32 bitFieldExcludeMask;
                Type enumType;
-               bool enumTypeIsBitsfield;
+               bool enumTypeIsBitsfield, forceRadioButton;
                string rbStyle, iconsPrefix, iconsExtension;            
                #endregion
 
@@ -72,7 +72,7 @@ namespace Crow
                /// </summary>
                [DefaultValue (null)]
                public string RadioButtonStyle {
-                       get { return rbStyle; }
+                       get => rbStyle;
                        set {
                                if (rbStyle == value)
                                        return;
@@ -82,6 +82,21 @@ namespace Crow
                        }
                }
                /// <summary>
+               /// if enum has the 'Flag' attribte, CheckBox will be used. RadioButton may still be forced by
+               /// setting 'ForceRadioButton'='true'
+               /// </summary>
+               /// <value></value>
+               [DefaultValue (false)]
+               public bool ForceRadioButton {
+                       get => forceRadioButton;
+                       set {
+                               if (forceRadioButton == value)
+                                       return;
+                               forceRadioButton = value;
+                               NotifyValueChangedAuto (forceRadioButton);
+                       }
+               }
+               /// <summary>
                /// use to define the colors of the 3d border
                /// </summary>
                [DefaultValue(null)]
index 5ae3ac367d4ff32d02379a853be514e2a6471880..a605f02d87ec821e195fe9cf485a9e66f836d473 100644 (file)
@@ -104,7 +104,7 @@ namespace Crow {
                                        }
                                        d += c.Slot.Height + Spacing;
                                }
-                       }                       
+                       }
                        DbgLogger.EndEvent(DbgEvtType.GOComputeChildrenPositions);
                }
                Widget stretchedGO = null;
@@ -126,10 +126,10 @@ namespace Crow {
                protected void setChildWidth (Widget w, int newW) {
                        if (w.MaximumSize.Width > 0)
                                newW = Math.Min (newW, w.MaximumSize.Width);
-                               
+
                        if (newW == w.Slot.Width)
                                return;
-                       
+
                        w.Slot.Width = newW;
                        w.IsDirty = true;
                        w.LayoutChanged -= OnChildLayoutChanges;
@@ -141,7 +141,7 @@ namespace Crow {
                protected void setChildHeight (Widget w, int newH) {
                        if (w.MaximumSize.Height > 0)
                                newH = Math.Min (newH, w.MaximumSize.Height);
-                               
+
                        if (newH == w.Slot.Height)
                                return;
 
@@ -153,14 +153,14 @@ namespace Crow {
                        w.LastSlots.Height = w.Slot.Height;
                        DbgLogger.SetMsg(DbgEvtType.GOAdjustStretchedGo, $"new height={newH}");
                }
-               internal void adjustStretchedGo (LayoutingType lt) {                    
+               internal void adjustStretchedGo (LayoutingType lt) {
                        if (stretchedGO == null)
                                return;
                        //Console.WriteLine ($"adjust stretched go: {stretchedGO} {lt}");
                        DbgLogger.StartEvent(DbgEvtType.GOAdjustStretchedGo, this);
                        if (lt == LayoutingType.Width)
                                setChildWidth (stretchedGO, Math.Max (
-                                       ClientRectangle.Width - contentSize.Width - Spacing * (Children.Count - 1),     stretchedGO.MinimumSize.Width));                                
+                                       ClientRectangle.Width - contentSize.Width - Spacing * (Children.Count - 1),     stretchedGO.MinimumSize.Width));
                        else
                                setChildHeight (stretchedGO, Math.Max (
                                        ClientRectangle.Height - contentSize.Height - Spacing * (Children.Count - 1), stretchedGO.MinimumSize.Height));
@@ -248,7 +248,7 @@ namespace Crow {
                        }else if (child.Height == Measure.Stretched)
                                child.RegisterForLayouting (LayoutingType.Height);
                        else
-                               contentSize.Height += child.LastSlots.Height;                   
+                               contentSize.Height += child.LastSlots.Height;
                }
                public override void RemoveChild (Widget child) {
                        if (child != stretchedGO) {
index 879f305c2859c0ce35213ab6573f688acaad970b..1412284380312605fb4453bdce0f10e6f7109ffe 100644 (file)
@@ -40,33 +40,33 @@ namespace Crow
        /// excedental child (above grid sizing) are ignored
        /// and invisible child keep their place in the grid
        /// </summary>
-    public class Grid : Group
-    {
+       public class Grid : Group
+       {
                #region CTOR
                protected Grid () : base(){}
                public Grid(Interface iface) : base(iface)
-               {            
+               {
                }
                #endregion
 
                #region Private fields
-        int _spacing;
+               int _spacing;
                int _columnCount;
                int _rowCount;
                #endregion
 
                #region Public Properties
-        [DefaultValue(2)]
-        public int Spacing
-        {
+               [DefaultValue(2)]
+               public int Spacing
+               {
                        get { return _spacing; }
-            set { _spacing = value; }
-        }
-        [DefaultValue(2)]
-        public virtual int ColumnCount
-        {
-            get { return _columnCount; }
-            set { 
+                       set { _spacing = value; }
+               }
+               [DefaultValue(2)]
+               public virtual int ColumnCount
+               {
+                       get { return _columnCount; }
+                       set {
                                if (_columnCount == value)
                                        return;
 
@@ -75,12 +75,12 @@ namespace Crow
                                NotifyValueChangedAuto (ColumnCount);
                                this.RegisterForLayouting (LayoutingType.ArrangeChildren);
                        }
-        }
+               }
                [DefaultValue(2)]
                public virtual int RowCount
                {
                        get { return _rowCount; }
-                       set { 
+                       set {
                                if (_rowCount == value)
                                        return;
 
@@ -91,10 +91,10 @@ namespace Crow
                        }
                }
                public virtual int CaseWidth {
-                       get { return (Slot.Width - (ColumnCount - 1) * Spacing) / ColumnCount; }
+                       get => (Slot.Width - (ColumnCount - 1) * Spacing) / ColumnCount;
                }
                public virtual int CaseHeight {
-                       get { return (Slot.Height - (RowCount - 1) * Spacing) / RowCount; }
+                       get => (Slot.Height - (RowCount - 1) * Spacing) / RowCount;
                }
 
                #endregion
@@ -151,14 +151,14 @@ namespace Crow
                {
                        RegisteredLayoutings &= (~layoutType);
 
-                       if (layoutType == LayoutingType.ArrangeChildren) {                              
+                       if (layoutType == LayoutingType.ArrangeChildren) {
 
                                ComputeChildrenPositions ();
 
                                //if no layouting remains in queue for item, registre for redraw
                                if (RegisteredLayoutings == LayoutingType.None && IsDirty)
                                        IFace.EnqueueForRepaint (this);
-                               
+
                                return true;
                        }
 
@@ -166,6 +166,6 @@ namespace Crow
                }
                #endregion
 
-    
+
        }
 }
index f13f335ae833ca3f492dd36d2f62d12913d2a7a9..90ff4e648eecb485800345c201b3490cde6a7e4d 100644 (file)
@@ -58,7 +58,7 @@ namespace Crow
                                return;
                        }
                        childrenRWLock.EnterWriteLock ();
-                       try {   
+                       try {
                                g.Parent = this;
                                Children.Insert (idx, g);
                        } finally {
@@ -74,8 +74,8 @@ namespace Crow
                                tallestChild = g;
                                contentSize.Height = g.LastSlots.Height;
                        }
-                       
-                       g.LayoutChanged += OnChildLayoutChanges;                        
+
+                       g.LayoutChanged += OnChildLayoutChanges;
                        g.RegisterForLayouting (LayoutingType.Sizing | LayoutingType.ArrangeChildren);
                }
                public override void ClearChildren()
@@ -106,10 +106,10 @@ namespace Crow
                                if (Children.Count > 0) {
                                        if (lt == LayoutingType.Width) {
                                                //if (largestChild == null)
-                                                       searchLargestChild ();                                  
+                                                       searchLargestChild ();
                                        } else {
                                                //if (tallestChild == null)
-                                                       searchTallestChild ();                                  
+                                                       searchTallestChild ();
                                        }
                                }
                                return base.measureRawSize (lt);
@@ -119,7 +119,7 @@ namespace Crow
                }
 
                public override void OnLayoutChanges (LayoutingType layoutType)
-               {                       
+               {
                        /*if (!IsVisible)
                                return;*/
                        base.OnLayoutChanges (layoutType);
@@ -223,7 +223,7 @@ namespace Crow
                                if (largestChild == null && !forceMeasure)
                                        searchLargestChild (true);
                        } finally {
-                               childrenRWLock.ExitReadLock ();                         
+                               childrenRWLock.ExitReadLock ();
                                DbgLogger.EndEvent (DbgEvtType.GOSearchLargestChild);
                        }
                }
@@ -270,8 +270,8 @@ namespace Crow
                                                total += 1 + child.ChildCount;
                                        return total;
                                } finally {
-                                       childrenRWLock.ExitReadLock ();                         
-                               }                               
+                                       childrenRWLock.ExitReadLock ();
+                               }
                        }
                }
 #endif
index c91486687e1d95b0a81c4e6421c543325c1aa10b..18cd2ccf9edb19feb13c7410a9a356d101c5b019 100644 (file)
@@ -16,6 +16,7 @@ namespace Crow
                ILayoutable LogicalParent { get; set; }
 
                Rectangle ClientRectangle { get; }
+               Rectangle GetClientRectangleForChild (ILayoutable child);
                Rectangle getSlot();
 
                bool ArrangeChildren { get; }
index c712cb3de95e3ad4edfdfe08a166cbf31de0ded3..babd4d591638f6939c12d43f079bd906aa9f1589 100644 (file)
@@ -49,7 +49,7 @@ namespace Crow
 
                public static Column Parse (string str) {
                        if (string.IsNullOrEmpty (str))
-                               return null;                            
+                               return null;
                        Column c = new Column();
                        string[] tmp = str.Split (',');
                        c.Caption = tmp[0];
@@ -95,7 +95,7 @@ namespace Crow
                        for (int i = 0; i < HeaderRow.Children.Count; i++) {
                                if (row.Children.Count <= i)
                                        continue;
-                               setRowCellWidth (row.Children[i], HeaderRow.Children[i].Slot.Width);                            
+                               setRowCellWidth (row.Children[i], HeaderRow.Children[i].Slot.Width);
                                row.Children[i].Slot.X = HeaderRow.Children[i].Slot.X;
                        }
                }
@@ -158,8 +158,8 @@ namespace Crow
                                        row.Margin = rowsMargin;
                                childrenRWLock.ExitReadLock ();
                        }
-               }               
-               //int lineWidth;                
+               }
+               //int lineWidth;
                public ObservableList<Column> Columns {
                        get => columns;
                        set {
@@ -174,7 +174,7 @@ namespace Crow
                                columns = value;
 
                                if (columns != null) {
-                                       createHeaderRow ();                                     
+                                       createHeaderRow ();
                                        columns.ListAdd += Ol_AddColumn;
                                        columns.ListAdd += Ol_RemoveColumn;
                                }
@@ -192,7 +192,7 @@ namespace Crow
                        if (Columns == null || headerCellITor == null)
                                return;
                        HeaderRow = new HorizontalStack(IFace, "TableHeaderRow") {Spacing = ColumnSpacing};
-                       InsertChild (0, HeaderRow);                     
+                       InsertChild (0, HeaderRow);
                        foreach (Column c in Columns) {
                                Widget cell = headerCellITor.CreateInstance();
                                cell.LayoutChanged += onHeaderCell_LayoutChanges;
@@ -200,7 +200,7 @@ namespace Crow
                                cell.DataSource = c;
                        }
                }
-               
+
                void Ol_AddColumn (object sender, ListChangedEventArg e) {
                        HeaderRow.InsertChild (e.Index, headerCellITor.CreateInstance());
                        HeaderRow.DataSource = e.Element;
@@ -217,7 +217,7 @@ namespace Crow
                                Widget g = sender as Widget;
                                int cIdx = HeaderRow.Children.IndexOf (g);
                                if (cIdx < Columns.Count &&  Columns[cIdx].Width.IsFit)
-                                       searchLargestChildInColumn (cIdx);                              
+                                       searchLargestChildInColumn (cIdx);
                                childrenRWLock.EnterReadLock ();
                                for (int i = 1; i < Children.Count; i++) {
                                        TableRow row = Children[i] as TableRow;
@@ -244,13 +244,13 @@ namespace Crow
                }
                protected void setRowCellWidth (Widget w, int newW) {
                        if (newW == w.Slot.Width)
-                               return;                 
+                               return;
                        w.Slot.Width = newW;
                        w.IsDirty = true;
                        w.OnLayoutChanges (LayoutingType.Width);
                        w.LastSlots.Width = w.Slot.Width;
                        w.RegisterForRedraw ();
-               }               
+               }
 
                public override void ClearChildren()
                {
@@ -267,7 +267,7 @@ namespace Crow
                        childrenRWLock.EnterReadLock ();
                        try {
                                c.LargestChild = null;
-                               int largestWidth = 0;   
+                               int largestWidth = 0;
                                for (int i = 1; i < Children.Count; i++) {
                                        TableRow row = Children[i] as TableRow;
                                        if (!row.IsVisible || row.Children.Count <= i)
@@ -290,15 +290,15 @@ namespace Crow
                        //HeaderRow.adjustStretchedGo (LayoutingType.Width);
 
                }
-               int splitIndex = -1;            
-               const int minColumnSize = 10;           
+               int splitIndex = -1;
+               const int minColumnSize = 10;
                public override void onMouseMove(object sender, MouseMoveEventArgs e)
                {
-                       
+
                        if (Columns != null && ColumnSpacing > 0 && Columns.Count > 0) {
                                Point m = ScreenPointToLocal (e.Position);
-                               if (IFace.IsDown (Glfw.MouseButton.Left) && splitIndex >= 0) {                                  
-                                       int splitPos = (int)(0.5 * ColumnSpacing + m.X);                                        
+                               if (IFace.IsDown (Glfw.MouseButton.Left) && splitIndex >= 0) {
+                                       int splitPos = (int)(0.5 * ColumnSpacing + m.X);
                                        if (splitPos > HeaderRow.Children[splitIndex].Slot.Left + minColumnSize && splitPos < HeaderRow.Children[splitIndex+1].Slot.Right - minColumnSize) {
                                                Columns[splitIndex+1].Width = HeaderRow.Children[splitIndex+1].Slot.Right - splitPos;
                                                splitPos -= ColumnSpacing;
@@ -306,9 +306,9 @@ namespace Crow
                                                HeaderRow.RegisterForLayouting (LayoutingType.ArrangeChildren);
                                                e.Handled = true;
                                        }
-                                       //Console.WriteLine ($"left:{HeaderRow.Children[splitIndex].Slot.Left} right:{HeaderRow.Children[splitIndex+1].Slot.Right} splitPos:{splitPos} m:{m}");                         
+                                       //Console.WriteLine ($"left:{HeaderRow.Children[splitIndex].Slot.Left} right:{HeaderRow.Children[splitIndex+1].Slot.Right} splitPos:{splitPos} m:{m}");
                                } else {
-                                       splitIndex = -1;                                        
+                                       splitIndex = -1;
                                        for (int i = 0; i < Columns.Count - 1; i++)
                                        {
                                                Rectangle r = HeaderRow.Children[i].Slot;
@@ -327,7 +327,7 @@ namespace Crow
                                }
                        }
                        base.onMouseMove(sender, e);
-               }               
+               }
 
 
                protected override void onDraw (Context gr) {
@@ -338,7 +338,7 @@ namespace Crow
                        if (Columns != null && columns.Count > 0 && HeaderRow != null) {
 
                                Rectangle cb = ClientRectangle;
-                                                       
+
                                Foreground.SetAsSource (IFace, gr, cb);
                                if (BorderLineWidth > 0) {
                                        gr.LineWidth = BorderLineWidth;
@@ -348,7 +348,7 @@ namespace Crow
                                double x = 0;
                                if (VerticalLineWidth > 0) {
                                        gr.LineWidth = VerticalLineWidth;
-                                       x = cb.Left + HeaderRow.Margin + 0.5 * ColumnSpacing + HeaderRow.Children[0].Slot.Width;// - 0.5 * VerticalLineWidth;                           
+                                       x = cb.Left + HeaderRow.Margin + 0.5 * ColumnSpacing + HeaderRow.Children[0].Slot.Width;// - 0.5 * VerticalLineWidth;
                                        for (int i = 1; i < HeaderRow.Children.Count ; i++)
                                        {
                                                gr.MoveTo (x, cb.Y);
@@ -369,11 +369,11 @@ namespace Crow
                                        }
                                        gr.Stroke ();
                                }
-                               
+
                        }
 
                        DbgLogger.EndEvent (DbgEvtType.GODraw);
-               }                       
+               }
 
        }
 }
index 2c6db331668f4a3c093d31fd75a30f30d517f746..70370b7b21654777b1d8c33ed83d9ea41581b70e 100644 (file)
@@ -35,7 +35,7 @@ namespace Crow
                public event EventHandler<EventArgs> ChildrenCleared;
                #endregion
                public override void ChildrenLayoutingConstraints(ILayoutable layoutable, ref LayoutingType layoutType)
-                       => layoutType &= (~(LayoutingType.X|LayoutingType.Width));              
+                       => layoutType &= (~(LayoutingType.X|LayoutingType.Width));
 
                public Table Table => Parent as Table;
                internal Widget tallestChild = null;
@@ -46,10 +46,10 @@ namespace Crow
                        }
                        childrenRWLock.EnterWriteLock ();
 
-                       try {                           
+                       try {
                                g.Parent = this;
                                Children.Insert (idx, g);
-                       } finally {                     
+                       } finally {
                                childrenRWLock.ExitWriteLock ();
                        }
 
@@ -58,7 +58,7 @@ namespace Crow
                                contentSize.Height = g.LastSlots.Height;
                        }
 
-                       
+
                        g.LayoutChanged += OnChildLayoutChanges;
                        g.RegisterForLayouting (LayoutingType.Sizing | LayoutingType.ArrangeChildren);
                }
@@ -76,7 +76,7 @@ namespace Crow
                                Children.Remove(child);
                                child.Parent = null;
                                child.LogicalParent = null;
-                       } finally {                     
+                       } finally {
                                childrenRWLock.ExitWriteLock ();
                        }
 
@@ -108,14 +108,14 @@ namespace Crow
                public override int measureRawSize (LayoutingType lt)
                {
                        DbgLogger.StartEvent(DbgEvtType.GOMeasure, this);
-                       try {                   
+                       try {
                                if (lt == LayoutingType.Height && Children.Count > 0 && tallestChild == null)
-                                       searchTallestChild ();                                  
+                                       searchTallestChild ();
                                return base.measureRawSize (lt);
                        } finally {
-                               DbgLogger.EndEvent(DbgEvtType.GOMeasure);       
+                               DbgLogger.EndEvent(DbgEvtType.GOMeasure);
                        }
-               }               
+               }
                public override void OnLayoutChanges (LayoutingType layoutType)
                {
                        base.OnLayoutChanges (layoutType);
@@ -134,7 +134,7 @@ namespace Crow
                                        childrenRWLock.ExitReadLock ();
                                }
                        }
-               }               
+               }
                public virtual void OnChildLayoutChanges (object sender, LayoutingEventArgs arg)
                {
                        DbgLogger.StartEvent(DbgEvtType.GOOnChildLayoutChange, this);
index 24aaa695567f1ae8b43d2e490414980521163a8d..c114fb3f91c48ea58eb6ac1a6831280617ae81ef 100644 (file)
@@ -48,7 +48,7 @@ namespace Crow
                        BindingFlags.Instance | BindingFlags.NonPublic);
                static MethodInfo miDesignAddValLoc = typeof(Widget).GetMethod("design_add_iml_location",
                        BindingFlags.Instance | BindingFlags.NonPublic);
-               
+
                public volatile bool design_HasChanged = false;
                public string design_id;
                public int design_line;
@@ -60,7 +60,7 @@ namespace Crow
                //public Dictionary<string,FileLocation> design_iml_locations = new Dictionary<string, FileLocation>();
                public Dictionary<string,FileLocation> design_style_locations = new Dictionary<string, FileLocation>();
 
-               internal void design_add_style_location (string memberName, string path, int line, int col) {                   
+               internal void design_add_style_location (string memberName, string path, int line, int col) {
                        if (design_style_locations.ContainsKey(memberName)){
                                System.Diagnostics.Debug.WriteLine ("default value localtion already set for {0}{1}.{2}", this.GetType().Name, this.design_id, memberName);
                                return;
@@ -74,7 +74,7 @@ namespace Crow
 //                     }
 //                     design_iml_locations.Add(memberName, new FileLocation(path,line,col));
 //             }
-                       
+
                public virtual bool FindByDesignID(string designID, out Widget go){
                        go = null;
                        if (this.design_id == designID){
@@ -107,7 +107,7 @@ namespace Crow
                public virtual void getIML(XmlDocument doc, XmlNode parentElem) {
                        if (this.design_isTGItem)
                                return;
-                       
+
                        XmlElement xe = doc.CreateElement(this.GetType().Name);
 
                        foreach (KeyValuePair<string,string> kv in design_iml_values) {
@@ -119,7 +119,7 @@ namespace Crow
                        parentElem.AppendChild (xe);
                }
                public Surface CreateIcon (int dragIconSize = 32) {
-#if VKVG                       
+#if VKVG
                        Surface di = new Surface (IFace.vkvgDevice, dragIconSize, dragIconSize);
 #else
                        ImageSurface di = new ImageSurface (Format.Argb32, dragIconSize, dragIconSize);
@@ -140,19 +140,19 @@ namespace Crow
                        }
                        return di;
                }
-        public string DesignName {
-            get { return GetType ().Name + design_id; }
-        }
+               public string DesignName {
+                       get { return GetType ().Name + design_id; }
+               }
 #endif
 
                #region IDisposable implementation
                protected bool disposed = false;
 
-               public void Dispose(){  
-                       Dispose(true);  
-                       GC.SuppressFinalize(this);  
-               }  
-               ~Widget(){                      
+               public void Dispose(){
+                       Dispose(true);
+                       GC.SuppressFinalize(this);
+               }
+               ~Widget(){
                        Dispose(false);
                }
                protected virtual void Dispose(bool disposing){
@@ -180,7 +180,7 @@ namespace Crow
                        disposed = true;
 #if DEBUG_STATS
                        TotalWidgetDisposed++;
-#endif                 
+#endif
 
                        DbgLogger.EndEvent (DbgEvtType.Disposing);
                }
@@ -205,7 +205,7 @@ namespace Crow
                #region IValueChange implementation
                /// <summary>
                /// Raise to notify that the value of a property has changed, the binding system
-               /// rely mainly on this event. the member name may not be present in the class, this is 
+               /// rely mainly on this event. the member name may not be present in the class, this is
                /// used in **propertyless** bindings, this allow to raise custom named events without needing
                /// to create an new one in the class or a new property.
                /// </summary>
@@ -368,14 +368,14 @@ namespace Crow
                                parent = value;
                                Slot = LastSlots = default(Rectangle);
                                parentRWLock.ExitWriteLock();
-                                                                       
+
                                onParentChanged (this, e);
                        }
                }
                /// <summary>
                /// Mouse routing need to go back to logical parent for popups
                /// </summary>
-               internal Widget FocusParent => (parent is Interface ? LogicalParent : parent) as Widget; 
+               internal Widget FocusParent => (parent is Interface ? LogicalParent : parent) as Widget;
 
                [XmlIgnore]public ILayoutable LogicalParent {
                        get { return logicalParent == null ? Parent : logicalParent; }
@@ -399,6 +399,7 @@ namespace Crow
                                return cb;
                        }
                }
+               public virtual Rectangle GetClientRectangleForChild (ILayoutable child) => ClientRectangle;
                /// <summary>
                /// Compute rectangle position on surface of the context. It ma be the first cached surface in parenting chain,
                /// or the top backend surface if no cached widget is part of the current widget tree.
@@ -423,7 +424,7 @@ namespace Crow
                public virtual Rectangle ScreenCoordinates (Rectangle r){
                        try {
                                return
-                                       Parent.ScreenCoordinates(r) + Parent.getSlot().Position + Parent.ClientRectangle.Position;                              
+                                       Parent.ScreenCoordinates(r) + Parent.getSlot().Position + Parent.ClientRectangle.Position;
                        } catch (Exception ex) {
                                Debug.WriteLine (ex);
                                return default(Rectangle);
@@ -700,7 +701,7 @@ namespace Crow
                [XmlIgnore]public virtual Measure HeightPolicy { get {
                                return Height.IsFit ? Measure.Fit : Measure.Stretched; } }
                /// <summary>
-               /// Indicate that this object may received focus or not, if not focusable all the descendants are 
+               /// Indicate that this object may received focus or not, if not focusable all the descendants are
                /// affected.
                /// </summary>
                [DesignCategory ("Behaviour")][DefaultValue(false)]
@@ -730,9 +731,9 @@ namespace Crow
                                        onUnfocused (this, null);
                                NotifyValueChangedAuto (hasFocus);
                        }
-               }               
+               }
                /// <summary>
-               /// true if this control is active, this means that mouse has been pressed in it and not yet released. It could 
+               /// true if this control is active, this means that mouse has been pressed in it and not yet released. It could
                /// be used for other two states periferic action.
                /// </summary>
                [XmlIgnore]public virtual bool IsActive {
@@ -760,8 +761,8 @@ namespace Crow
                                isHover = value;
 
                                if (isHover) {
-                                       if (stickyMouseEnabled && stickyMouse > 0) 
-                                               IFace.stickedWidget = this;                                                                                     
+                                       if (stickyMouseEnabled && stickyMouse > 0)
+                                               IFace.stickedWidget = this;
                                        Hover.Raise (this, null);
                                }
 
@@ -807,8 +808,8 @@ namespace Crow
                                        return;
                                stickyMouse = value;
                                NotifyValueChangedAuto (stickyMouse);
-            }
-        }
+                       }
+               }
                /// <summary>
                /// Boolean for enabling or not the sticky mouse mechanic
                /// </summary>
@@ -820,8 +821,8 @@ namespace Crow
                                        return;
                                stickyMouseEnabled = value;
                                NotifyValueChangedAuto (stickyMouseEnabled);
-            }
-        }
+                       }
+               }
                /// <summary>
                /// Determine Cursor when mouse is Hover.
                /// </summary>
@@ -858,7 +859,7 @@ namespace Crow
                                NotifyValueChangedAuto (background);
                                RegisterForRedraw ();
                                if (background is SolidColor sc && sc.Equals (Colors.Clear))
-                                       clearBackground = true;                         
+                                       clearBackground = true;
                        }
                }
                /// <summary>
@@ -931,23 +932,23 @@ namespace Crow
                /// </summary>
                [DesignCategory ("Appearance")][DefaultValue(true)]
                public virtual bool IsVisible {
-                       get => isVisible; 
+                       get => isVisible;
                        set {
                                if (value == isVisible)
                                        return;
 
-                               isVisible = value;                              
-                               
+                               isVisible = value;
+
                                /*if (!isVisible)
                                        unshownPostActions ();
                                RegisterForLayouting (LayoutingType.Sizing);*/
 
-                               if (isVisible){                                                                         
+                               if (isVisible){
                                        IsDirty = true;
                                } else {
-                                       unshownPostActions ();                                  
+                                       unshownPostActions ();
                                }
-                               RegisterForLayouting(LayoutingType.Sizing);                             
+                               RegisterForLayouting(LayoutingType.Sizing);
 
                                NotifyValueChangedAuto (isVisible);
                        }
@@ -1164,7 +1165,7 @@ namespace Crow
                        string styleKey = style;
                        if (!string.IsNullOrEmpty (style)) {
                                if (IFace.Styling.ContainsKey (style))
-                                       styling.Add (IFace.Styling [style]);                            
+                                       styling.Add (IFace.Styling [style]);
                        }
                        //check the whole type hierarchy for styling
                        Type styleType = thisType;
@@ -1196,7 +1197,7 @@ namespace Crow
 
                        dm = new DynamicMethod("dyn_loadDefValues", null, new Type[] { typeof (object) }, thisType, true);
 
-            il = dm.GetILGenerator(256);
+                       il = dm.GetILGenerator(256);
                        il.DeclareLocal(typeof (object));//store root
                        il.Emit(OpCodes.Nop);
                        //set local GraphicObject to root object passed as 1st argument
@@ -1208,9 +1209,9 @@ namespace Crow
                                if (!getDefaultEvent(ei, styling, out expression))
                                        continue;
                                //TODO:dynEventHandler could be cached somewhere, maybe a style instanciator class holding the styling delegate and bound to it.
-                               foreach (string exp in expression.Split (';')) {                                        
+                               foreach (string exp in expression.Split (';')) {
                                //foreach (string exp in CompilerServices.splitOnSemiColumnOutsideAccolades(expression)) {
-                                       
+
                                        string trimed = exp.Trim();
                                        if (trimed.StartsWith ("{", StringComparison.Ordinal)){
                                                il.Emit (OpCodes.Ldloc_0);//load this as 1st arg of event Add
@@ -1338,9 +1339,9 @@ namespace Crow
 #endregion
 
                public virtual Widget FindByName(string nameToFind)
-                       => string.Equals(nameToFind, name, StringComparison.Ordinal) ? this : null;             
+                       => string.Equals(nameToFind, name, StringComparison.Ordinal) ? this : null;
                public virtual T FindByType<T> () //where T : Widget
-                       => this is T t? t : default(T);         
+                       => this is T t? t : default(T);
                public virtual bool Contains(Widget goToFind){
                        return false;
                }
@@ -1386,7 +1387,7 @@ namespace Crow
                                allowDrop = value;
                                NotifyValueChanged ("AllowDrop", allowDrop);
                        }
-               }               
+               }
                /// <summary>
                /// Semicolon separated list of accepted types as dropped widget.
                /// </summary>
@@ -1443,17 +1444,17 @@ namespace Crow
                        IsDragged = true;
                        StartDrag.Raise (this, IFace.DragAndDropOperation);
                        #if DEBUG_DRAGNDROP
-                       Debug.WriteLine(this.ToString() + " : START DRAG => " + e.ToString());                  
+                       Debug.WriteLine(this.ToString() + " : START DRAG => " + e.ToString());
                        #endif
                }
-               protected virtual void onDragEnter (object sender, DragDropEventArgs e){                        
-                       e.DropTarget = this;                    
+               protected virtual void onDragEnter (object sender, DragDropEventArgs e){
+                       e.DropTarget = this;
                        DragEnter.Raise (this, e);
                        #if DEBUG_DRAGNDROP
                        Debug.WriteLine(this.ToString() + " : DRAG Enter => " + e.ToString());
                        #endif
                }
-               public virtual void onDragLeave (object sender, DragDropEventArgs e){                   
+               public virtual void onDragLeave (object sender, DragDropEventArgs e){
                        DragLeave.Raise (this, e);
 #if DEBUG_DRAGNDROP
                        Debug.WriteLine (this.ToString () + " : DRAG Leave => " + e.ToString ());
@@ -1470,7 +1471,7 @@ namespace Crow
                        Debug.WriteLine(this.ToString() + " : END DRAG => " + e.ToString());
 #endif
                }
-               public virtual void onDrop (object sender, DragDropEventArgs e){                        
+               public virtual void onDrop (object sender, DragDropEventArgs e){
                        IsDragged = false;
                        Drop.Raise (this, e);
                        //e.DropTarget.onDragLeave (this, e);//raise drag leave in target
@@ -1478,7 +1479,7 @@ namespace Crow
                        Debug.WriteLine(this.ToString() + " : DROP => " + e.ToString());
 #endif
                }
-               public bool IsDropTarget => IFace.DragAndDropOperation?.DropTarget == this;             
+               public bool IsDropTarget => IFace.DragAndDropOperation?.DropTarget == this;
                #endregion
 
                #region Queuing
@@ -1489,7 +1490,7 @@ namespace Crow
                        DbgLogger.StartEvent (DbgEvtType.GOClippingRegistration, this);
 
                        parentRWLock.EnterReadLock ();
-                       if (parent != null) {                                   
+                       if (parent != null) {
                                parent.RegisterClip (LastPaintedSlot);
                                parent.RegisterClip (Slot);
                        }else {
@@ -1513,7 +1514,7 @@ namespace Crow
                                //we register clip in the parent, if it's dirty, all children will be redrawn
                                if (IsDirty && CacheEnabled) {
                                        DbgLogger.SetMsg (DbgEvtType.GORegisterClip, $"regclip canceled Dirty:{IsDirty} Cached:{CacheEnabled}");
-                                       return;                 
+                                       return;
                                }
                                Rectangle cb = ClientRectangle;
                                Rectangle  r = clip + cb.Position;
@@ -1523,18 +1524,18 @@ namespace Crow
                                        r.Height -= r.Bottom - cb.Bottom;*/
                                if (r.Width < 0 || r.Height < 0){
                                        DbgLogger.SetMsg (DbgEvtType.GORegisterClip, $"regclip canceled size w:{r.Width} h:{r.Height}");
-                                       return;                 
+                                       return;
                                }
                                if (cacheEnabled)
                                        Clipping.UnionRectangle (r);
                                if (Parent == null){
                                        DbgLogger.SetMsg (DbgEvtType.GORegisterClip, "clip chain aborded (no parent)");
-                                       return;                 
+                                       return;
                                }
                                /*Widget p = Parent as Widget;
                                if (p?.IsDirty == true && p?.CacheEnabled == true){
                                        Console.WriteLine ($"parent.regclip canceled p.Dirty:{p?.IsDirty} Cached:{p?.CacheEnabled}: {this.ToString()}");
-                                       return;                 
+                                       return;
                                }*/
                                Parent.RegisterClip (r + Slot.Position);
                        } finally {
@@ -1551,7 +1552,7 @@ namespace Crow
                        }
                        DbgLogger.StartEvent(DbgEvtType.GORegisterForGraphicUpdate, this);
 
-                       IsDirty = true;                 
+                       IsDirty = true;
                        if (Width.IsFit || Height.IsFit)
                                RegisterForLayouting (LayoutingType.Sizing);
                        else
@@ -1579,7 +1580,7 @@ namespace Crow
                /// of the drawing could take place in the onDraw method, and the markers (single line, rectangle, ...)
                /// could be drawn in the Paint method. Such widget must have 'CacheEnabled=true' and to simply update the
                /// markers without a full redraw, just call 'RegisterForRepaint'.
-               /// 
+               ///
                /// </remark>
                public void RegisterForRepaint () {
                        if (RequiredLayoutings == LayoutingType.None)// && !IsDirty)
@@ -1597,7 +1598,7 @@ namespace Crow
                                return lt == LayoutingType.Width ?
                                        contentSize.Width + 2 * margin : contentSize.Height + 2 * margin;
                        } finally {
-                               DbgLogger.EndEvent(DbgEvtType.GOMeasure);       
+                               DbgLogger.EndEvent(DbgEvtType.GOMeasure);
                        }
                }
 
@@ -1614,14 +1615,14 @@ namespace Crow
                        }
                        return false;
                }
-               protected bool stretchedInFit (LayoutingType lt) {                      
-                       
+               protected bool stretchedInFit (LayoutingType lt) {
+
                        if (Parent == null)
                                return false;
                        Widget p = Parent as Widget;
                        if (lt == LayoutingType.Width) {
                                if (!Width.IsRelativeToParent)
-                                       return false;                           
+                                       return false;
                                while (p.Width.IsRelativeToParent) {
                                        p = p.Parent as Widget;
                                        if (p == null)
@@ -1630,7 +1631,7 @@ namespace Crow
                                return p.Width.IsFit;
                        }
                        if (!Height.IsRelativeToParent)
-                               return false;                   
+                               return false;
                        while (p.Height.IsRelativeToParent) {
                                p = p.Parent as Widget;
                                if (p == null)
@@ -1646,10 +1647,10 @@ namespace Crow
                /// arrange children in the x direction.
                /// </summary>
                /// <param name="layoutable">The children that is calling the constraints</param>
-               /// <param name="layoutType">The currently registering layouting types</param>          
+               /// <param name="layoutType">The currently registering layouting types</param>
                public virtual void ChildrenLayoutingConstraints(ILayoutable layoutable, ref LayoutingType layoutType){ }
                /// <summary> Query a layouting for the type pass as parameter, redraw only if layout changed. </summary>
-               
+
                internal ReaderWriterLockSlim layoutMutex = new ReaderWriterLockSlim (LockRecursionPolicy.SupportsRecursion);
                public virtual void RegisterForLayouting(LayoutingType layoutType){
                        if (disposed) {
@@ -1657,7 +1658,7 @@ namespace Crow
                                return;
                        }
 
-                       parentRWLock.EnterReadLock ();                  
+                       parentRWLock.EnterReadLock ();
 
                        try {
                                if (Parent == null)
@@ -1666,14 +1667,14 @@ namespace Crow
                                layoutMutex.EnterWriteLock ();
 
                                try {
-                                               
-                               
+
+
                                        //prevent queueing same LayoutingType for this
                                        layoutType &= (~RegisteredLayoutings);
 
                                        if (layoutType == LayoutingType.None)
                                                return;
-                                       
+
                                        //dont set position for stretched item
                                        if (Width == Measure.Stretched)
                                                layoutType &= (~LayoutingType.X);
@@ -1694,7 +1695,7 @@ namespace Crow
 
                                        RequiredLayoutings |= layoutType;
                                } finally {
-                                       layoutMutex.ExitWriteLock ();                                   
+                                       layoutMutex.ExitWriteLock ();
                                }
 
                                DbgLogger.StartEvent (DbgEvtType.GOLockLayouting, this);
@@ -1760,7 +1761,7 @@ namespace Crow
                                if (left == 0) {
 
                                        if (Parent.RequiredLayoutings.HasFlag (LayoutingType.Width) ||
-                                           RequiredLayoutings.HasFlag (LayoutingType.Width))
+                                               RequiredLayoutings.HasFlag (LayoutingType.Width))
                                                return false;
 
                                        switch (horizontalAlignment) {
@@ -1768,10 +1769,10 @@ namespace Crow
                                                Slot.X = 0;
                                                break;
                                        case HorizontalAlignment.Right:
-                                               Slot.X = Parent.ClientRectangle.Width - Slot.Width;
+                                               Slot.X = Parent.GetClientRectangleForChild(this).Width - Slot.Width;
                                                break;
                                        case HorizontalAlignment.Center:
-                                               Slot.X = Parent.ClientRectangle.Width / 2 - Slot.Width / 2;
+                                               Slot.X = Parent.GetClientRectangleForChild(this).Width / 2 - Slot.Width / 2;
                                                break;
                                        }
                                } else
@@ -1790,7 +1791,7 @@ namespace Crow
                                if (top == 0) {
 
                                        if (Parent.RequiredLayoutings.HasFlag (LayoutingType.Height) ||
-                                           RequiredLayoutings.HasFlag (LayoutingType.Height))
+                                               RequiredLayoutings.HasFlag (LayoutingType.Height))
                                                return false;
 
                                        switch (verticalAlignment) {
@@ -1798,10 +1799,10 @@ namespace Crow
                                                Slot.Y = 0;
                                                break;
                                        case VerticalAlignment.Bottom:
-                                               Slot.Y = Parent.ClientRectangle.Height - Slot.Height;
+                                               Slot.Y = Parent.GetClientRectangleForChild(this).Height - Slot.Height;
                                                break;
                                        case VerticalAlignment.Center:
-                                               Slot.Y = Parent.ClientRectangle.Height / 2 - Slot.Height / 2;
+                                               Slot.Y = Parent.GetClientRectangleForChild(this).Height / 2 - Slot.Height / 2;
                                                break;
                                        }
                                } else
@@ -1825,19 +1826,19 @@ namespace Crow
                                        } else if (Parent.RegisteredLayoutings.HasFlag (LayoutingType.Width))
                                                return false;
                                        else if (Width == Measure.Stretched)
-                                               Slot.Width = Parent.ClientRectangle.Width;
+                                               Slot.Width = Parent.GetClientRectangleForChild(this).Width;
                                        else
-                                               Slot.Width = (int)Math.Round ((double)(Parent.ClientRectangle.Width * Width) / 100.0);
+                                               Slot.Width = (int)Math.Round ((double)(Parent.GetClientRectangleForChild(this).Width * Width) / 100.0);
 
                                        if (Slot.Width < 0)
                                                return false;
 
                                        //size constrain
                                        if (Slot.Width < minimumSize.Width)
-                                               Slot.Width = minimumSize.Width;                                         
+                                               Slot.Width = minimumSize.Width;
                                        else if (maximumSize.Width > 0 && Slot.Width > maximumSize.Width)
                                                Slot.Width = maximumSize.Width;
-                                       
+
                                } else
                                        Slot.Width = 0;
 
@@ -1859,9 +1860,9 @@ namespace Crow
                                        } else if (Parent.RegisteredLayoutings.HasFlag (LayoutingType.Height))
                                                return false;
                                        else if (Height == Measure.Stretched)
-                                               Slot.Height = Parent.ClientRectangle.Height;
+                                               Slot.Height = Parent.GetClientRectangleForChild(this).Height;
                                        else
-                                               Slot.Height = (int)Math.Round ((double)(Parent.ClientRectangle.Height * Height) / 100.0);
+                                               Slot.Height = (int)Math.Round ((double)(Parent.GetClientRectangleForChild(this).Height * Height) / 100.0);
 
                                        if (Slot.Height < 0)
                                                return false;
@@ -1871,7 +1872,7 @@ namespace Crow
                                                Slot.Height = minimumSize.Height;
                                         else if (maximumSize.Height > 0 && Slot.Height > maximumSize.Height)
                                                Slot.Height = maximumSize.Height;
-                                       
+
                                } else
                                        Slot.Height = 0;
 
@@ -1906,7 +1907,7 @@ namespace Crow
                #region Rendering
                /// <summary> This is the common overridable drawing routine to create new widget </summary>
                protected virtual void onDraw(Context gr)
-               {                       
+               {
                        DbgLogger.StartEvent(DbgEvtType.GODraw, this);
 
                        Rectangle rBack = new Rectangle (Slot.Size);
@@ -1947,12 +1948,12 @@ namespace Crow
                                onDraw (gr);
                        }
 
-                       IsDirty = false;                        
+                       IsDirty = false;
 
                        DbgLogger.EndEvent (DbgEvtType.GORecreateCache);
                }
                protected void paintCache(Context ctx, Rectangle rb) {
-                       DbgLogger.StartEvent(DbgEvtType.GOPaintCache, this);    
+                       DbgLogger.StartEvent(DbgEvtType.GOPaintCache, this);
                        if (clearBackground) {
                                ctx.Operator = Operator.Clear;
                                ctx.Rectangle (rb);
@@ -1960,18 +1961,18 @@ namespace Crow
                                ctx.Operator = Operator.Over;
                        }
 
-                       ctx.SetSource (bmp, rb.X, rb.Y);                        
+                       ctx.SetSource (bmp, rb.X, rb.Y);
                        ctx.Paint ();
 #if VKVG
                        ctx.Flush ();
 #endif
-                       DbgLogger.EndEvent(DbgEvtType.GOPaintCache);    
+                       DbgLogger.EndEvent(DbgEvtType.GOPaintCache);
                }
                protected virtual void UpdateCache(Context ctx){
-                       DbgLogger.StartEvent(DbgEvtType.GOUpdateCache, this);                   
+                       DbgLogger.StartEvent(DbgEvtType.GOUpdateCache, this);
                        paintCache (ctx, Slot + Parent.ClientRectangle.Position);
                        DbgLogger.AddEvent (DbgEvtType.GOResetClip, this);
-                       Clipping.Reset ();                      
+                       Clipping.Reset ();
                        DbgLogger.EndEvent (DbgEvtType.GOUpdateCache);
                }
                /// <summary> Chained painting routine on the parent context of the actual cached version
@@ -1996,13 +1997,13 @@ namespace Crow
 #endif
                                DbgLogger.AddEvent (DbgEvtType.Warning);
                                DbgLogger.EndEvent (DbgEvtType.GOPaint);
-                               return; 
+                               return;
                        }
                        //lock (this) {
                                if (cacheEnabled) {
                                        if (Slot.Width > Interface.MaxCacheSize || Slot.Height > Interface.MaxCacheSize)
                                                cacheEnabled = false;
-                               }                               
+                               }
 
                                if (cacheEnabled) {
                                        if (IsDirty) {
@@ -2010,8 +2011,8 @@ namespace Crow
                                                paintCache (ctx, Slot + Parent.ClientRectangle.Position);
                                        }else
                                                UpdateCache (ctx);
-                                       if (!IsEnabled)                                         
-                                               paintDisabled (ctx, Slot + Parent.ClientRectangle.Position);                                    
+                                       if (!IsEnabled)
+                                               paintDisabled (ctx, Slot + Parent.ClientRectangle.Position);
                                } else {
                                        Rectangle rb = Slot + Parent.ClientRectangle.Position;
                                        //ctx.Save ();
@@ -2027,7 +2028,7 @@ namespace Crow
                                        if (!IsEnabled)
                                                paintDisabled (ctx, rb);
 
-                               }                               
+                               }
 
                                LastPaintedSlot = Slot;
                        //}
@@ -2044,7 +2045,7 @@ namespace Crow
                }
                #endregion
 
-        #region Keyboard handling
+               #region Keyboard handling
                public virtual void onKeyDown(object sender, KeyEventArgs e){
                        if (KeyDown != null)
                                KeyDown.Invoke (this, e);
@@ -2063,7 +2064,7 @@ namespace Crow
                        else if (!e.Handled)
                                FocusParent?.onKeyPress (sender, e);
                }
-        #endregion
+               #endregion
 
                #region Mouse handling
                /// <summary>
@@ -2081,7 +2082,7 @@ namespace Crow
                        if (!parent.PointIsIn(ref m))
                                return false;
                        m -= (parent.getSlot().Position + parent.ClientRectangle.Position) ;
-                       return Slot.ContainsOrIsEqual (m);                                      
+                       return Slot.ContainsOrIsEqual (m);
                }
                public virtual bool MouseIsIn(Point m)
                        => (!(isVisible & IsEnabled) || IsDragged) ? false : PointIsIn (ref m);
@@ -2091,7 +2092,7 @@ namespace Crow
                                if (IFace.dragndropHover != this) {
                                        IFace.dragndropHover = this;
 #if DEBUG_DRAGNDROP
-                                       Debug.WriteLine($"DragNDropHover = {this.ToString()} AllowDrop:{AllowDrop}, {IFace.DragAndDropOperation.DragSource.AllowedDropTypes}");                 
+                                       Debug.WriteLine($"DragNDropHover = {this.ToString()} AllowDrop:{AllowDrop}, {IFace.DragAndDropOperation.DragSource.AllowedDropTypes}");
 #endif
 
                                        if (AllowDrop && AcceptDrop (IFace.DragAndDropOperation.DragSource))
@@ -2100,17 +2101,17 @@ namespace Crow
                        } else if (IFace.HoverWidget != this) {
                                onMouseEnter (this, e);
                                IFace.HoverWidget = this;
-                       }                       
+                       }
                }
                public virtual void onMouseMove (object sender, MouseMoveEventArgs e)
                {
-                       if (AllowDrag & IFace.IsDown (MouseButton.Left)) {                              
+                       if (AllowDrag & IFace.IsDown (MouseButton.Left)) {
                                onStartDrag (this, new DragDropEventArgs (this, FocusParent));
                                return;
                        }
 
                        if (MouseMove != null)
-                               MouseMove.Invoke (this, e);                     
+                               MouseMove.Invoke (this, e);
                        else if (!e.Handled && BubbleMouseEvent.HasFlag (DeviceEventType.MouseMove))
                                FocusParent?.onMouseMove (sender, e);
                }
@@ -2171,7 +2172,7 @@ namespace Crow
                /// <param name="sender">The Sender of the event</param>
                /// <param name="e">event arguments</param>
                public virtual void onMouseDoubleClick(object sender, MouseButtonEventArgs e){
-                       if (MouseDoubleClick != null)                   
+                       if (MouseDoubleClick != null)
                                MouseDoubleClick.Invoke (this, e);
                        else if (!e.Handled && BubbleMouseEvent.HasFlag (DeviceEventType.MouseClick))
                                FocusParent?.onMouseDoubleClick (sender, e);
@@ -2203,14 +2204,14 @@ namespace Crow
                        MouseEnter.Raise (this, e);
                }
                public virtual void onMouseLeave(object sender, MouseMoveEventArgs e)
-               {                       
+               {
                        MouseLeave.Raise (this, e);
                }
 
                #endregion
 
                protected virtual void onFocused(object sender, EventArgs e){
-                       DbgLogger.AddEvent (DbgEvtType.FocusedWidget, this);                    
+                       DbgLogger.AddEvent (DbgEvtType.FocusedWidget, this);
                        Focused.Raise (this, e);
                }
                protected virtual void onUnfocused(object sender, EventArgs e){
@@ -2256,7 +2257,7 @@ namespace Crow
                        string tmp ="";
 
                        if (Parent != null)
-                               tmp = Parent.ToString () + tmp;                 
+                               tmp = Parent.ToString () + tmp;
                        return string.IsNullOrEmpty(Name) ? tmp + "." + LogName : tmp + "." + Name;
                        //#endif
                }
@@ -2264,7 +2265,7 @@ namespace Crow
                /// Checks to handle when widget is removed from the visible graphic tree
                /// </summary>
                void unshownPostActions () {
-                       IsDirty = true;                 
+                       IsDirty = true;
 
                        /*if (parent is Widget p)
                                p.RegisterForGraphicUpdate();
@@ -2278,7 +2279,7 @@ namespace Crow
                        {
                                Debug.WriteLine($"[ERR]:unshownPostActions:{e}");
                        }
-                               
+
 
                        /*if (IFace.ActiveWidget != null) {
                                if (IsActive) {
@@ -2304,7 +2305,7 @@ namespace Crow
                                        IFace.OnMouseMove (IFace.MousePosition.X, IFace.MousePosition.Y);
                                }
                        }
-                       
+
                        /*Slot = default;
                        try
                        {
@@ -2313,7 +2314,7 @@ namespace Crow
                                if (LastSlots.Height > 0)
                                        OnLayoutChanges (LayoutingType.Height);
                                OnLayoutChanges (LayoutingType.X);
-                               OnLayoutChanges (LayoutingType.Y);                              
+                               OnLayoutChanges (LayoutingType.Y);
                        }
                        catch (System.Exception ex)
                        {
@@ -2321,7 +2322,8 @@ namespace Crow
                        }
                        LastSlots = default;
                        LastPaintedSlot = default;*/
-                       //Slot = LastSlots = default;                   
+                       //Slot = LastSlots = LastPaintedSlot = default;
+                       Slot = LastPaintedSlot = default;
                }
        }
 }
index 6540a305b2b4c0736e28dced3eda0dcde7d2e97c..a028c7d712e0c074557a405cc48af93ce1e72ce7 100644 (file)
@@ -172,7 +172,6 @@ namespace Crow
                        CMDMaximize = new Command ("Maximize", () => CurrentState = Status.Maximized, "#Crow.Icons.maximize.svg", allowedStates.HasFlag (Status.Maximized));
                        CMDNormalize = new Command ("Normalize", () => CurrentState = Status.Normal, "#Crow.Icons.normalize.svg", false);
                        CMDClose = new Command ("Close", close, "#Crow.Icons.exit2.svg", true);
-
                        Commands = new CommandGroup(CMDMinimize, CMDNormalize, CMDMaximize, CMDClose);
                }
 
index b91129b568c797253d643891c3abc5c15d63d063..81510eed5ec35a9adfd90b90bd10a8ae52769acb 100644 (file)
@@ -6,7 +6,7 @@
                <Authors>Jean-Philippe Bruyère</Authors>           
                <LangVersion>7.3</LangVersion>
                
-               <CrowVersion>0.9.5</CrowVersion>
+               <CrowVersion>0.9.6</CrowVersion>
                <CrowPackageVersion>$(CrowVersion)-beta</CrowPackageVersion>
 
                <!-- If you dont have a native libstb on your system, enable the managed version of stb here
@@ -18,7 +18,7 @@
                <CrowDebugLogEnabled>false</CrowDebugLogEnabled>
 
                <!-- Collect several statistics on widgets-->
-               <CrowDebugStatsEnabled>true</CrowDebugStatsEnabled>
+               <CrowDebugStatsEnabled>false</CrowDebugStatsEnabled>
 
                <!-- Used only by CrowIDE and CrowEdit-->
                <CrowDesignModeEnabled>false</CrowDesignModeEnabled>
index 22418f31624d141c6f82022fd3ce3251788e5635..c093d34599329b42b3aa66c3bcca475ef1129a42 100644 (file)
@@ -155,7 +155,7 @@ namespace Crow
                        lock (IFace.UpdateMutex) {
                                if (overlay == null) {
                                        overlay = IFace.LoadIMLFragment<ListBox>(@"
-                                               <ListBox Style='suggestionsListBox' Data='{Suggestions}' >
+                                               <ListBox Style='suggestionsListBox' Data='{Suggestions}' UseLoadingThread='False' >
                                                        <ItemTemplate>
                                                                <ListItem Height='Fit' Margin='0' Focusable='false' HorizontalAlignment='Left' 
                                                                                                Selected = '{Background=${ControlHighlight}}'
@@ -163,7 +163,7 @@ namespace Crow
                                                                        <Label Text='{}' HorizontalAlignment='Left' />
                                                                </ListItem>                                                     
                                                        </ItemTemplate>
-                                                       <ItemTemplate DataType='MemberInfo'>
+                                                       <ItemTemplate DataType='System.Reflection.MemberInfo'>
                                                                <ListItem Height='Fit' Margin='0' Focusable='false' HorizontalAlignment='Left' 
                                                                                                Selected = '{Background=${ControlHighlight}}'
                                                                                                Unselected = '{Background=Transparent}'>
@@ -172,7 +172,7 @@ namespace Crow
                                                                                <Label Text='{Name}' HorizontalAlignment='Left' />
                                                                        </HorizontalStack>
                                                                </ListItem>                                                     
-                                                       </ItemTemplate>
+                                                       </ItemTemplate>                                                 
                                                        <ItemTemplate DataType='Colors'>
                                                                <ListItem Height='Fit' Margin='0' Focusable='false' HorizontalAlignment='Left' 
                                                                                                Selected = '{Background=${ControlHighlight}}'
diff --git a/Samples/common/ui/Interfaces/Experimental/testGrid.crow b/Samples/common/ui/Interfaces/Experimental/testGrid.crow
new file mode 100644 (file)
index 0000000..1385acc
--- /dev/null
@@ -0,0 +1,6 @@
+<Grid ColumnCount="2" RowCount="2">
+       <Label/>
+       <Label/>
+       <Label/>
+       <Label/>
+</Grid>
\ No newline at end of file