From 4d1f3264dc4b4ddc211164712e0d2d654a913bb7 Mon Sep 17 00:00:00 2001 From: jpbruyere Date: Sat, 27 May 2017 18:35:01 +0200 Subject: [PATCH] c native GraphicObject implementation, work in progress --- Crow.csproj | 3 +- src/CompilerServices/CompilerServices.cs | 4 +- src/Enums.cs | 10 +- src/GraphicObjects/Border.cs | 4 +- src/GraphicObjects/ColorSelector.cs | 4 +- src/GraphicObjects/ComboBox.cs | 4 +- src/GraphicObjects/GenericStack.cs | 32 +- src/GraphicObjects/GraphicObject.cs | 456 ++++++++++-------- src/GraphicObjects/Grid.cs | 8 +- src/GraphicObjects/Group.cs | 30 +- src/GraphicObjects/HueSelector.cs | 4 +- src/GraphicObjects/ILayoutable.cs | 55 --- src/GraphicObjects/Label.cs | 4 +- src/GraphicObjects/Popper.cs | 30 +- src/GraphicObjects/PrivateContainer.cs | 16 +- src/GraphicObjects/SaturationValueSelector.cs | 4 +- src/GraphicObjects/Scroller.cs | 26 +- src/GraphicObjects/Slider.cs | 4 +- src/GraphicObjects/Splitter.cs | 28 +- src/GraphicObjects/TabItem.cs | 42 +- src/GraphicObjects/TabView.cs | 12 +- src/GraphicObjects/TemplatedGroup.cs | 6 +- src/GraphicObjects/TreeView.cs | 2 +- src/GraphicObjects/Window.cs | 34 +- src/GraphicObjects/Wrapper.cs | 60 +-- src/Interface.cs | 67 ++- src/LayoutingQueueItem.cs | 10 +- src/Measure.cs | 4 +- testDrm/TestCrow.cs | 22 +- testDrm/testDrm.csproj | 4 +- testDrm/ui/2.crow | 2 +- 31 files changed, 502 insertions(+), 489 deletions(-) delete mode 100644 src/GraphicObjects/ILayoutable.cs diff --git a/Crow.csproj b/Crow.csproj index 1c419008..767868b8 100644 --- a/Crow.csproj +++ b/Crow.csproj @@ -31,7 +31,7 @@ true full true - DEBUG_FOCUS0;DEBUG_LAYOUTING0;TRACE;DEBUG;__linux__;MEASURE_TIME;DEBUG_LOAD0;DEBUG_BINDING0;DEBUG_CLIP_RECTANGLE0 + DEBUG_FOCUS0;DEBUG_LAYOUTING0;TRACE;DEBUG;MEASURE_TIME;DEBUG_LOAD0;DEBUG_BINDING0;DEBUG_CLIP_RECTANGLE0 false @@ -60,7 +60,6 @@ - diff --git a/src/CompilerServices/CompilerServices.cs b/src/CompilerServices/CompilerServices.cs index 9961c52d..82f82817 100644 --- a/src/CompilerServices/CompilerServices.cs +++ b/src/CompilerServices/CompilerServices.cs @@ -795,8 +795,8 @@ namespace Crow /// true, if logical parents are not null /// Start Instance /// Levels to go upward - internal static ILayoutable goUpNbLevels(ILayoutable instance, int levelCount){ - ILayoutable tmp = instance; + internal static GraphicObject goUpNbLevels(GraphicObject instance, int levelCount){ + GraphicObject tmp = instance; int i = 0; while (tmp != null && i < levelCount) { tmp = tmp.LogicalParent; diff --git a/src/Enums.cs b/src/Enums.cs index 6249135b..bafea06f 100644 --- a/src/Enums.cs +++ b/src/Enums.cs @@ -37,7 +37,7 @@ namespace Crow Vertical } - public enum Alignment + public enum Alignment : byte { Top = 0x01, Left = 0x02, @@ -49,16 +49,16 @@ namespace Crow BottomRight = 0x0c, Center = 0x10 } - public enum HorizontalAlignment + public enum HorizontalAlignment : byte { + Center, Left, Right, - Center, } - public enum VerticalAlignment + public enum VerticalAlignment : byte { + Center, Top, Bottom, - Center, } } diff --git a/src/GraphicObjects/Border.cs b/src/GraphicObjects/Border.cs index 672d5ab8..51a597be 100644 --- a/src/GraphicObjects/Border.cs +++ b/src/GraphicObjects/Border.cs @@ -66,9 +66,9 @@ namespace Crow int tmp = base.measureRawSize (lt); return tmp < 0 ? tmp : tmp + 2 * BorderWidth; } - protected override void onDraw (Cairo.Context gr) + unsafe protected override void onDraw (Cairo.Context gr) { - Rectangle rBack = new Rectangle (Slot.Size); + Rectangle rBack = new Rectangle (nativeHnd->Slot.Size); //rBack.Inflate (-Margin); // if (BorderWidth > 0) diff --git a/src/GraphicObjects/ColorSelector.cs b/src/GraphicObjects/ColorSelector.cs index c9f3a198..56ae4a73 100644 --- a/src/GraphicObjects/ColorSelector.cs +++ b/src/GraphicObjects/ColorSelector.cs @@ -54,8 +54,8 @@ namespace Crow updateMouseLocalPos (e.Position); } - protected virtual void updateMouseLocalPos(Point mPos){ - Rectangle r = ScreenCoordinates (Slot); + unsafe protected virtual void updateMouseLocalPos(Point mPos){ + Rectangle r = ScreenCoordinates (nativeHnd->Slot); Rectangle cb = ClientRectangle; mousePos = mPos - r.Position; diff --git a/src/GraphicObjects/ComboBox.cs b/src/GraphicObjects/ComboBox.cs index 15b49dbe..d57ed23d 100644 --- a/src/GraphicObjects/ComboBox.cs +++ b/src/GraphicObjects/ComboBox.cs @@ -44,12 +44,12 @@ namespace Crow } } - public override void OnLayoutChanges (LayoutingType layoutType) + unsafe public override void OnLayoutChanges (LayoutingType layoutType) { base.OnLayoutChanges (layoutType); if (layoutType == LayoutingType.Width) - MinimumPopupSize = new Size (this.Slot.Width, minimumPopupSize.Height); + MinimumPopupSize = new Size (this.nativeHnd->Slot.Width, minimumPopupSize.Height); } } } diff --git a/src/GraphicObjects/GenericStack.cs b/src/GraphicObjects/GenericStack.cs index cecdaffd..8004e950 100644 --- a/src/GraphicObjects/GenericStack.cs +++ b/src/GraphicObjects/GenericStack.cs @@ -93,22 +93,22 @@ namespace Crow return base.measureRawSize (lt); } - public virtual void ComputeChildrenPositions() + unsafe public virtual void ComputeChildrenPositions() { int d = 0; if (Orientation == Orientation.Horizontal) { foreach (GraphicObject c in Children) { if (!c.Visible) continue; - c.Slot.X = d; - d += c.Slot.Width + Spacing; + c.nativeHnd->Slot.X = d; + d += c.nativeHnd->Slot.Width + Spacing; } } else { foreach (GraphicObject c in Children) { if (!c.Visible) continue; - c.Slot.Y = d; - d += c.Slot.Height + Spacing; + c.nativeHnd->Slot.Y = d; + d += c.nativeHnd->Slot.Height + Spacing; } } IsDirty = true; @@ -135,7 +135,7 @@ namespace Crow return base.UpdateLayout(layoutType); } - public override void OnChildLayoutChanges (object sender, LayoutingEventArgs arg) + unsafe public override void OnChildLayoutChanges (object sender, LayoutingEventArgs arg) { GraphicObject go = sender as GraphicObject; //Debug.WriteLine ("child layout change: " + go.LastSlots.ToString() + " => " + go.Slot.ToString()); @@ -146,12 +146,12 @@ namespace Crow if (stretchedGO == null && Width != Measure.Fit) stretchedGO = go; else if (stretchedGO != go) { - go.Slot.Width = 0; + go.nativeHnd->Slot.Width = 0; go.Width = Measure.Fit; return; } } else - contentSize.Width += go.Slot.Width - go.LastSlots.Width; + contentSize.Width += go.nativeHnd->Slot.Width - go.nativeHnd->LastSlot.Width; if (stretchedGO != null) { int newW = Math.Max ( @@ -159,8 +159,8 @@ namespace Crow stretchedGO.MinimumSize.Width); if (stretchedGO.MaximumSize.Width > 0) newW = Math.Min (newW, stretchedGO.MaximumSize.Width); - if (newW != stretchedGO.Slot.Width) { - stretchedGO.Slot.Width = newW; + if (newW != stretchedGO.nativeHnd->Slot.Width) { + stretchedGO.nativeHnd->Slot.Width = newW; stretchedGO.IsDirty = true; #if DEBUG_LAYOUTING Debug.WriteLine ("\tAdjusting Width of " + stretchedGO.ToString()); @@ -168,7 +168,7 @@ namespace Crow stretchedGO.LayoutChanged -= OnChildLayoutChanges; stretchedGO.OnLayoutChanges (LayoutingType.Width); stretchedGO.LayoutChanged += OnChildLayoutChanges; - stretchedGO.LastSlots.Width = stretchedGO.Slot.Width; + stretchedGO.nativeHnd->LastSlot.Width = stretchedGO.nativeHnd->Slot.Width; } } @@ -185,12 +185,12 @@ namespace Crow if (stretchedGO == null && Height != Measure.Fit) stretchedGO = go; else if (stretchedGO != go){ - go.Slot.Height = 0; + go.nativeHnd->Slot.Height = 0; go.Height = Measure.Fit; return; } } else - contentSize.Height += go.Slot.Height - go.LastSlots.Height; + contentSize.Height += go.nativeHnd->Slot.Height - go.nativeHnd->LastSlot.Height; if (stretchedGO != null) { int newH = Math.Max ( @@ -198,8 +198,8 @@ namespace Crow stretchedGO.MinimumSize.Height); if (stretchedGO.MaximumSize.Height > 0) newH = Math.Min (newH, stretchedGO.MaximumSize.Height); - if (newH != stretchedGO.Slot.Height) { - stretchedGO.Slot.Height = newH; + if (newH != stretchedGO.nativeHnd->Slot.Height) { + stretchedGO.nativeHnd->Slot.Height = newH; stretchedGO.IsDirty = true; #if DEBUG_LAYOUTING Debug.WriteLine ("\tAdjusting Height of " + stretchedGO.ToString()); @@ -207,7 +207,7 @@ namespace Crow stretchedGO.LayoutChanged -= OnChildLayoutChanges; stretchedGO.OnLayoutChanges (LayoutingType.Height); stretchedGO.LayoutChanged += OnChildLayoutChanges; - stretchedGO.LastSlots.Height = stretchedGO.Slot.Height; + stretchedGO.nativeHnd->LastSlot.Height = stretchedGO.nativeHnd->Slot.Height; } } diff --git a/src/GraphicObjects/GraphicObject.cs b/src/GraphicObjects/GraphicObject.cs index e7c22d9a..f8069337 100644 --- a/src/GraphicObjects/GraphicObject.cs +++ b/src/GraphicObjects/GraphicObject.cs @@ -35,30 +35,66 @@ using Cairo; using System.Linq; using System.Diagnostics; using System.IO; +using System.Runtime.InteropServices; namespace Crow { - public class GraphicObject : ILayoutable, IValueChange - { - internal static ulong currentUid = 0; - internal ulong uid = 0; - - Interface currentInterface = null; + [StructLayout(LayoutKind.Sequential)] + unsafe public struct NativeGO { + public NativeGO* Parent; + public int Left; + public int Top; + public Measure Width; + public Measure Height; + public int Margin; + public Size MinimumSize; + public Size MaximumSize; + byte visible; + public LayoutingType RegisteredLayoutings; + /// + /// Current size and position computed during layouting pass + /// + public Rectangle Slot; + /// + /// keep last slot components for each layouting pass to track + /// changes and trigger update of other component accordingly + /// + public Rectangle LastSlot; + /// + /// keep last slot painted on screen to clear traces if moved or resized + /// TODO: we should ensure the whole parsed widget tree is the last painted + /// version to clear effective oldslot if parents have been moved or resized. + /// IDEA is to add a ScreenCoordinates function that use only lastPaintedSlots + /// + public Rectangle LastPaintedSlot; + public VerticalAlignment VerticalAlignment; + public HorizontalAlignment HorizontalAlignment; - [XmlIgnore]public Interface CurrentInterface { - get { - if (currentInterface == null) { - currentInterface = Interface.CurrentInterface; - Initialize (); - } - return currentInterface; - } + unsafe public bool Visible { + get { return visible > 0; } set { - currentInterface = value; + if (value) + visible = 1; + else + visible = 0; } } + } + public class GraphicObject : IValueChange, IDisposable + { + #region PINVOKE + const string lib = "/home/jp/devel/testsharedlib/bin/Debug/libcrow.so"; + [DllImport(lib)] + unsafe static extern NativeGO* CreateGO(); + [DllImport(lib)] + unsafe static extern void DestroyGO(NativeGO* go); + #endregion - public Region Clipping = new Region(); + internal static ulong currentUid = 0; + internal ulong uid = 0; + + + unsafe internal NativeGO* nativeHnd; #region IValueChange implementation public event EventHandler ValueChanged; @@ -72,6 +108,9 @@ namespace Crow #region CTOR public GraphicObject () { + unsafe { + nativeHnd = CreateGO (); + } #if DEBUG uid = currentUid; currentUid++; @@ -88,27 +127,20 @@ namespace Crow loadDefaultValues (); } #region private fields - LayoutingType registeredLayoutings = LayoutingType.All; - ILayoutable logicalParent; - ILayoutable parent; + + Interface currentInterface = null; + GraphicObject logicalParent; + GraphicObject parent; string name; Fill background = Color.Transparent; Fill foreground = Color.White; Font font = "droid, 10"; - Measure width, height; - int left, top; double cornerRadius = 0; - int margin = 0; bool focusable = false; bool hasFocus = false; bool isActive = false; bool mouseRepeat; - protected bool isVisible = true; bool isEnabled = true; - VerticalAlignment verticalAlignment = VerticalAlignment.Center; - HorizontalAlignment horizontalAlignment = HorizontalAlignment.Center; - Size maximumSize = "0,0"; - Size minimumSize = "0,0"; bool cacheEnabled = false; bool clipToClientRect = true; protected object dataSource; @@ -118,21 +150,9 @@ namespace Crow #region public fields /// - /// Current size and position computed during layouting pass - /// - public Rectangle Slot = new Rectangle (); - /// - /// keep last slot components for each layouting pass to track - /// changes and trigger update of other component accordingly + /// The clipping rectangles list /// - public Rectangle LastSlots; - /// - /// keep last slot painted on screen to clear traces if moved or resized - /// TODO: we should ensure the whole parsed widget tree is the last painted - /// version to clear effective oldslot if parents have been moved or resized. - /// IDEA is to add a ScreenCoordinates function that use only lastPaintedSlots - /// - public Rectangle LastPaintedSlot; + public Region Clipping = new Region(); /// Prevent requeuing multiple times the same widget public bool IsQueueForRedraw = false; /// drawing Cache bitmap @@ -149,51 +169,53 @@ namespace Crow #endregion #region ILayoutable - [XmlIgnore]public LayoutingType RegisteredLayoutings { get { return registeredLayoutings; } set { registeredLayoutings = value; } } + [XmlIgnore]unsafe public LayoutingType RegisteredLayoutings { + get { return nativeHnd->RegisteredLayoutings; } set { nativeHnd->RegisteredLayoutings = value; } } //TODO: it would save the recurent cost of a cast in event bubbling if parent type was GraphicObject // or we could add to the interface the mouse events /// /// Parent in the graphic tree, used for rendering and layouting /// - [XmlIgnore]public virtual ILayoutable Parent { + [XmlIgnore]public virtual GraphicObject Parent { get { return parent; } set { if (parent == value) return; DataSourceChangeEventArgs e = new DataSourceChangeEventArgs (parent, value); - lock (this) + lock (this) { parent = value; + //nativeHnd->Parent = value?.nativeHnd; + } onParentChanged (this, e); } } - [XmlIgnore]public ILayoutable LogicalParent { + [XmlIgnore]public GraphicObject LogicalParent { get { return logicalParent == null ? Parent : logicalParent; } set { if (logicalParent == value) return; if (logicalParent != null) - (logicalParent as GraphicObject).DataSourceChanged -= onLogicalParentDataSourceChanged; + logicalParent.DataSourceChanged -= onLogicalParentDataSourceChanged; DataSourceChangeEventArgs dsce = new DataSourceChangeEventArgs (LogicalParent, null); logicalParent = value; dsce.NewDataSource = LogicalParent; if (logicalParent != null) - (logicalParent as GraphicObject).DataSourceChanged += onLogicalParentDataSourceChanged; + logicalParent.DataSourceChanged += onLogicalParentDataSourceChanged; onLogicalParentChanged (this, dsce); } } - [XmlIgnore]public virtual Rectangle ClientRectangle { + [XmlIgnore]unsafe public virtual Rectangle ClientRectangle { get { - Rectangle cb = Slot.Size; + Rectangle cb = nativeHnd->Slot.Size; cb.Inflate ( - Margin); return cb; } } public virtual Rectangle ContextCoordinates(Rectangle r){ - GraphicObject go = Parent as GraphicObject; - if (go == null) + if (Parent is Interface) return r + Parent.ClientRectangle.Position; - return go.CacheEnabled ? + return parent.CacheEnabled ? r + Parent.ClientRectangle.Position : Parent.ContextCoordinates (r); } @@ -201,7 +223,7 @@ namespace Crow return Parent.ScreenCoordinates(r) + Parent.getSlot().Position + Parent.ClientRectangle.Position; } - public virtual Rectangle getSlot () { return Slot;} + unsafe public virtual Rectangle getSlot () { return nativeHnd->Slot;} #endregion #region EVENT HANDLERS @@ -227,6 +249,18 @@ namespace Crow #endregion #region public properties + [XmlIgnore]public Interface CurrentInterface { + get { + if (currentInterface == null) { + currentInterface = Interface.CurrentInterface; + Initialize (); + } + return currentInterface; + } + set { + currentInterface = value; + } + } /// Random value placeholder [XmlAttributeAttribute] public object Tag { @@ -286,47 +320,51 @@ namespace Crow } } [XmlAttributeAttribute ()][DefaultValue(VerticalAlignment.Center)] - public virtual VerticalAlignment VerticalAlignment { - get { return verticalAlignment; } + unsafe public virtual VerticalAlignment VerticalAlignment { + get { return nativeHnd->VerticalAlignment; } set { - if (verticalAlignment == value) + if (nativeHnd->VerticalAlignment == value) return; - verticalAlignment = value; - NotifyValueChanged("VerticalAlignment", verticalAlignment); + nativeHnd->VerticalAlignment = value; + NotifyValueChanged("VerticalAlignment", nativeHnd->VerticalAlignment); RegisterForLayouting (LayoutingType.Y); } } [XmlAttributeAttribute()][DefaultValue(HorizontalAlignment.Center)] - public virtual HorizontalAlignment HorizontalAlignment { - get { return horizontalAlignment; } + unsafe public virtual HorizontalAlignment HorizontalAlignment { + get { return nativeHnd->HorizontalAlignment; } set { - if (horizontalAlignment == value) + if (nativeHnd->HorizontalAlignment == value) return; - horizontalAlignment = value; - NotifyValueChanged("HorizontalAlignment", horizontalAlignment); + nativeHnd->HorizontalAlignment = value; + NotifyValueChanged("HorizontalAlignment", nativeHnd->HorizontalAlignment); RegisterForLayouting (LayoutingType.X); } } [XmlAttributeAttribute()][DefaultValue(0)] public virtual int Left { - get { return left; } + get { unsafe { return nativeHnd->Left; } } set { - if (left == value) + if (Left == value) return; - left = value; - NotifyValueChanged ("Left", left); + unsafe { + nativeHnd->Left = value; + } + NotifyValueChanged ("Left", Left); this.RegisterForLayouting (LayoutingType.X); } } [XmlAttributeAttribute()][DefaultValue(0)] public virtual int Top { - get { return top; } + get { unsafe { return nativeHnd->Top; } } set { - if (top == value) + if (Top == value) return; - top = value; - NotifyValueChanged ("Top", top); + unsafe { + nativeHnd->Top = value; + } + NotifyValueChanged ("Top", Top); this.RegisterForLayouting (LayoutingType.Y); } } @@ -344,22 +382,21 @@ namespace Crow } } [XmlAttributeAttribute()][DefaultValue("Inherit")] - public virtual Measure Width { + unsafe public virtual Measure Width { get { - return width.Units == Unit.Inherit ? - Parent is GraphicObject ? (Parent as GraphicObject).WidthPolicy : - Measure.Stretched : width; + return nativeHnd->Width.Units == Unit.Inherit ? Parent == null ? + Measure.Stretched : Parent.WidthPolicy : nativeHnd->Width; } set { - if (width == value) + if (nativeHnd->Width == value) return; if (value.IsFixed) { if (value < MinimumSize.Width || (value > MaximumSize.Width && MaximumSize.Width > 0)) return; } Measure lastWP = WidthPolicy; - width = value; - NotifyValueChanged ("Width", width); + nativeHnd->Width = value; + NotifyValueChanged ("Width", nativeHnd->Width); if (WidthPolicy != lastWP) { NotifyValueChanged ("WidthPolicy", WidthPolicy); //contentSize in Stacks are only update on childLayoutChange, and the single stretched @@ -369,9 +406,9 @@ namespace Crow if (parent is GenericStack) {//TODO:check if I should test Group instead if ((parent as GenericStack).Orientation == Orientation.Horizontal) { if (lastWP == Measure.Fit) - (parent as GenericStack).contentSize.Width -= this.LastSlots.Width; + (parent as GenericStack).contentSize.Width -= nativeHnd->LastSlot.Width; else - (parent as GenericStack).contentSize.Width += this.LastSlots.Width; + (parent as GenericStack).contentSize.Width += nativeHnd->LastSlot.Width; } } } @@ -380,34 +417,32 @@ namespace Crow } } [XmlAttributeAttribute()][DefaultValue("Inherit")] - public virtual Measure Height { + unsafe public virtual Measure Height { get { - return height.Units == Unit.Inherit ? - Parent is GraphicObject ? (Parent as GraphicObject).HeightPolicy : - Measure.Stretched : height; + return nativeHnd->Height.Units == Unit.Inherit ? Parent == null ? + Measure.Stretched : Parent.HeightPolicy : nativeHnd->Height; } set { - if (height == value) + if (nativeHnd->Height == value) return; if (value.IsFixed) { if (value < MinimumSize.Height || (value > MaximumSize.Height && MaximumSize.Height > 0)) return; } Measure lastHP = HeightPolicy; - height = value; - NotifyValueChanged ("Height", height); + nativeHnd->Height = value; + NotifyValueChanged ("Height", nativeHnd->Height); if (HeightPolicy != lastHP) { NotifyValueChanged ("HeightPolicy", HeightPolicy); if (parent is GenericStack) { if ((parent as GenericStack).Orientation == Orientation.Vertical) { if (lastHP == Measure.Fit) - (parent as GenericStack).contentSize.Height -= this.LastSlots.Height; + (parent as GenericStack).contentSize.Height -= nativeHnd->LastSlot.Height; else - (parent as GenericStack).contentSize.Height += this.LastSlots.Height; + (parent as GenericStack).contentSize.Height += nativeHnd->LastSlot.Height; } } } - this.RegisterForLayouting (LayoutingType.Height); } } @@ -521,30 +556,33 @@ namespace Crow } [XmlAttributeAttribute()][DefaultValue(0)] public virtual int Margin { - get { return margin; } + get { unsafe { return nativeHnd->Margin; } } set { - if (value == margin) + if (value == Margin) return; - margin = value; - NotifyValueChanged ("Margin", margin); + unsafe { + nativeHnd->Margin = value; + } + NotifyValueChanged ("Margin", Margin); RegisterForGraphicUpdate (); } } [XmlAttributeAttribute][DefaultValue(true)] public virtual bool Visible { - get { return isVisible; } + get { unsafe { return nativeHnd->Visible;} } set { - if (value == isVisible) + if (value == Visible) return; - - isVisible = value; + unsafe { + nativeHnd->Visible = value; + } RegisterForLayouting (LayoutingType.Sizing); //trigger a mouse to handle possible hover changes //CurrentInterface.ProcessMouseMove (CurrentInterface.Mouse.X, CurrentInterface.Mouse.Y); - NotifyValueChanged ("Visible", isVisible); + NotifyValueChanged ("Visible", Visible); } } [XmlAttributeAttribute][DefaultValue(true)] @@ -565,29 +603,32 @@ namespace Crow RegisterForRedraw (); } } - [XmlAttributeAttribute()][DefaultValue("1,1")] + [XmlAttributeAttribute][DefaultValue("1,1")] public virtual Size MinimumSize { - get { return minimumSize; } + get { unsafe { return nativeHnd->MinimumSize;} } set { - if (value == minimumSize) + if (value == MinimumSize) return; - minimumSize = value; + unsafe { + nativeHnd->MinimumSize = value; + } - NotifyValueChanged ("MinimumSize", minimumSize); + NotifyValueChanged ("MinimumSize", MinimumSize); RegisterForLayouting (LayoutingType.Sizing); } } - [XmlAttributeAttribute()][DefaultValue("0,0")] + [XmlAttributeAttribute][DefaultValue("0,0")] public virtual Size MaximumSize { - get { return maximumSize; } + get { unsafe { return nativeHnd->MaximumSize;} } set { - if (value == maximumSize) + if (value == MaximumSize) return; + unsafe { + nativeHnd->MaximumSize = value; + } - maximumSize = value; - - NotifyValueChanged ("MaximumSize", maximumSize); + NotifyValueChanged ("MaximumSize", MaximumSize); RegisterForLayouting (LayoutingType.Sizing); } } @@ -612,8 +653,7 @@ namespace Crow get { return dataSource == null ? LogicalParent == null ? null : - LogicalParent is GraphicObject ? (LogicalParent as GraphicObject).DataSource : null : - dataSource; + LogicalParent.DataSource : dataSource; } } protected virtual void onLogicalParentDataSourceChanged(object sender, DataSourceChangeEventArgs e){ @@ -830,18 +870,18 @@ namespace Crow /// /// Register old and new slot for clipping /// - public virtual void ClippingRegistration(){ + unsafe public virtual void ClippingRegistration(){ IsQueueForRedraw = false; if (Parent == null) return; - Parent.RegisterClip (LastPaintedSlot); - Parent.RegisterClip (Slot); + Parent.RegisterClip (nativeHnd->LastPaintedSlot); + Parent.RegisterClip (nativeHnd->Slot); } /// /// Add clip rectangle to this.clipping and propagate up to root /// /// Clip rectangle - public virtual void RegisterClip(Rectangle clip){ + unsafe public virtual void RegisterClip(Rectangle clip){ Rectangle r = clip + ClientRectangle.Position; if (CacheEnabled && !IsDirty) Clipping.UnionRectangle (r); @@ -850,7 +890,7 @@ namespace Crow GraphicObject p = Parent as GraphicObject; if (p?.IsDirty == true && p?.CacheEnabled == true) return; - Parent.RegisterClip (r + Slot.Position); + Parent.RegisterClip (r + nativeHnd->Slot.Position); } /// Full update, taking care of sizing policy [MethodImpl(MethodImplOptions.AggressiveInlining)] @@ -902,8 +942,7 @@ namespace Crow layoutType &= (~LayoutingType.ArrangeChildren); //apply constraints depending on parent type - if (Parent is GraphicObject) - (Parent as GraphicObject).ChildrenLayoutingConstraints (ref layoutType); + Parent.ChildrenLayoutingConstraints (ref layoutType); // //prevent queueing same LayoutingType for this // layoutType &= (~RegisteredLayoutings); @@ -952,10 +991,10 @@ namespace Crow /// The redrawing will only be triggered if final slot size has changed /// true, if layouting was possible, false if conditions were not /// met and LQI has to be re-queued - public virtual bool UpdateLayout (LayoutingType layoutType) + unsafe public virtual bool UpdateLayout (LayoutingType layoutType) { //unset bit, it would be reset if LQI is re-queued - registeredLayoutings &= (~layoutType); + RegisteredLayoutings &= (~layoutType); switch (layoutType) { case LayoutingType.X: @@ -967,26 +1006,26 @@ namespace Crow switch (HorizontalAlignment) { case HorizontalAlignment.Left: - Slot.X = 0; + nativeHnd->Slot.X = 0; break; case HorizontalAlignment.Right: - Slot.X = Parent.ClientRectangle.Width - Slot.Width; + nativeHnd->Slot.X = Parent.ClientRectangle.Width - nativeHnd->Slot.Width; break; case HorizontalAlignment.Center: - Slot.X = Parent.ClientRectangle.Width / 2 - Slot.Width / 2; + nativeHnd->Slot.X = Parent.ClientRectangle.Width / 2 - nativeHnd->Slot.Width / 2; break; } } else - Slot.X = Left; - - if (LastSlots.X == Slot.X) + nativeHnd->Slot.X = Left; + + if (nativeHnd->LastSlot.X == nativeHnd->Slot.X) break; IsDirty = true; OnLayoutChanges (layoutType); - LastSlots.X = Slot.X; + nativeHnd->LastSlot.X = nativeHnd->Slot.X; break; case LayoutingType.Y: if (Top == 0) { @@ -997,103 +1036,103 @@ namespace Crow switch (VerticalAlignment) { case VerticalAlignment.Top://this could be processed even if parent Height is not known - Slot.Y = 0; + nativeHnd->Slot.Y = 0; break; case VerticalAlignment.Bottom: - Slot.Y = Parent.ClientRectangle.Height - Slot.Height; + nativeHnd->Slot.Y = Parent.ClientRectangle.Height - nativeHnd->Slot.Height; break; case VerticalAlignment.Center: - Slot.Y = Parent.ClientRectangle.Height / 2 - Slot.Height / 2; + nativeHnd->Slot.Y = Parent.ClientRectangle.Height / 2 - nativeHnd->Slot.Height / 2; break; } } else - Slot.Y = Top; + nativeHnd->Slot.Y = Top; - if (LastSlots.Y == Slot.Y) + if (nativeHnd->LastSlot.Y == nativeHnd->Slot.Y) break; IsDirty = true; OnLayoutChanges (layoutType); - LastSlots.Y = Slot.Y; + nativeHnd->LastSlot.Y = nativeHnd->Slot.Y; break; case LayoutingType.Width: if (Visible) { if (Width.IsFixed) - Slot.Width = Width; + nativeHnd->Slot.Width = Width; else if (Width == Measure.Fit) { - Slot.Width = measureRawSize (LayoutingType.Width); + nativeHnd->Slot.Width = measureRawSize (LayoutingType.Width); } else if (Parent.RegisteredLayoutings.HasFlag (LayoutingType.Width)) return false; else if (Width == Measure.Stretched) - Slot.Width = Parent.ClientRectangle.Width; + nativeHnd->Slot.Width = Parent.ClientRectangle.Width; else - Slot.Width = (int)Math.Round ((double)(Parent.ClientRectangle.Width * Width) / 100.0); + nativeHnd->Slot.Width = (int)Math.Round ((double)(Parent.ClientRectangle.Width * Width) / 100.0); - if (Slot.Width < 0) + if (nativeHnd->Slot.Width < 0) return false; //size constrain - if (Slot.Width < MinimumSize.Width) { - Slot.Width = MinimumSize.Width; + if (nativeHnd->Slot.Width < MinimumSize.Width) { + nativeHnd->Slot.Width = MinimumSize.Width; //NotifyValueChanged ("WidthPolicy", Measure.Stretched); - } else if (Slot.Width > MaximumSize.Width && MaximumSize.Width > 0) { - Slot.Width = MaximumSize.Width; + } else if (nativeHnd->Slot.Width > MaximumSize.Width && MaximumSize.Width > 0) { + nativeHnd->Slot.Width = MaximumSize.Width; //NotifyValueChanged ("WidthPolicy", Measure.Stretched); } } else - Slot.Width = 0; + nativeHnd->Slot.Width = 0; - if (LastSlots.Width == Slot.Width) + if (nativeHnd->LastSlot.Width == nativeHnd->Slot.Width) break; IsDirty = true; OnLayoutChanges (layoutType); - LastSlots.Width = Slot.Width; + nativeHnd->LastSlot.Width = nativeHnd->Slot.Width; break; case LayoutingType.Height: if (Visible) { if (Height.IsFixed) - Slot.Height = Height; + nativeHnd->Slot.Height = Height; else if (Height == Measure.Fit) { - Slot.Height = measureRawSize (LayoutingType.Height); + nativeHnd->Slot.Height = measureRawSize (LayoutingType.Height); } else if (Parent.RegisteredLayoutings.HasFlag (LayoutingType.Height)) return false; else if (Height == Measure.Stretched) - Slot.Height = Parent.ClientRectangle.Height; + nativeHnd->Slot.Height = Parent.ClientRectangle.Height; else - Slot.Height = (int)Math.Round ((double)(Parent.ClientRectangle.Height * Height) / 100.0); + nativeHnd->Slot.Height = (int)Math.Round ((double)(Parent.ClientRectangle.Height * Height) / 100.0); - if (Slot.Height < 0) + if (nativeHnd->Slot.Height < 0) return false; //size constrain - if (Slot.Height < MinimumSize.Height) { - Slot.Height = MinimumSize.Height; + if (nativeHnd->Slot.Height < MinimumSize.Height) { + nativeHnd->Slot.Height = MinimumSize.Height; //NotifyValueChanged ("HeightPolicy", Measure.Stretched); - } else if (Slot.Height > MaximumSize.Height && MaximumSize.Height > 0) { - Slot.Height = MaximumSize.Height; + } else if (nativeHnd->Slot.Height > MaximumSize.Height && MaximumSize.Height > 0) { + nativeHnd->Slot.Height = MaximumSize.Height; //NotifyValueChanged ("HeightPolicy", Measure.Stretched); } } else - Slot.Height = 0; + nativeHnd->Slot.Height = 0; - if (LastSlots.Height == Slot.Height) + if (nativeHnd->LastSlot.Height == nativeHnd->Slot.Height) break; IsDirty = true; OnLayoutChanges (layoutType); - LastSlots.Height = Slot.Height; + nativeHnd->LastSlot.Height = nativeHnd->Slot.Height; break; } //if no layouting remains in queue for item, registre for redraw - if (this.registeredLayoutings == LayoutingType.None && IsDirty) + if (RegisteredLayoutings == LayoutingType.None && IsDirty) CurrentInterface.EnqueueForRepaint (this); return true; @@ -1102,9 +1141,9 @@ namespace Crow #region Rendering /// This is the common overridable drawing routine to create new widget - protected virtual void onDraw(Context gr) + unsafe protected virtual void onDraw(Context gr) { - Rectangle rBack = new Rectangle (Slot.Size); + Rectangle rBack = new Rectangle (nativeHnd->Slot.Size); Background.SetAsSource (gr, rBack); CairoHelpers.CairoRectangle (gr, rBack, cornerRadius); @@ -1114,15 +1153,15 @@ namespace Crow /// /// Internal drawing context creation on a cached surface limited to slot size /// this trigger the effective drawing routine - protected virtual void RecreateCache () + unsafe protected virtual void RecreateCache () { - int stride = 4 * Slot.Width; + int stride = 4 * nativeHnd->Slot.Width; - int bmpSize = Math.Abs (stride) * Slot.Height; + int bmpSize = Math.Abs (stride) * nativeHnd->Slot.Height; bmp = new byte[bmpSize]; IsDirty = false; using (ImageSurface draw = - new ImageSurface(bmp, Format.Argb32, Slot.Width, Slot.Height, stride)) { + new ImageSurface(bmp, Format.Argb32, nativeHnd->Slot.Width, nativeHnd->Slot.Height, stride)) { using (Context gr = new Context (draw)) { gr.Antialias = Interface.Antialias; onDraw (gr); @@ -1130,9 +1169,9 @@ namespace Crow draw.Flush (); } } - protected virtual void UpdateCache(Context ctx){ - Rectangle rb = Slot + Parent.ClientRectangle.Position; - using (ImageSurface cache = new ImageSurface (bmp, Format.Argb32, Slot.Width, Slot.Height, 4 * Slot.Width)) { + unsafe protected virtual void UpdateCache(Context ctx){ + Rectangle rb = nativeHnd->Slot + Parent.ClientRectangle.Position; + using (ImageSurface cache = new ImageSurface (bmp, Format.Argb32, nativeHnd->Slot.Width, nativeHnd->Slot.Height, 4 * nativeHnd->Slot.Width)) { if (clearBackground) { ctx.Save (); ctx.Operator = Operator.Clear; @@ -1148,14 +1187,14 @@ namespace Crow } /// Chained painting routine on the parent context of the actual cached version /// of the widget - public virtual void Paint (ref Context ctx) + unsafe public virtual void Paint (ref Context ctx) { //TODO:this test should not be necessary - if (Slot.Height < 0 || Slot.Width < 0 || parent == null) + if (nativeHnd->Slot.Height < 0 || nativeHnd->Slot.Width < 0 || parent == null) return; lock (this) { if (cacheEnabled) { - if (Slot.Width > Interface.MaxCacheSize || Slot.Height > Interface.MaxCacheSize) + if (nativeHnd->Slot.Width > Interface.MaxCacheSize || nativeHnd->Slot.Height > Interface.MaxCacheSize) cacheEnabled = false; } @@ -1165,20 +1204,20 @@ namespace Crow UpdateCache (ctx); if (!isEnabled) - paintDisabled (ctx, Slot + Parent.ClientRectangle.Position); + paintDisabled (ctx, nativeHnd->Slot + Parent.ClientRectangle.Position); } else { - Rectangle rb = Slot + Parent.ClientRectangle.Position; + Rectangle rb = nativeHnd->Slot + Parent.ClientRectangle.Position; ctx.Save (); ctx.Translate (rb.X, rb.Y); onDraw (ctx); if (!isEnabled) - paintDisabled (ctx, Slot); + paintDisabled (ctx, nativeHnd->Slot); ctx.Restore (); } - LastPaintedSlot = Slot; + nativeHnd->LastPaintedSlot = nativeHnd->Slot; } } void paintDisabled(Context gr, Rectangle rb){ @@ -1203,18 +1242,15 @@ namespace Crow #endregion #region Mouse handling - public virtual bool MouseIsIn(Point m) + unsafe public virtual bool MouseIsIn(Point m) { try { if (!(Visible & isEnabled)) return false; - if (ScreenCoordinates (Slot).ContainsOrIsEqual (m)) { + if (ScreenCoordinates (nativeHnd->Slot).ContainsOrIsEqual (m)) { Scroller scr = Parent as Scroller; - if (scr == null) { - if (Parent is GraphicObject) - return (Parent as GraphicObject).MouseIsIn (m); - else return true; - } + if (scr == null) + return Parent.MouseIsIn (m); return scr.MouseIsIn (scr.savedMousePos); } } catch (Exception ex) { @@ -1234,9 +1270,8 @@ namespace Crow public virtual void onMouseMove(object sender, MouseMoveEventArgs e) { //bubble event to the top - GraphicObject p = Parent as GraphicObject; - if (p != null) - p.onMouseMove(sender,e); + if (Parent != null) + Parent.onMouseMove(sender,e); MouseMove.Raise (this, e); } @@ -1257,17 +1292,15 @@ namespace Crow } } //bubble event to the top - GraphicObject p = Parent as GraphicObject; - if (p != null) - p.onMouseDown(sender,e); + if (Parent != null) + Parent.onMouseDown(sender,e); MouseDown.Raise (this, e); } public virtual void onMouseUp(object sender, MouseButtonEventArgs e){ //bubble event to the top - GraphicObject p = Parent as GraphicObject; - if (p != null) - p.onMouseUp(sender,e); + if (Parent != null) + Parent.onMouseUp(sender,e); MouseUp.Raise (this, e); @@ -1277,22 +1310,19 @@ namespace Crow onMouseClick (this, e); } } - public virtual void onMouseClick(object sender, MouseButtonEventArgs e){ - GraphicObject p = Parent as GraphicObject; - if (p != null) - p.onMouseClick(sender,e); + public virtual void onMouseClick(object sender, MouseButtonEventArgs e){ + if (Parent != null) + Parent.onMouseClick(sender,e); MouseClick.Raise (this, e); } - public virtual void onMouseDoubleClick(object sender, MouseButtonEventArgs e){ - GraphicObject p = Parent as GraphicObject; - if (p != null) - p.onMouseDoubleClick(sender,e); + public virtual void onMouseDoubleClick(object sender, MouseButtonEventArgs e){ + if (Parent != null) + Parent.onMouseDoubleClick(sender,e); MouseDoubleClick.Raise (this, e); } - public virtual void onMouseWheel(object sender, MouseWheelEventArgs e){ - GraphicObject p = Parent as GraphicObject; - if (p != null) - p.onMouseWheel(sender,e); + public virtual void onMouseWheel(object sender, MouseWheelEventArgs e){ + if (Parent != null) + Parent.onMouseWheel(sender,e); MouseWheelChanged.Raise (this, e); } @@ -1351,5 +1381,25 @@ namespace Crow return Name == "unamed" ? tmp + "." + this.GetType ().Name : tmp + "." + Name; #endif } + #region IDisposable implementation + ~GraphicObject(){ + Dispose (false); + } + public void Dispose () + { + Dispose (true); + GC.SuppressFinalize (this); + } + bool disposed = false; + protected virtual void Dispose (bool disposing){ + if (disposed) + return; + Clipping.Dispose (); + unsafe{ + DestroyGO (nativeHnd); + } + disposed = true; + } + #endregion } } diff --git a/src/GraphicObjects/Grid.cs b/src/GraphicObjects/Grid.cs index 3d1847a2..4f9abf78 100644 --- a/src/GraphicObjects/Grid.cs +++ b/src/GraphicObjects/Grid.cs @@ -101,11 +101,11 @@ namespace Crow this.RegisterForLayouting (LayoutingType.ArrangeChildren); } } - public virtual int CaseWidth { - get { return (Slot.Width - (ColumnCount - 1) * Spacing) / ColumnCount; } + unsafe public virtual int CaseWidth { + get { return (nativeHnd->Slot.Width - (ColumnCount - 1) * Spacing) / ColumnCount; } } - public virtual int CaseHeight { - get { return (Slot.Height - (RowCount - 1) * Spacing) / RowCount; } + unsafe public virtual int CaseHeight { + get { return (nativeHnd->Slot.Height - (RowCount - 1) * Spacing) / RowCount; } } #endregion diff --git a/src/GraphicObjects/Group.cs b/src/GraphicObjects/Group.cs index 55c4fc8b..d42da81d 100644 --- a/src/GraphicObjects/Group.cs +++ b/src/GraphicObjects/Group.cs @@ -230,11 +230,11 @@ namespace Crow } gr.Restore (); } - protected override void UpdateCache (Context ctx) + unsafe protected override void UpdateCache (Context ctx) { - Rectangle rb = Slot + Parent.ClientRectangle.Position; + Rectangle rb = nativeHnd->Slot + Parent.ClientRectangle.Position; - using (ImageSurface cache = new ImageSurface (bmp, Format.Argb32, Slot.Width, Slot.Height, 4 * Slot.Width)) { + using (ImageSurface cache = new ImageSurface (bmp, Format.Argb32, nativeHnd->Slot.Width, nativeHnd->Slot.Height, 4 * nativeHnd->Slot.Width)) { Context gr = new Context (cache); if (!Clipping.IsEmpty) { @@ -256,7 +256,7 @@ namespace Crow foreach (GraphicObject c in Children) { if (!c.Visible) continue; - if (Clipping.Contains (c.Slot + ClientRectangle.Position) == RegionOverlap.Out) + if (Clipping.Contains (c.nativeHnd->Slot + ClientRectangle.Position) == RegionOverlap.Out) continue; c.Paint (ref gr); } @@ -276,7 +276,7 @@ namespace Crow } #endregion - public virtual void OnChildLayoutChanges (object sender, LayoutingEventArgs arg) + unsafe public virtual void OnChildLayoutChanges (object sender, LayoutingEventArgs arg) { GraphicObject g = sender as GraphicObject; @@ -284,9 +284,9 @@ namespace Crow case LayoutingType.Width: if (Width != Measure.Fit) return; - if (g.Slot.Width > contentSize.Width) { + if (g.nativeHnd->Slot.Width > contentSize.Width) { largestChild = g; - contentSize.Width = g.Slot.Width; + contentSize.Width = g.nativeHnd->Slot.Width; } else if (g == largestChild) searchLargestChild (); @@ -295,9 +295,9 @@ namespace Crow case LayoutingType.Height: if (Height != Measure.Fit) return; - if (g.Slot.Height > contentSize.Height) { + if (g.nativeHnd->Slot.Height > contentSize.Height) { tallestChild = g; - contentSize.Height = g.Slot.Height; + contentSize.Height = g.nativeHnd->Slot.Height; } else if (g == tallestChild) searchTallestChild (); @@ -311,7 +311,7 @@ namespace Crow tallestChild = null; contentSize = 0; } - void searchLargestChild(){ + unsafe void searchLargestChild(){ #if DEBUG_LAYOUTING Debug.WriteLine("\tSearch largest child"); #endif @@ -322,13 +322,13 @@ namespace Crow continue; if (children [i].RegisteredLayoutings.HasFlag (LayoutingType.Width)) continue; - if (Children [i].Slot.Width > contentSize.Width) { - contentSize.Width = Children [i].Slot.Width; + if (Children [i].nativeHnd->Slot.Width > contentSize.Width) { + contentSize.Width = Children [i].nativeHnd->Slot.Width; largestChild = Children [i]; } } } - void searchTallestChild(){ + unsafe void searchTallestChild(){ #if DEBUG_LAYOUTING Debug.WriteLine("\tSearch tallest child"); #endif @@ -339,8 +339,8 @@ namespace Crow continue; if (children [i].RegisteredLayoutings.HasFlag (LayoutingType.Height)) continue; - if (Children [i].Slot.Height > contentSize.Height) { - contentSize.Height = Children [i].Slot.Height; + if (Children [i].nativeHnd->Slot.Height > contentSize.Height) { + contentSize.Height = Children [i].nativeHnd->Slot.Height; tallestChild = Children [i]; } } diff --git a/src/GraphicObjects/HueSelector.cs b/src/GraphicObjects/HueSelector.cs index 365cc72a..ab20edd9 100644 --- a/src/GraphicObjects/HueSelector.cs +++ b/src/GraphicObjects/HueSelector.cs @@ -89,11 +89,11 @@ namespace Crow gr.Fill(); } - public override void Paint (ref Context ctx) + unsafe public override void Paint (ref Context ctx) { base.Paint (ref ctx); - Rectangle rb = Slot + Parent.ClientRectangle.Position; + Rectangle rb = nativeHnd->Slot + Parent.ClientRectangle.Position; ctx.Save (); ctx.Translate (rb.X, rb.Y); diff --git a/src/GraphicObjects/ILayoutable.cs b/src/GraphicObjects/ILayoutable.cs deleted file mode 100644 index c0c1cf5c..00000000 --- a/src/GraphicObjects/ILayoutable.cs +++ /dev/null @@ -1,55 +0,0 @@ -// -// ILayoutable.cs -// -// Author: -// Jean-Philippe Bruyère -// -// Copyright (c) 2013-2017 Jean-Philippe Bruyère -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. - -using System; -using System.Collections.Generic; - -namespace Crow -{ - public interface ILayoutable - { - /// Parent in the graphic tree - ILayoutable Parent { get; set; } - /// The logical parent (used mainly for bindings) as opposed - /// to the parent in the graphic tree - ILayoutable LogicalParent { get; set; } - - Rectangle ClientRectangle { get; } - Rectangle getSlot(); - - bool ArrangeChildren { get; } - LayoutingType RegisteredLayoutings { get; set; } - void RegisterForLayouting(LayoutingType layoutType); - void RegisterClip(Rectangle clip); - bool UpdateLayout(LayoutingType layoutType); - - - Rectangle ContextCoordinates(Rectangle r); - Rectangle ScreenCoordinates (Rectangle r); - - } -} - diff --git a/src/GraphicObjects/Label.cs b/src/GraphicObjects/Label.cs index 64ee9688..4c802fec 100644 --- a/src/GraphicObjects/Label.cs +++ b/src/GraphicObjects/Label.cs @@ -675,8 +675,8 @@ namespace Crow #endregion #region Mouse handling - void updatemouseLocalPos(Point mpos){ - mouseLocalPos = mpos - ScreenCoordinates(Slot).TopLeft - ClientRectangle.TopLeft; + unsafe void updatemouseLocalPos(Point mpos){ + mouseLocalPos = mpos - ScreenCoordinates(nativeHnd->Slot).TopLeft - ClientRectangle.TopLeft; if (mouseLocalPos.X < 0) mouseLocalPos.X = 0; if (mouseLocalPos.Y < 0) diff --git a/src/GraphicObjects/Popper.cs b/src/GraphicObjects/Popper.cs index 0e5364d6..18e615b5 100644 --- a/src/GraphicObjects/Popper.cs +++ b/src/GraphicObjects/Popper.cs @@ -130,43 +130,43 @@ namespace Crow _content.LayoutChanged += _content_LayoutChanged; } } - void positionContent(LayoutingType lt){ - ILayoutable tc = Content.Parent; + unsafe void positionContent(LayoutingType lt){ + GraphicObject tc = Content.Parent; if (tc == null) return; - Rectangle r = this.ScreenCoordinates (this.Slot); + Rectangle r = this.ScreenCoordinates (this.nativeHnd->Slot); if (lt == LayoutingType.X) { if (popDirection.HasFlag (Alignment.Right)) { - if (r.Right + Content.Slot.Width > tc.ClientRectangle.Right) - Content.Left = r.Left - Content.Slot.Width; + if (r.Right + Content.nativeHnd->Slot.Width > tc.ClientRectangle.Right) + Content.Left = r.Left - Content.nativeHnd->Slot.Width; else Content.Left = r.Right; } else if (popDirection.HasFlag (Alignment.Left)) { - if (r.Left - Content.Slot.Width < tc.ClientRectangle.Left) + if (r.Left - Content.nativeHnd->Slot.Width < tc.ClientRectangle.Left) Content.Left = r.Right; else - Content.Left = r.Left - Content.Slot.Width; + Content.Left = r.Left - Content.nativeHnd->Slot.Width; } else { - if (Content.Slot.Width < tc.ClientRectangle.Width) { - if (r.Left + Content.Slot.Width > tc.ClientRectangle.Right) - Content.Left = tc.ClientRectangle.Right - Content.Slot.Width; + if (Content.nativeHnd->Slot.Width < tc.ClientRectangle.Width) { + if (r.Left + Content.nativeHnd->Slot.Width > tc.ClientRectangle.Right) + Content.Left = tc.ClientRectangle.Right - Content.nativeHnd->Slot.Width; else Content.Left = r.Left; } else Content.Left = 0; } }else if (lt == LayoutingType.Y) { - if (Content.Slot.Height < tc.ClientRectangle.Height) { + if (Content.nativeHnd->Slot.Height < tc.ClientRectangle.Height) { if (PopDirection.HasFlag (Alignment.Bottom)) { - if (r.Bottom + Content.Slot.Height > tc.ClientRectangle.Bottom) - Content.Top = r.Top - Content.Slot.Height; + if (r.Bottom + Content.nativeHnd->Slot.Height > tc.ClientRectangle.Bottom) + Content.Top = r.Top - Content.nativeHnd->Slot.Height; else Content.Top = r.Bottom; } else if (PopDirection.HasFlag (Alignment.Top)) { - if (r.Top - Content.Slot.Height < tc.ClientRectangle.Top) + if (r.Top - Content.nativeHnd->Slot.Height < tc.ClientRectangle.Top) Content.Top = r.Bottom; else - Content.Top = r.Top - Content.Slot.Height; + Content.Top = r.Top - Content.nativeHnd->Slot.Height; } else Content.Top = r.Top; }else diff --git a/src/GraphicObjects/PrivateContainer.cs b/src/GraphicObjects/PrivateContainer.cs index 73a971db..67083c05 100644 --- a/src/GraphicObjects/PrivateContainer.cs +++ b/src/GraphicObjects/PrivateContainer.cs @@ -49,7 +49,7 @@ namespace Crow protected GraphicObject child; - internal virtual void SetChild(GraphicObject _child) + unsafe internal virtual void SetChild(GraphicObject _child) { if (child != null) { @@ -69,7 +69,7 @@ namespace Crow if (child != null) { child.Parent = this; child.LayoutChanged += OnChildLayoutChanges; - contentSize = child.Slot.Size; + contentSize = child.nativeHnd->Slot.Size; child.RegisteredLayoutings = LayoutingType.None; child.RegisterForLayouting (LayoutingType.Sizing); } @@ -141,19 +141,19 @@ namespace Crow return; child.RegisterForLayouting (ltChild); } - public virtual void OnChildLayoutChanges (object sender, LayoutingEventArgs arg) + unsafe public virtual void OnChildLayoutChanges (object sender, LayoutingEventArgs arg) { GraphicObject g = sender as GraphicObject; if (arg.LayoutType == LayoutingType.Width) { if (Width != Measure.Fit) return; - contentSize.Width = g.Slot.Width; + contentSize.Width = g.nativeHnd->Slot.Width; this.RegisterForLayouting (LayoutingType.Width); }else if (arg.LayoutType == LayoutingType.Height){ if (Height != Measure.Fit) return; - contentSize.Height = g.Slot.Height; + contentSize.Height = g.nativeHnd->Slot.Height; this.RegisterForLayouting (LayoutingType.Height); } } @@ -175,11 +175,11 @@ namespace Crow } gr.Restore (); } - protected override void UpdateCache (Context ctx) + unsafe protected override void UpdateCache (Context ctx) { - Rectangle rb = Slot + Parent.ClientRectangle.Position; + Rectangle rb = nativeHnd->Slot + Parent.ClientRectangle.Position; - using (ImageSurface cache = new ImageSurface (bmp, Format.Argb32, Slot.Width, Slot.Height, 4 * Slot.Width)) { + using (ImageSurface cache = new ImageSurface (bmp, Format.Argb32, nativeHnd->Slot.Width, nativeHnd->Slot.Height, 4 * nativeHnd->Slot.Width)) { Context gr = new Context (cache); if (!Clipping.IsEmpty) { diff --git a/src/GraphicObjects/SaturationValueSelector.cs b/src/GraphicObjects/SaturationValueSelector.cs index 39c324f4..0abf07cb 100644 --- a/src/GraphicObjects/SaturationValueSelector.cs +++ b/src/GraphicObjects/SaturationValueSelector.cs @@ -90,11 +90,11 @@ namespace Crow gr.Fill(); } - public override void Paint (ref Context ctx) + unsafe public override void Paint (ref Context ctx) { base.Paint (ref ctx); - Rectangle rb = Slot + Parent.ClientRectangle.Position; + Rectangle rb = nativeHnd->Slot + Parent.ClientRectangle.Position; ctx.Save (); ctx.Translate (rb.X, rb.Y); diff --git a/src/GraphicObjects/Scroller.cs b/src/GraphicObjects/Scroller.cs index 640fcfe8..21f7cd88 100644 --- a/src/GraphicObjects/Scroller.cs +++ b/src/GraphicObjects/Scroller.cs @@ -61,7 +61,7 @@ namespace Crow set { _scrollbarVisible = value; } } [XmlAttributeAttribute][DefaultValue(0.0)] - public double ScrollX { + unsafe public double ScrollX { get { return _scrollX; } @@ -70,8 +70,8 @@ namespace Crow return; if (value < 0.0) _scrollX = 0.0; - else if (value > Child.Slot.Width - ClientRectangle.Width) - _scrollX = Math.Max(0.0, Child.Slot.Width - ClientRectangle.Width); + else if (value > Child.nativeHnd->Slot.Width - ClientRectangle.Width) + _scrollX = Math.Max(0.0, Child.nativeHnd->Slot.Width - ClientRectangle.Width); else _scrollX = value; NotifyValueChanged("ScrollX", _scrollX); @@ -80,7 +80,7 @@ namespace Crow } } [XmlAttributeAttribute][DefaultValue(0.0)] - public double ScrollY { + unsafe public double ScrollY { get { return _scrollY; } @@ -89,8 +89,8 @@ namespace Crow return; if (value < 0.0) _scrollY = 0.0; - else if (value > Child.Slot.Height - ClientRectangle.Height) - _scrollY = Math.Max(0.0,Child.Slot.Height - ClientRectangle.Height); + else if (value > Child.nativeHnd->Slot.Height - ClientRectangle.Height) + _scrollY = Math.Max(0.0,Child.nativeHnd->Slot.Height - ClientRectangle.Height); else _scrollY = value; NotifyValueChanged("ScrollY", _scrollY); @@ -100,12 +100,12 @@ namespace Crow } [XmlIgnore] - public int MaximumScroll { + unsafe public int MaximumScroll { get { try { return VerticalScrolling ? - Math.Max(Child.Slot.Height - ClientRectangle.Height,0) : - Math.Max(Child.Slot.Width - ClientRectangle.Width,0); + Math.Max(Child.nativeHnd->Slot.Height - ClientRectangle.Height,0) : + Math.Max(Child.nativeHnd->Slot.Width - ClientRectangle.Width,0); } catch { return 0; } @@ -179,9 +179,9 @@ namespace Crow { return base.ScreenCoordinates (r) - new Point((int)ScrollX,(int)ScrollY); } - protected override void onDraw (Context gr) + unsafe protected override void onDraw (Context gr) { - Rectangle rBack = new Rectangle (Slot.Size); + Rectangle rBack = new Rectangle (nativeHnd->Slot.Size); Background.SetAsSource (gr, rBack); CairoHelpers.CairoRectangle(gr,rBack, CornerRadius); @@ -202,9 +202,9 @@ namespace Crow #region Mouse handling internal Point savedMousePos; - public override bool MouseIsIn (Point m) + unsafe public override bool MouseIsIn (Point m) { - return Visible ? base.ScreenCoordinates(Slot).ContainsOrIsEqual (m) : false; + return Visible ? base.ScreenCoordinates(nativeHnd->Slot).ContainsOrIsEqual (m) : false; } public override void checkHoverWidget (MouseMoveEventArgs e) { diff --git a/src/GraphicObjects/Slider.cs b/src/GraphicObjects/Slider.cs index 36f7e731..fd451c98 100644 --- a/src/GraphicObjects/Slider.cs +++ b/src/GraphicObjects/Slider.cs @@ -178,11 +178,11 @@ namespace Crow } #region mouse handling - public override void onMouseDown (object sender, MouseButtonEventArgs e) + unsafe public override void onMouseDown (object sender, MouseButtonEventArgs e) { base.onMouseDown (sender, e); - Rectangle cursInScreenCoord = ScreenCoordinates (cursor + Slot.Position); + Rectangle cursInScreenCoord = ScreenCoordinates (cursor + nativeHnd->Slot.Position); if (cursInScreenCoord.ContainsOrIsEqual (e.Position)) holdCursor = true; else if (_orientation == Orientation.Horizontal) { diff --git a/src/GraphicObjects/Splitter.cs b/src/GraphicObjects/Splitter.cs index 2f5dd15b..d7f1c7a3 100644 --- a/src/GraphicObjects/Splitter.cs +++ b/src/GraphicObjects/Splitter.cs @@ -70,7 +70,7 @@ namespace Crow } #region GraphicObject override - public override ILayoutable Parent { + public override GraphicObject Parent { get { return base.Parent; } set { if (value != null) { @@ -95,7 +95,7 @@ namespace Crow base.onMouseLeave (sender, e); CurrentInterface.MouseCursor = XCursor.Default; } - public override void onMouseDown (object sender, MouseButtonEventArgs e) + unsafe public override void onMouseDown (object sender, MouseButtonEventArgs e) { base.onMouseDown (sender, e); go1 = go2 = null; @@ -111,7 +111,7 @@ namespace Crow go2 = gs.Children [ptrSplit + 1]; if (gs.Orientation == Orientation.Horizontal) { - initSplit (go1.Width, go1.Slot.Width, go2.Width, go2.Slot.Width); + initSplit (go1.Width, go1.nativeHnd->Slot.Width, go2.Width, go2.nativeHnd->Slot.Width); min1 = go1.MinimumSize.Width; min2 = go2.MinimumSize.Width; max1 = go1.MaximumSize.Width; @@ -121,7 +121,7 @@ namespace Crow if (init2 >= 0) go2.Width = init2; } else { - initSplit (go1.Height, go1.Slot.Height, go2.Height, go2.Slot.Height); + initSplit (go1.Height, go1.nativeHnd->Slot.Height, go2.Height, go2.nativeHnd->Slot.Height); min1 = go1.MinimumSize.Height; min2 = go2.MinimumSize.Height; max1 = go1.MaximumSize.Height; @@ -132,7 +132,7 @@ namespace Crow go2.Height = init2; } } - public override void onMouseMove (object sender, MouseMoveEventArgs e) + unsafe public override void onMouseMove (object sender, MouseMoveEventArgs e) { base.onMouseMove (sender, e); @@ -144,15 +144,15 @@ namespace Crow if (gs.Orientation == Orientation.Horizontal) { newDelta -= e.XDelta; if (size1 < 0) - size1 = go1.Slot.Width + delta; + size1 = go1.nativeHnd->Slot.Width + delta; if (size2 < 0) - size2 = go2.Slot.Width - delta; + size2 = go2.nativeHnd->Slot.Width - delta; } else { newDelta -= e.YDelta; if (size1 < 0) - size1 = go1.Slot.Height + delta; + size1 = go1.nativeHnd->Slot.Height + delta; if (size2 < 0) - size2 = go2.Slot.Height - delta; + size2 = go2.nativeHnd->Slot.Height - delta; } if (size1 - newDelta < min1 || (max1 > 0 && size1 - newDelta > max1) || @@ -173,7 +173,7 @@ namespace Crow go2.Height = init2 + delta; } } - public override void onMouseUp (object sender, MouseButtonEventArgs e) + unsafe public override void onMouseUp (object sender, MouseButtonEventArgs e) { base.onMouseUp (sender, e); @@ -182,18 +182,18 @@ namespace Crow if (init1 >= 0 && u1 == Unit.Percent) { if (gs.Orientation == Orientation.Horizontal) go1.Width = new Measure ((int)Math.Ceiling ( - go1.Width.Value * 100.0 / (double)gs.Slot.Width), Unit.Percent); + go1.Width.Value * 100.0 / (double)gs.nativeHnd->Slot.Width), Unit.Percent); else go1.Height = new Measure ((int)Math.Ceiling ( - go1.Height.Value * 100.0 / (double)gs.Slot.Height), Unit.Percent); + go1.Height.Value * 100.0 / (double)gs.nativeHnd->Slot.Height), Unit.Percent); } if (init2 >= 0 && u2 == Unit.Percent) { if (gs.Orientation == Orientation.Horizontal) go2.Width = new Measure ((int)Math.Floor ( - go2.Width.Value * 100.0 / (double)gs.Slot.Width), Unit.Percent); + go2.Width.Value * 100.0 / (double)gs.nativeHnd->Slot.Width), Unit.Percent); else go2.Height = new Measure ((int)Math.Floor ( - go2.Height.Value * 100.0 / (double)gs.Slot.Height), Unit.Percent); + go2.Height.Value * 100.0 / (double)gs.nativeHnd->Slot.Height), Unit.Percent); } } public override bool UpdateLayout (LayoutingType layoutType) diff --git a/src/GraphicObjects/TabItem.cs b/src/GraphicObjects/TabItem.cs index 7dac5472..094c2cde 100644 --- a/src/GraphicObjects/TabItem.cs +++ b/src/GraphicObjects/TabItem.cs @@ -106,28 +106,28 @@ namespace Crow NotifyValueChanged ("IsSelected", isSelected); } } - protected override void onDraw (Cairo.Context gr) + unsafe protected override void onDraw (Cairo.Context gr) { gr.Save (); int spacing = (Parent as TabView).Spacing; - gr.MoveTo (0.5, TabTitle.Slot.Bottom-0.5); - gr.LineTo (TabTitle.Slot.Left - spacing, TabTitle.Slot.Bottom-0.5); + gr.MoveTo (0.5, TabTitle.nativeHnd->Slot.Bottom-0.5); + gr.LineTo (TabTitle.nativeHnd->Slot.Left - spacing, TabTitle.nativeHnd->Slot.Bottom-0.5); gr.CurveTo ( - TabTitle.Slot.Left - spacing / 2, TabTitle.Slot.Bottom-0.5, - TabTitle.Slot.Left - spacing / 2, 0.5, - TabTitle.Slot.Left, 0.5); - gr.LineTo (TabTitle.Slot.Right, 0.5); + TabTitle.nativeHnd->Slot.Left - spacing / 2, TabTitle.nativeHnd->Slot.Bottom-0.5, + TabTitle.nativeHnd->Slot.Left - spacing / 2, 0.5, + TabTitle.nativeHnd->Slot.Left, 0.5); + gr.LineTo (TabTitle.nativeHnd->Slot.Right, 0.5); gr.CurveTo ( - TabTitle.Slot.Right + spacing / 2, 0.5, - TabTitle.Slot.Right + spacing / 2, TabTitle.Slot.Bottom-0.5, - TabTitle.Slot.Right + spacing, TabTitle.Slot.Bottom-0.5); - gr.LineTo (Slot.Width-0.5, TabTitle.Slot.Bottom-0.5); + TabTitle.nativeHnd->Slot.Right + spacing / 2, 0.5, + TabTitle.nativeHnd->Slot.Right + spacing / 2, TabTitle.nativeHnd->Slot.Bottom-0.5, + TabTitle.nativeHnd->Slot.Right + spacing, TabTitle.nativeHnd->Slot.Bottom-0.5); + gr.LineTo (nativeHnd->Slot.Width-0.5, TabTitle.nativeHnd->Slot.Bottom-0.5); - gr.LineTo (Slot.Width-0.5, Slot.Height-0.5); - gr.LineTo (0.5, Slot.Height-0.5); + gr.LineTo (nativeHnd->Slot.Width-0.5, nativeHnd->Slot.Height-0.5); + gr.LineTo (0.5, nativeHnd->Slot.Height-0.5); gr.ClosePath (); gr.LineWidth = 2; Foreground.SetAsSource (gr); @@ -139,16 +139,16 @@ namespace Crow } #region Mouse Handling - public override bool MouseIsIn (Point m) + unsafe public override bool MouseIsIn (Point m) { if (!Visible) return false; - bool mouseIsInTitle = TabTitle.ScreenCoordinates (TabTitle.Slot).ContainsOrIsEqual (m); + bool mouseIsInTitle = TabTitle.ScreenCoordinates (TabTitle.nativeHnd->Slot).ContainsOrIsEqual (m); if (!IsSelected) return mouseIsInTitle; - return _contentContainer.ScreenCoordinates (_contentContainer.Slot).ContainsOrIsEqual (m) + return _contentContainer.ScreenCoordinates (_contentContainer.nativeHnd->Slot).ContainsOrIsEqual (m) || mouseIsInTitle; } bool holdCursor = false; @@ -163,7 +163,7 @@ namespace Crow holdCursor = false; (Parent as TabView).UpdateLayout (LayoutingType.ArrangeChildren); } - public override void onMouseMove (object sender, MouseMoveEventArgs e) + unsafe public override void onMouseMove (object sender, MouseMoveEventArgs e) { base.onMouseMove (sender, e); @@ -174,14 +174,14 @@ namespace Crow int tmp = TabOffset + e.XDelta; if (tmp < tv.Spacing) TabOffset = tv.Spacing; - else if (tmp > Parent.getSlot ().Width - TabTitle.Slot.Width - tv.Spacing) - TabOffset = Parent.getSlot ().Width - TabTitle.Slot.Width - tv.Spacing; + else if (tmp > Parent.getSlot ().Width - TabTitle.nativeHnd->Slot.Width - tv.Spacing) + TabOffset = Parent.getSlot ().Width - TabTitle.nativeHnd->Slot.Width - tv.Spacing; else{ int idx = tv.Children.IndexOf (this); if (idx > 0 && e.XDelta < 0) { previous = tv.Children [idx - 1] as TabItem; - if (tmp < previous.TabOffset + previous.TabTitle.Slot.Width / 2) { + if (tmp < previous.TabOffset + previous.TabTitle.nativeHnd->Slot.Width / 2) { tv.Children.RemoveAt (idx); tv.Children.Insert (idx - 1, this); tv.SelectedTab = idx - 1; @@ -190,7 +190,7 @@ namespace Crow }else if (idx < tv.Children.Count - 1 && e.XDelta > 0) { next = tv.Children [idx + 1] as TabItem; - if (tmp > next.TabOffset - next.TabTitle.Slot.Width / 2){ + if (tmp > next.TabOffset - next.TabTitle.nativeHnd->Slot.Width / 2){ tv.Children.RemoveAt (idx); tv.Children.Insert (idx + 1, this); tv.SelectedTab = idx + 1; diff --git a/src/GraphicObjects/TabView.cs b/src/GraphicObjects/TabView.cs index ecf38f10..93338fc2 100644 --- a/src/GraphicObjects/TabView.cs +++ b/src/GraphicObjects/TabView.cs @@ -115,7 +115,7 @@ namespace Crow SelectedTab = selectedTab; } public override bool ArrangeChildren { get { return true; } } - public override bool UpdateLayout (LayoutingType layoutType) + unsafe public override bool UpdateLayout (LayoutingType layoutType) { RegisteredLayoutings &= (~layoutType); @@ -129,11 +129,11 @@ namespace Crow if (Orientation == Orientation.Horizontal) { if (ti.TabTitle.RegisteredLayoutings.HasFlag (LayoutingType.Width)) return false; - curOffset += ti.TabTitle.Slot.Width + Spacing; + curOffset += ti.TabTitle.nativeHnd->Slot.Width + Spacing; } else { if (ti.TabTitle.RegisteredLayoutings.HasFlag (LayoutingType.Height)) return false; - curOffset += ti.TabTitle.Slot.Height + Spacing; + curOffset += ti.TabTitle.nativeHnd->Slot.Height + Spacing; } } @@ -146,9 +146,9 @@ namespace Crow return base.UpdateLayout(layoutType); } - protected override void onDraw (Context gr) + unsafe protected override void onDraw (Context gr) { - Rectangle rBack = new Rectangle (Slot.Size); + Rectangle rBack = new Rectangle (nativeHnd->Slot.Size); Background.SetAsSource (gr, rBack); CairoHelpers.CairoRectangle(gr,rBack, CornerRadius); @@ -185,7 +185,7 @@ namespace Crow if (SelectedTab > Children.Count - 1) return; - if (((Children[SelectedTab] as TabItem).Content.Parent as GraphicObject).MouseIsIn(e.Position)) + if ((Children[SelectedTab] as TabItem).Content.Parent.MouseIsIn(e.Position)) { Children[SelectedTab].checkHoverWidget (e); return; diff --git a/src/GraphicObjects/TemplatedGroup.cs b/src/GraphicObjects/TemplatedGroup.cs index eea3a184..719da077 100644 --- a/src/GraphicObjects/TemplatedGroup.cs +++ b/src/GraphicObjects/TemplatedGroup.cs @@ -405,7 +405,7 @@ namespace Crow // } else if (e.LayoutType == LayoutingType.Height) // _gsList.Height = approxSize; // } - int approxSize + unsafe int approxSize { get { if (data == null) @@ -417,10 +417,10 @@ namespace Crow return page1.Orientation == Orientation.Horizontal ? data.Count < itemPerPage ? -1: - (int)Math.Ceiling ((double)page1.Slot.Width / (double)itemPerPage * (double)(data.Count+1)): + (int)Math.Ceiling ((double)page1.nativeHnd->Slot.Width / (double)itemPerPage * (double)(data.Count+1)): data.Count < itemPerPage ? -1: - (int)Math.Ceiling ((double)page1.Slot.Height / (double)itemPerPage * (double)(data.Count+1)); + (int)Math.Ceiling ((double)page1.nativeHnd->Slot.Height / (double)itemPerPage * (double)(data.Count+1)); } } internal virtual void itemClick(object sender, MouseButtonEventArgs e){ diff --git a/src/GraphicObjects/TreeView.cs b/src/GraphicObjects/TreeView.cs index 6549f148..9afd9b3e 100644 --- a/src/GraphicObjects/TreeView.cs +++ b/src/GraphicObjects/TreeView.cs @@ -66,7 +66,7 @@ namespace Crow //register ItemClick on the Root node TreeView tv = this as TreeView; while (!tv.IsRoot) { - ILayoutable tmp = tv.Parent; + GraphicObject tmp = tv.Parent; while (!(tmp is TreeView)) { tmp = tmp.Parent; } diff --git a/src/GraphicObjects/Window.cs b/src/GraphicObjects/Window.cs index 8a6903f6..4b002f8b 100644 --- a/src/GraphicObjects/Window.cs +++ b/src/GraphicObjects/Window.cs @@ -174,7 +174,7 @@ namespace Crow #endregion #region GraphicObject Overrides - public override void onMouseMove (object sender, MouseMoveEventArgs e) + unsafe public override void onMouseMove (object sender, MouseMoveEventArgs e) { base.onMouseMove (sender, e); @@ -193,22 +193,22 @@ namespace Crow int currentWidth, currentHeight; if (currentLeft == 0) { - currentLeft = this.Slot.Left; + currentLeft = this.nativeHnd->Slot.Left; this.Left = currentLeft; } if (currentTop == 0) { - currentTop = this.Slot.Top; + currentTop = this.nativeHnd->Slot.Top; this.Top = currentTop; } if (this.Width.IsFixed) currentWidth = this.Width; else - currentWidth = this.Slot.Width; + currentWidth = this.nativeHnd->Slot.Width; if (this.Height.IsFixed) currentHeight = this.Height; else - currentHeight = this.Slot.Height; + currentHeight = this.nativeHnd->Slot.Height; switch (currentDirection) { case Direction.None: @@ -262,23 +262,23 @@ namespace Crow if (Resizable) { Direction lastDir = currentDirection; - if (Math.Abs (e.Position.Y - this.Slot.Y) < Interface.BorderThreshold) { - if (Math.Abs (e.Position.X - this.Slot.X) < Interface.BorderThreshold) + if (Math.Abs (e.Position.Y - this.nativeHnd->Slot.Y) < Interface.BorderThreshold) { + if (Math.Abs (e.Position.X - this.nativeHnd->Slot.X) < Interface.BorderThreshold) currentDirection = Direction.NW; - else if (Math.Abs (e.Position.X - this.Slot.Right) < Interface.BorderThreshold) + else if (Math.Abs (e.Position.X - this.nativeHnd->Slot.Right) < Interface.BorderThreshold) currentDirection = Direction.NE; else currentDirection = Direction.N; - } else if (Math.Abs (e.Position.Y - this.Slot.Bottom) < Interface.BorderThreshold) { - if (Math.Abs (e.Position.X - this.Slot.X) < Interface.BorderThreshold) + } else if (Math.Abs (e.Position.Y - this.nativeHnd->Slot.Bottom) < Interface.BorderThreshold) { + if (Math.Abs (e.Position.X - this.nativeHnd->Slot.X) < Interface.BorderThreshold) currentDirection = Direction.SW; - else if (Math.Abs (e.Position.X - this.Slot.Right) < Interface.BorderThreshold) + else if (Math.Abs (e.Position.X - this.nativeHnd->Slot.Right) < Interface.BorderThreshold) currentDirection = Direction.SE; else currentDirection = Direction.S; - } else if (Math.Abs (e.Position.X - this.Slot.X) < Interface.BorderThreshold) + } else if (Math.Abs (e.Position.X - this.nativeHnd->Slot.X) < Interface.BorderThreshold) currentDirection = Direction.W; - else if (Math.Abs (e.Position.X - this.Slot.Right) < Interface.BorderThreshold) + else if (Math.Abs (e.Position.X - this.nativeHnd->Slot.Right) < Interface.BorderThreshold) currentDirection = Direction.E; else currentDirection = Direction.None; @@ -322,10 +322,10 @@ namespace Crow } #endregion - protected void onMaximized (object sender, EventArgs e){ + unsafe protected void onMaximized (object sender, EventArgs e){ lock (CurrentInterface.LayoutMutex) { if (!IsMinimized) - savedBounds = this.LastPaintedSlot; + savedBounds = nativeHnd->LastPaintedSlot; this.Left = this.Top = 0; this.RegisterForLayouting (LayoutingType.Positioning); this.Width = this.Height = Measure.Stretched; @@ -356,10 +356,10 @@ namespace Crow Unmaximized.Raise (sender, e); } - protected void onMinimized (object sender, EventArgs e){ + unsafe protected void onMinimized (object sender, EventArgs e){ lock (CurrentInterface.LayoutMutex) { if (IsNormal) - savedBounds = this.LastPaintedSlot; + savedBounds = nativeHnd->LastPaintedSlot; Width = 200; Height = 20; Resizable = false; diff --git a/src/GraphicObjects/Wrapper.cs b/src/GraphicObjects/Wrapper.cs index 8b282ebb..e22b922d 100644 --- a/src/GraphicObjects/Wrapper.cs +++ b/src/GraphicObjects/Wrapper.cs @@ -38,7 +38,7 @@ namespace Crow { layoutType &= (~LayoutingType.Positioning); } - public override void ComputeChildrenPositions() + unsafe public override void ComputeChildrenPositions() { int dx = 0; int dy = 0; @@ -48,38 +48,38 @@ namespace Crow foreach (GraphicObject c in Children) { if (!c.Visible) continue; - if (dx + c.Slot.Width > ClientRectangle.Width) { + if (dx + c.nativeHnd->Slot.Width > ClientRectangle.Width) { dx = 0; dy += tallestChild + Spacing; - c.Slot.X = dx; - c.Slot.Y = dy; - tallestChild = c.Slot.Height; + c.nativeHnd->Slot.X = dx; + c.nativeHnd->Slot.Y = dy; + tallestChild = c.nativeHnd->Slot.Height; } else { - if (tallestChild < c.Slot.Height) - tallestChild = c.Slot.Height; - c.Slot.X = dx; - c.Slot.Y = dy; + if (tallestChild < c.nativeHnd->Slot.Height) + tallestChild = c.nativeHnd->Slot.Height; + c.nativeHnd->Slot.X = dx; + c.nativeHnd->Slot.Y = dy; } - dx += c.Slot.Width + Spacing; + dx += c.nativeHnd->Slot.Width + Spacing; } } else { int largestChild = 0; foreach (GraphicObject c in Children) { if (!c.Visible) continue; - if (dy + c.Slot.Height > ClientRectangle.Height) { + if (dy + c.nativeHnd->Slot.Height > ClientRectangle.Height) { dy = 0; dx += largestChild + Spacing; - c.Slot.X = dx; - c.Slot.Y = dy; - largestChild = c.Slot.Width; + c.nativeHnd->Slot.X = dx; + c.nativeHnd->Slot.Y = dy; + largestChild = c.nativeHnd->Slot.Width; } else { - if (largestChild < c.Slot.Width) - largestChild = c.Slot.Width; - c.Slot.X = dx; - c.Slot.Y = dy; + if (largestChild < c.nativeHnd->Slot.Width) + largestChild = c.nativeHnd->Slot.Width; + c.nativeHnd->Slot.X = dx; + c.nativeHnd->Slot.Y = dy; } - dy += c.Slot.Height + Spacing; + dy += c.nativeHnd->Slot.Height + Spacing; } } IsDirty = true; @@ -112,7 +112,7 @@ namespace Crow #endregion #region GraphicObject Overrides - protected override int measureRawSize (LayoutingType lt) + unsafe protected override int measureRawSize (LayoutingType lt) { int tmp = 0; //Wrapper can't fit in the opposite direction of the wrapper, this func is called only if Fit @@ -132,14 +132,14 @@ namespace Crow if (c.Height.Units == Unit.Percent && c.RegisteredLayoutings.HasFlag (LayoutingType.Height)) return -1; - if (dy + c.Slot.Height > ClientRectangle.Height) { + if (dy + c.nativeHnd->Slot.Height > ClientRectangle.Height) { dy = 0; tmp += largestChild + Spacing; - largestChild = c.Slot.Width; - } else if (largestChild < c.Slot.Width) - largestChild = c.Slot.Width; + largestChild = c.nativeHnd->Slot.Width; + } else if (largestChild < c.nativeHnd->Slot.Width) + largestChild = c.nativeHnd->Slot.Width; - dy += c.Slot.Height + Spacing; + dy += c.nativeHnd->Slot.Height + Spacing; } if (dy == 0) tmp -= Spacing; @@ -161,14 +161,14 @@ namespace Crow if (c.Width.Units == Unit.Percent && c.RegisteredLayoutings.HasFlag (LayoutingType.Width)) return -1; - if (dx + c.Slot.Width > ClientRectangle.Width) { + if (dx + c.nativeHnd->Slot.Width > ClientRectangle.Width) { dx = 0; tmp += tallestChild + Spacing; - tallestChild = c.Slot.Height; - } else if (tallestChild < c.Slot.Height) - tallestChild = c.Slot.Height; + tallestChild = c.nativeHnd->Slot.Height; + } else if (tallestChild < c.nativeHnd->Slot.Height) + tallestChild = c.nativeHnd->Slot.Height; - dx += c.Slot.Width + Spacing; + dx += c.nativeHnd->Slot.Width + Spacing; } if (dx == 0) tmp -= Spacing; diff --git a/src/Interface.cs b/src/Interface.cs index 90a757c5..6887c7dd 100644 --- a/src/Interface.cs +++ b/src/Interface.cs @@ -49,7 +49,7 @@ namespace Crow /// - Keyboard and Mouse logic /// - the resulting bitmap of the interface /// - public class Interface : ILayoutable + public class Interface : GraphicObject { #region CTOR static Interface(){ @@ -496,7 +496,7 @@ namespace Crow } /// Clipping Rectangles drive the drawing process. For compositing, each object under a clip rectangle should be /// repainted. If it contains also clip rectangles, its cache will be update, or if not cached a full redraw will take place - void processDrawing(){ + unsafe void processDrawing(){ #if MEASURE_TIME drawingMeasure.StartCycle(); #endif @@ -515,7 +515,7 @@ namespace Crow GraphicObject p = GraphicTree[i]; if (!p.Visible) continue; - if (clipping.Contains (p.Slot) == RegionOverlap.Out) + if (clipping.Contains (p.nativeHnd->Slot) == RegionOverlap.Out) continue; ctx.Save (); @@ -710,9 +710,9 @@ namespace Crow //check topmost graphicobject first GraphicObject tmp = HoverWidget; GraphicObject topc = null; - while (tmp is GraphicObject) { + while (!(tmp is Interface)) { topc = tmp; - tmp = tmp.LogicalParent as GraphicObject; + tmp = tmp.LogicalParent; } int idxhw = GraphicTree.IndexOf (topc); if (idxhw != 0) { @@ -722,7 +722,7 @@ namespace Crow if (GraphicTree [i].MouseIsIn (e.Position)) { while (HoverWidget != null) { HoverWidget.onMouseLeave (HoverWidget, e); - HoverWidget = HoverWidget.LogicalParent as GraphicObject; + HoverWidget = HoverWidget.LogicalParent; } GraphicTree [i].checkHoverWidget (e); @@ -739,8 +739,8 @@ namespace Crow } else { HoverWidget.onMouseLeave (HoverWidget, e); //seek upward from last focused graph obj's - while (HoverWidget.LogicalParent as GraphicObject != null) { - HoverWidget = HoverWidget.LogicalParent as GraphicObject; + while (!(HoverWidget.LogicalParent is Interface)) { + HoverWidget = HoverWidget.LogicalParent; if (HoverWidget.MouseIsIn (e.Position)) { HoverWidget.checkHoverWidget (e); return true; @@ -853,6 +853,13 @@ namespace Crow _focusedWidget.onKeyPress (this, e); return true; } + public override void onMouseMove (object sender, MouseMoveEventArgs e) {} + public override void onMouseUp (object sender, MouseButtonEventArgs e) {} + public override void onMouseDown (object sender, MouseButtonEventArgs e) {} + public override void onMouseClick (object sender, MouseButtonEventArgs e) {} + public override void onMouseDoubleClick (object sender, MouseButtonEventArgs e) {} + public override void onMouseWheel (object sender, MouseWheelEventArgs e) {} + #endregion #region Device Repeat Events @@ -882,41 +889,33 @@ namespace Crow } #endregion - #region ILayoutable implementation - public void RegisterClip(Rectangle r){ + public override void RegisterClip(Rectangle r){ clipping.UnionRectangle (r); } - public bool ArrangeChildren { get { return false; }} - public int LayoutingTries { - get { throw new NotImplementedException (); } + public override bool ArrangeChildren { get { return false; }} + public override void RegisterForLayouting (LayoutingType layoutType) { } + public override bool UpdateLayout (LayoutingType layoutType) { throw new NotImplementedException (); } + public override Rectangle ContextCoordinates (Rectangle r) { return r;} + public override Rectangle ScreenCoordinates (Rectangle r) { return r; } + public override GraphicObject Parent { + get { return null; } set { throw new NotImplementedException (); } } - public LayoutingType RegisteredLayoutings { - get { return LayoutingType.None; } - set { throw new NotImplementedException (); } + public override Rectangle ClientRectangle { + get { return clientRectangle; } } - public void RegisterForLayouting (LayoutingType layoutType) { throw new NotImplementedException (); } - public bool UpdateLayout (LayoutingType layoutType) { throw new NotImplementedException (); } - public Rectangle ContextCoordinates (Rectangle r) { return r;} - public Rectangle ScreenCoordinates (Rectangle r) { return r; } - - public ILayoutable Parent { - get { return null; } + public override Rectangle getSlot () { return ClientRectangle; } + public override Measure WidthPolicy { get { return Measure.Stretched; }} + public override Measure HeightPolicy { get { return Measure.Stretched; }} + public override Measure Width { set { throw new NotImplementedException (); } + get { return clientRectangle.Width; } } - public ILayoutable LogicalParent { - get { return null; } + public override Measure Height { set { throw new NotImplementedException (); } + get { return clientRectangle.Height; } } - - public Rectangle ClientRectangle { - get { return clientRectangle; } - } - public Interface HostContainer { - get { return this; } - } - public Rectangle getSlot () { return ClientRectangle; } - #endregion + public override bool MouseIsIn (Point m) => true; #if MEASURE_TIME public PerformanceMeasure clippingMeasure = new PerformanceMeasure("Clipping", 100); diff --git a/src/LayoutingQueueItem.cs b/src/LayoutingQueueItem.cs index 7f272d98..79140720 100644 --- a/src/LayoutingQueueItem.cs +++ b/src/LayoutingQueueItem.cs @@ -28,6 +28,7 @@ using System; using System.Diagnostics; using System.Collections.Generic; using System.Linq; +using System.Runtime.InteropServices; namespace Crow { @@ -48,10 +49,11 @@ namespace Crow /// /// Element class of the LayoutingQueue /// + [StructLayout(LayoutKind.Sequential)] public struct LayoutingQueueItem { /// Instance of widget to be layouted - public ILayoutable Layoutable; + public GraphicObject Layoutable; /// Bitfield containing the element of the layout to performs (x|y|width|height) public LayoutingType LayoutType; /// Unsuccessfull UpdateLayout and requeueing count @@ -78,7 +80,7 @@ namespace Crow #endif #region CTOR - public LayoutingQueueItem (LayoutingType _layoutType, ILayoutable _graphicObject) + public LayoutingQueueItem (LayoutingType _layoutType, GraphicObject _graphicObject) { LayoutType = _layoutType; Layoutable = _graphicObject; @@ -116,7 +118,7 @@ namespace Crow #endif if (LayoutingTries < Interface.MaxLayoutingTries) { Layoutable.RegisteredLayoutings |= LayoutType; - (Layoutable as GraphicObject).CurrentInterface.LayoutingQueue.Enqueue (this); + Layoutable.CurrentInterface.LayoutingQueue.Enqueue (this); } else if (DiscardCount < Interface.MaxDiscardCount) { #if DEBUG_LAYOUTING Debug.WriteLine ("\t\tDiscarded"); @@ -124,7 +126,7 @@ namespace Crow LayoutingTries = 0; DiscardCount++; Layoutable.RegisteredLayoutings |= LayoutType; - (Layoutable as GraphicObject).CurrentInterface.DiscardQueue.Enqueue (this); + Layoutable.CurrentInterface.DiscardQueue.Enqueue (this); } #if DEBUG_LAYOUTING else diff --git a/src/Measure.cs b/src/Measure.cs index 352ce8ff..c58acfe0 100644 --- a/src/Measure.cs +++ b/src/Measure.cs @@ -25,16 +25,18 @@ // THE SOFTWARE. using System; +using System.Runtime.InteropServices; namespace Crow { /// /// Measurement unit /// - public enum Unit { Pixel, Percent, Inherit } + public enum Unit : byte { Pixel, Percent, Inherit } /// /// Measure class allow proportional sizes as well as stretched and fit on content. /// + [StructLayout(LayoutKind.Sequential)] public struct Measure { /// diff --git a/testDrm/TestCrow.cs b/testDrm/TestCrow.cs index cfacae83..3eaa2656 100644 --- a/testDrm/TestCrow.cs +++ b/testDrm/TestCrow.cs @@ -26,6 +26,7 @@ using System; using Crow; using System.Runtime.InteropServices; +using System.Diagnostics; namespace testDrm { @@ -43,10 +44,25 @@ namespace testDrm unsafe static Rectangle* rect; unsafe static void Main(){ + const int count = 10000; rect = allocate(); - update (150, 160); - Console.WriteLine (rect->Height); - rect->Height = 200; + Console.WriteLine ("function update"); + Stopwatch sw = Stopwatch.StartNew (); + for (int i = 0; i < count; i++) { + update (150, 160); + } + sw.Stop (); + Console.WriteLine ("{0} updates in {1} ticks and {2} ms", count, sw.ElapsedTicks, sw.ElapsedMilliseconds); + + Console.WriteLine ("field update"); + sw.Restart (); + for (int i = 0; i < count; i++) { + rect->Height = 200; + rect->Width = 250; + } + sw.Stop (); + Console.WriteLine ("{0} updates in {1} ticks and {2} ms", count, sw.ElapsedTicks, sw.ElapsedMilliseconds); + Console.WriteLine (rect->Height); // Rectangle bounds = new Rectangle(0,0,1024,768); // Interface iface = new Interface(); diff --git a/testDrm/testDrm.csproj b/testDrm/testDrm.csproj index 27db51e6..2cf19157 100644 --- a/testDrm/testDrm.csproj +++ b/testDrm/testDrm.csproj @@ -19,13 +19,13 @@ - testDrm.TestCrow + testDrm.TestApp true full false - DEBUG; + DEBUG;MEASURE_TIME prompt 4 true diff --git a/testDrm/ui/2.crow b/testDrm/ui/2.crow index a56d079d..bad2daae 100755 --- a/testDrm/ui/2.crow +++ b/testDrm/ui/2.crow @@ -1,5 +1,5 @@  - +