#region PINVOKE
const string lib = "libcrow";
[DllImport(lib, CallingConvention = CallingConvention.Cdecl)]
- unsafe internal static extern IntPtr crow_context_create ();
+ internal static extern IntPtr crow_context_create ();
[DllImport(lib, CallingConvention = CallingConvention.Cdecl)]
- unsafe internal static extern void crow_context_destroy (IntPtr ctx);
+ internal static extern void crow_context_destroy (IntPtr ctx);
[DllImport(lib, CallingConvention = CallingConvention.Cdecl)]
- unsafe internal static extern void crow_context_process_layouting (IntPtr layCtx);
+ unsafe internal static extern void crow_context_set_root (IntPtr ctx, crow_object_t* root);
[DllImport(lib, CallingConvention = CallingConvention.Cdecl)]
- unsafe internal static extern void crow_context_process_clipping (IntPtr ctx);
+ internal static extern void crow_context_process_layouting (IntPtr ctx);
+ [DllImport(lib, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void crow_context_process_clipping (IntPtr ctx);
+ [DllImport(lib, CallingConvention = CallingConvention.Cdecl)]
+ internal static extern void crow_context_process_drawing (IntPtr ctx, IntPtr cairoCtx);
[DllImport(lib)]
unsafe internal static extern crow_object_t* crow_object_create();
[DllImport(lib, CallingConvention = CallingConvention.Cdecl)]
unsafe internal static extern byte crow_object_do_layout (crow_object_t* go, LayoutingType layout);
[DllImport(lib, CallingConvention = CallingConvention.Cdecl)]
- unsafe internal static extern void crow_object_register_layouting (crow_object_t* go, LayoutingType layout);
+ unsafe internal static extern byte crow_object_register_layouting (crow_object_t* go, LayoutingType layout);
+
+
+ [DllImport(lib, CallingConvention = CallingConvention.Cdecl)]
+ unsafe internal static extern void crow_object_child_add (crow_object_t* parent, crow_object_t* child);
+ [DllImport(lib, CallingConvention = CallingConvention.Cdecl)]
+ unsafe internal static extern void crow_object_child_remove (crow_object_t* parent, crow_object_t* child);
#endregion
}
}
public int ChildrenCount;
public crow_object_t* Parent;
public crow_object_t** Children;
+ public crow_object_t* LargestChild;
+ public crow_object_t* TallestChild;
public int Left;
public int Top;
public Measure Width;
public int Margin;
public Size MinimumSize;
public Size MaximumSize;
+ public IntPtr Background;
public byte Visible;
/// <summary>if true, content has to be recreated</summary>
public byte IsDirty;
public byte InClippingPool;
+ public byte CacheEnabled;
public IntPtr Clipping;
public LayoutingType RegisteredLayoutings;
+ public Size ContentSize;
/// <summary>
/// Current size and position computed during layouting pass
/// </summary>
public Rectangle Slot;
- public Size ContentSize;
/// <summary>
/// keep last slot components for each layouting pass to track
/// changes and trigger update of other component accordingly
public IntPtr OnLayoutChanged;
public IntPtr OnChildLayoutChanged;
public IntPtr ChildrenLayoutingConstraints;
+ public IntPtr UpdateCache;
public IntPtr OnDraw;
-
}
}
\ No newline at end of file
unloadDialog ((sender as GraphicObject).CurrentInterface);
}
void unloadDialog(Interface host){
- host.DeleteWidget (this);
+ host.RemoveChild (this);
}
}
}
#region CTOR
public GraphicObject ()
{
+ initLibcrow ();
+ #if DEBUG
+ uid = currentUid;
+ currentUid++;
+ #endif
+ }
+ protected virtual void initLibcrow (){
unsafe {
nativeHnd = LibCrow.crow_object_create ();
LibCrow.crow_object_set_type (nativeHnd, CrowType.Simple);
nativeHnd->Context = Interface.CurrentInterface.layoutingCtx;
+ nativeHnd->IsDirty = 1;
//nativeHnd->OnLayoutChanged = Marshal.GetFunctionPointerForDelegate((LayoutChangedCallBack)OnLayoutChanges);
}
- #if DEBUG
- uid = currentUid;
- currentUid++;
- #endif
- }
- internal protected GraphicObject (bool isInterface){
}
#endregion
bool isActive = false;
bool mouseRepeat;
bool isEnabled = true;
- bool cacheEnabled = false;
bool clipToClientRect = true;
protected object dataSource;
string style;
DataSourceChangeEventArgs e = new DataSourceChangeEventArgs (parent, value);
lock (this) {
parent = value;
- if (parent == null)
- nativeHnd->Parent = null;
- else
- nativeHnd->Parent = value.nativeHnd;
+// if (parent == null)
+// nativeHnd->Parent = null;
+// else
+// nativeHnd->Parent = value.nativeHnd;
}
onParentChanged (this, e);
/// speeding up rendering of complex object. Default is enabled.
/// </summary>
[XmlAttributeAttribute][DefaultValue(true)]
- public virtual bool CacheEnabled {
- get { return cacheEnabled; }
+ unsafe public virtual bool CacheEnabled {
+ get { return nativeHnd->CacheEnabled>0; }
set {
- if (cacheEnabled == value)
+ if (CacheEnabled == value)
return;
- cacheEnabled = value;
- NotifyValueChanged ("CacheEnabled", cacheEnabled);
+ if (value)
+ nativeHnd->CacheEnabled = 1;
+ else
+ nativeHnd->CacheEnabled = 0;
+ NotifyValueChanged ("CacheEnabled", CacheEnabled);
}
}
/// <summary>
}
bool clearBackground = false;
[XmlAttributeAttribute()][DefaultValue("Transparent")]
- public virtual Fill Background {
+ unsafe public virtual Fill Background {
get { return background; }
set {
if (background == value)
return;
clearBackground = false;
+ if (nativeHnd->Background != IntPtr.Zero) {
+ Cairo.NativeMethods.cairo_pattern_destroy (nativeHnd->Background);
+ nativeHnd->Background = IntPtr.Zero;
+ }
if (value == null)
return;
background = value;
+ SolidColor sc = value as SolidColor;
+ if (sc != null) {
+ nativeHnd->Background = Cairo.NativeMethods.cairo_pattern_create_rgba (
+ sc.color.R, sc.color.G, sc.color.B, sc.color.A);
+ }
NotifyValueChanged ("Background", background);
RegisterForRedraw ();
- if (background is SolidColor) {
- if ((Background as SolidColor).Equals (Color.Clear))
- clearBackground = true;
- }
}
}
[XmlAttributeAttribute()][DefaultValue("White")]
if (nativeHnd->Slot.Height < 0 || nativeHnd->Slot.Width < 0 || parent == null)
return;
lock (this) {
- if (cacheEnabled) {
+ if (CacheEnabled) {
if (nativeHnd->Slot.Width > Interface.MaxCacheSize || nativeHnd->Slot.Height > Interface.MaxCacheSize)
- cacheEnabled = false;
+ CacheEnabled = false;
}
- if (cacheEnabled) {
+ if (CacheEnabled) {
if (IsDirty)
RecreateCache ();
using Cairo;
using System.Diagnostics;
using System.Reflection;
+using Crow.Native;
namespace Crow
: base(){}
#endregion
+ protected override void initLibcrow ()
+ {
+ unsafe {
+ nativeHnd = LibCrow.crow_object_create ();
+ LibCrow.crow_object_set_type (nativeHnd, CrowType.Group);
+ nativeHnd->IsDirty = 1;
+ nativeHnd->Context = Interface.CurrentInterface.layoutingCtx;
+ }
+ }
+
#region EVENT HANDLERS
public event EventHandler<EventArgs> ChildrenCleared;
#endregion
}
public virtual void AddChild(GraphicObject g){
lock (children) {
+ unsafe {
+ LibCrow.crow_object_child_add (this.nativeHnd, g.nativeHnd);
+ }
g.Parent = this;
Children.Add (g);
}
lock (Interface.CurrentInterface.UpdateMutex) {
MessageBox mb = new MessageBox ();
mb.Initialize ();
- mb.CurrentInterface.AddWidget (mb);
+ mb.CurrentInterface.AddChild (mb);
mb.MsgType = msgBoxType;
mb.Message = message;
if (!string.IsNullOrEmpty(okMsg))
if (Content != null) {
Content.Visible = true;
if (Content.Parent == null)
- CurrentInterface.AddWidget (Content, true);
+ CurrentInterface.AddChild (Content);
if (Content.LogicalParent != this)
Content.LogicalParent = this;
- CurrentInterface.PutOnTop (Content, true);
+ //CurrentInterface.PutOnTop (Content, true);
_content_LayoutChanged (this, new LayoutingEventArgs (LayoutingType.Sizing));
}
Popped.Raise (this, e);
return;
alwaysOnTop = value;
- if (alwaysOnTop && Parent != null)
- CurrentInterface.PutOnTop (this);
+// if (alwaysOnTop && Parent != null)
+// CurrentInterface.PutOnTop (this);
NotifyValueChanged ("AlwaysOnTop", alwaysOnTop);
}
protected void close(){
Closing.Raise (this, null);
- CurrentInterface.DeleteWidget (this);
+ CurrentInterface.RemoveChild (this);
}
}
}
/// - Keyboard and Mouse logic
/// - the resulting bitmap of the interface
/// </summary>
- public class Interface : GraphicObject
+ public class Interface : Group
{
#region CTOR
static Interface(){
FontRenderingOptions.HintStyle = HintStyle.Medium;
FontRenderingOptions.SubpixelOrder = SubpixelOrder.Rgb;
}
- public Interface() : base (true){
+ public Interface() : base (){
+ CacheEnabled = true;
+ CultureInfo.DefaultThreadCurrentCulture = System.Globalization.CultureInfo.InvariantCulture;
+ }
+ protected override void initLibcrow ()
+ {
CurrentInterface = this;
layoutingCtx = LibCrow.crow_context_create ();
- unsafe {
- nativeHnd = LibCrow.crow_object_create ();
- }
- CultureInfo.DefaultThreadCurrentCulture = System.Globalization.CultureInfo.InvariantCulture;
+ base.initLibcrow ();
+
+ unsafe {
+ LibCrow.crow_context_set_root (layoutingCtx, nativeHnd);
+ //nativeHnd->Background = Cairo.NativeMethods.cairo_pattern_create_rgb (1, 0, 1);
+ }
}
#endregion
{
lock (UpdateMutex) {
GraphicObject tmp = Load (path);
- AddWidget (tmp);
+ AddChild (tmp);
return tmp;
}
#if MEASURE_TIME
clippingMeasure.StartCycle();
#endif
- LibCrow.crow_context_process_layouting (layoutingCtx);
+ LibCrow.crow_context_process_clipping (layoutingCtx);
#if MEASURE_TIME
clippingMeasure.StopCycle();
#endif
drawingMeasure.StartCycle();
#endif
using (surf = new ImageSurface (bmp, Format.Argb32, ClientRectangle.Width, ClientRectangle.Height, ClientRectangle.Width * 4)) {
- using (ctx = new Context (surf)){
- if (!clipping.IsEmpty) {
-
- for (int i = 0; i < clipping.NumRectangles; i++)
- ctx.Rectangle(clipping.GetRectangle(i));
- ctx.ClipPreserve();
- ctx.Operator = Operator.Clear;
- ctx.Fill();
- ctx.Operator = Operator.Over;
-
- for (int i = GraphicTree.Count -1; i >= 0 ; i--){
- GraphicObject p = GraphicTree[i];
- if (!p.Visible)
- continue;
- if (clipping.Contains (p.nativeHnd->Slot) == RegionOverlap.Out)
- continue;
-
- ctx.Save ();
- p.Paint (ref ctx);
- ctx.Restore ();
- }
-
- #if DEBUG_CLIP_RECTANGLE
- clipping.stroke (ctx, Color.Red.AdjustAlpha(0.5));
- #endif
- lock (RenderMutex) {
-// Array.Copy (bmp, dirtyBmp, bmp.Length);
-
- IsDirty = true;
- if (IsDirty)
- DirtyRect += clipping.Extents;
- else
- DirtyRect = clipping.Extents;
-
- DirtyRect.Left = Math.Max (0, DirtyRect.Left);
- DirtyRect.Top = Math.Max (0, DirtyRect.Top);
- DirtyRect.Width = Math.Min (ClientRectangle.Width - DirtyRect.Left, DirtyRect.Width);
- DirtyRect.Height = Math.Min (ClientRectangle.Height - DirtyRect.Top, DirtyRect.Height);
- DirtyRect.Width = Math.Max (0, DirtyRect.Width);
- DirtyRect.Height = Math.Max (0, DirtyRect.Height);
-
- if (DirtyRect.Width > 0 && DirtyRect.Height >0) {
- dirtyBmp = new byte[4 * DirtyRect.Width * DirtyRect.Height];
- for (int y = 0; y < DirtyRect.Height; y++) {
- Array.Copy (bmp,
- ((DirtyRect.Top + y) * ClientRectangle.Width * 4) + DirtyRect.Left * 4,
- dirtyBmp, y * DirtyRect.Width * 4, DirtyRect.Width * 4);
- }
-
- } else
- IsDirty = false;
- }
- clipping.Dispose ();
- clipping = new Region ();
- }
- //surf.WriteToPng (@"/mnt/data/test.png");
+ using (ctx = new Context (surf)) {
+ LibCrow.crow_context_process_drawing (layoutingCtx, ctx.Handle);
}
}
#if MEASURE_TIME
}
#endregion
- #region GraphicTree handling
- /// <summary>Add widget to the Graphic tree of this interface and register it for layouting</summary>
- public void AddWidget(GraphicObject g, bool isOverlay = false)
- {
- g.Parent = this;
- int ptr = 0;
- Window newW = g as Window;
- if (newW != null) {
- while (ptr < GraphicTree.Count) {
- Window w = GraphicTree [ptr] as Window;
- if (w != null) {
- if (newW.AlwaysOnTop || !w.AlwaysOnTop)
- break;
- }
- ptr++;
- }
- }
-
- lock (UpdateMutex)
- GraphicTree.Insert (ptr, g);
-
- g.RegisteredLayoutings = LayoutingType.None;
- g.RegisterForLayouting (LayoutingType.Sizing | LayoutingType.ArrangeChildren);
- }
- /// <summary>Set visible state of widget to false and remove if from the graphic tree</summary>
- public void DeleteWidget(GraphicObject g)
- {
- if (_hoverWidget != null) {
- if (g.Contains (_hoverWidget))
- HoverWidget = null;
- }
- lock (UpdateMutex) {
- g.DataSource = null;
- g.Visible = false;
- GraphicTree.Remove (g);
- }
- }
- /// <summary> Put widget on top of other root widgets</summary>
- public void PutOnTop(GraphicObject g, bool isOverlay = false)
- {
- int ptr = 0;
- Window newW = g as Window;
- if (newW != null) {
- while (ptr < GraphicTree.Count) {
- Window w = GraphicTree [ptr] as Window;
- if (w != null) {
- if (newW.AlwaysOnTop || !w.AlwaysOnTop)
- break;
- }
- ptr++;
- }
- }
- if (GraphicTree.IndexOf(g) > ptr)
- {
- lock (UpdateMutex) {
- GraphicTree.Remove (g);
- GraphicTree.Insert (ptr, g);
- }
- EnqueueForRepaint (g);
- }
- }
- /// <summary> Remove all Graphic objects from top container </summary>
- public void ClearInterface()
- {
- lock (UpdateMutex) {
- while (GraphicTree.Count > 0) {
- //TODO:parent is not reset to null because object will be added
- //to ObjectToRedraw list, and without parent, it fails
- GraphicObject g = GraphicTree [0];
- g.DataSource = null;
- g.Visible = false;
- GraphicTree.RemoveAt (0);
- }
- }
- #if DEBUG_LAYOUTING
- LQIsTries = new List<LQIList>();
- curLQIsTries = new LQIList();
- LQIs = new List<LQIList>();
- curLQIs = new LQIList();
- #endif
- }
-
- /// <summary>Search a Graphic object in the tree named 'nameToFind'</summary>
- public GraphicObject FindByName (string nameToFind)
- {
- foreach (GraphicObject w in GraphicTree) {
- GraphicObject r = w.FindByName (nameToFind);
- if (r != null)
- return r;
- }
- return null;
- }
- #endregion
-
public void ProcessResize(Rectangle bounds){
lock (UpdateMutex) {
unsafe {
GraphicObject g = GraphicTree [i];
if (g.MouseIsIn (e.Position)) {
g.checkHoverWidget (e);
- if (g is Window)
- PutOnTop (g);
+// if (g is Window)
+// PutOnTop (g);
return true;
}
}
static void Main(){
using (Interface iface = new Interface ()) {
+ Console.WriteLine ("is dirty: {0}", iface.IsDirty);
iface.ProcessResize (new Rectangle (0, 0, 1024, 768));
iface.LoadInterface ("#testDrm.ui.go.crow");
iface.Update ();
<Compile Include="src\Linux\Bindings\Udev.cs" />
<Compile Include="src\Linux\Signal.cs" />
<Compile Include="src\Application.cs" />
- <Compile Include="Main.cs" />
- <Compile Include="tests.cs" />
<Compile Include="testLibInput.cs" />
<Compile Include="src\EVDEV\Device.cs" />
<Compile Include="src\Linux\Bindings\EvdevClass.cs" />
<Compile Include="src\Linux\DRIControler.cs" />
<Compile Include="testCairo.cs" />
<Compile Include="TestCrow.cs" />
- <Compile Include="Showcase.cs" />
</ItemGroup>
<ItemGroup>
<Reference Include="System" />
<EmbeddedResource Include="ui\go.crow" />
<EmbeddedResource Include="ui\showcase.crow" />
</ItemGroup>
+ <ItemGroup>
+ <None Include="Main.cs" />
+ <None Include="tests.cs" />
+ <None Include="Showcase.cs" />
+ </ItemGroup>
</Project>
\ No newline at end of file
<?xml version="1.0"?>
-<GraphicObject Width="Stretched" Height="Stretched" Background="Mantis"/>
\ No newline at end of file
+<Group Margin="50" Width="Stretched" Height="Stretched" Background="DimGray">
+ <Group Margin="100" Background="Jet" Width="Stretched" Height="Stretched">
+ <GraphicObject Margin="50" Width="Stretched" Height="100" Background="Mantis"/>
+ <GraphicObject Margin="50" Width="Stretched" Height="100" Background="Maize" VerticalAlignment="Bottom"/>
+ </Group>
+</Group>
\ No newline at end of file