aboutsummaryrefslogtreecommitdiffstatsci
path: root/src/GraphicObjects/GraphicObject.cs
diff options
context:
space:
mode:
authorjpbruyere <jp.bruyere@hotmail.com>2017-05-27 18:35:01 +0200
committerjpbruyere <jp.bruyere@hotmail.com>2017-05-27 18:35:01 +0200
commit4d1f3264dc4b4ddc211164712e0d2d654a913bb7 (patch)
tree30655ea8f740eaf115a06c2ebfaaad29a7bcb39e /src/GraphicObjects/GraphicObject.cs
parent8d385b053423c16e18d02467bdd54be17c3b42aa (diff)
c native GraphicObject implementation, work in progressTestKMS
Diffstat (limited to 'src/GraphicObjects/GraphicObject.cs')
-rw-r--r--src/GraphicObjects/GraphicObject.cs456
1 files changed, 253 insertions, 203 deletions
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;
+ /// <summary>
+ /// Current size and position computed during layouting pass
+ /// </summary>
+ public Rectangle Slot;
+ /// <summary>
+ /// keep last slot components for each layouting pass to track
+ /// changes and trigger update of other component accordingly
+ /// </summary>
+ public Rectangle LastSlot;
+ /// <summary>
+ /// 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
+ /// </summary>
+ 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<ValueChangeEventArgs> 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
/// <summary>
- /// Current size and position computed during layouting pass
- /// </summary>
- public Rectangle Slot = new Rectangle ();
- /// <summary>
- /// keep last slot components for each layouting pass to track
- /// changes and trigger update of other component accordingly
+ /// The clipping rectangles list
/// </summary>
- public Rectangle LastSlots;
- /// <summary>
- /// 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
- /// </summary>
- public Rectangle LastPaintedSlot;
+ public Region Clipping = new Region();
/// <summary>Prevent requeuing multiple times the same widget</summary>
public bool IsQueueForRedraw = false;
/// <summary>drawing Cache bitmap</summary>
@@ -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
/// <summary>
/// Parent in the graphic tree, used for rendering and layouting
/// </summary>
- [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;
+ }
+ }
/// <summary>Random value placeholder</summary>
[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
/// <summary>
/// Register old and new slot for clipping
/// </summary>
- 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);
}
/// <summary>
/// Add clip rectangle to this.clipping and propagate up to root
/// </summary>
/// <param name="clip">Clip rectangle</param>
- 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);
}
/// <summary> Full update, taking care of sizing policy </summary>
[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 </summary>
/// <returns><c>true</c>, if layouting was possible, <c>false</c> if conditions were not
/// met and LQI has to be re-queued</returns>
- 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
/// <summary> This is the common overridable drawing routine to create new widget </summary>
- 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
/// <summary>
/// Internal drawing context creation on a cached surface limited to slot size
/// this trigger the effective drawing routine </summary>
- 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
}
/// <summary> Chained painting routine on the parent context of the actual cached version
/// of the widget </summary>
- 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
}
}