<CheckForOverflowUnderflow>true</CheckForOverflowUnderflow>
<Optimize>false</Optimize>
<OutputPath>$(SolutionDir)build\Debug</OutputPath>
- <DefineConstants>TRACE0;DEBUG;DEBUG_BINDING_FUNC_CALLS0;DEBUG_DRAGNDROP0;DEBUG_LOG0;XLIB_BACKEND0;DESIGN_MODE;DEBUG_UPDATE0;DEBUG_FOCUS;DEBUG_DISPOSE0;MEASURE_TIME;DEBUG_LOAD0;DEBUG_BINDING0;DEBUG_CLIP_RECTANGLE0</DefineConstants>
+ <DefineConstants>TRACE0;DEBUG;DEBUG_BINDING_FUNC_CALLS0;DEBUG_DRAGNDROP0;DEBUG_LOG0;XLIB_BACKEND0;DESIGN_MODE;DEBUG_UPDATE0;DEBUG_FOCUS0;DEBUG_DISPOSE0;MEASURE_TIME;DEBUG_LOAD0;DEBUG_BINDING0;DEBUG_CLIP_RECTANGLE0</DefineConstants>
<EnvironmentVariables>
<EnvironmentVariables>
<Variable name="MONO_CAIRO_DEBUG_DISPOSE" value="1" />
Label {
Height = "Fit";
Width = "Fit";
- Margin = "0";
+ Margin = "1";
}
Menu {
Margin = "1";
Slider {
Background = "vgradient|0:Black|0.1:Grey|0.9:Grey|1:LightGrey";
Foreground = "Grey";
- Height = "10";
+ Height = "8";
Value="5";
}
Splitter {
Context gr = new Context (bmp);
if (!Clipping.IsEmpty) {
- for (int i = 0; i < Clipping.NumRectangles; i++)
- gr.Rectangle(Clipping.GetRectangle(i));
- gr.ClipPreserve();
- gr.Operator = Operator.Clear;
- gr.Fill();
- gr.Operator = Operator.Over;
+ Clipping.clearAndClip (gr);
base.onDraw (gr);
foreach (Widget c in Children) {
if (!c.Visible)
continue;
- if (Clipping.Contains (c.Slot + ClientRectangle.Position) == RegionOverlap.Out)
+ if (!Clipping.intersect (c.Slot + ClientRectangle.Position))
continue;
c.Paint (ref gr);
}
childrenRWLock.ExitReadLock ();
#if DEBUG_CLIP_RECTANGLE
- /*gr.LineWidth = 1;
- gr.SetSourceColor(Color.DarkMagenta.AdjustAlpha (0.8));
- for (int i = 0; i < Clipping.NumRectangles; i++)
- gr.Rectangle(Clipping.GetRectangle(i));
- gr.Stroke ();*/
+ gr.LineWidth = 1;
+ Clipping.stroke(gr,Color.DarkMagenta.AdjustAlpha (0.8));
+ gr.Stroke ();
#endif
}
gr.Dispose ();
ctx.SetSourceSurface (bmp, rb.X, rb.Y);
ctx.Paint ();
- Clipping.Dispose();
- Clipping = new Region ();
+ Clipping.Reset();
}
#endregion
Context gr = new Context (bmp);
if (!Clipping.IsEmpty) {
- for (int i = 0; i < Clipping.NumRectangles; i++)
- gr.Rectangle(Clipping.GetRectangle(i));
- gr.ClipPreserve();
- gr.Operator = Operator.Clear;
- gr.Fill();
- gr.Operator = Operator.Over;
+ Clipping.clearAndClip (gr);
onDraw (gr);
}
ctx.SetSourceSurface (bmp, rb.X, rb.Y);
ctx.Paint ();
- Clipping.Dispose();
- Clipping = new Region ();
+ Clipping.Reset ();
}
#endregion
NotifyValueChanged ("CursorColor", _cursorColor);
}
}
- [DefaultValue(20)]
+ [DefaultValue(10)]
public virtual int CursorSize {
get { return _cursorSize; }
set {
parentRWLock.ExitWriteLock();
} else
Debug.WriteLine ("!!! Finalized by GC: {0}", this.ToString ());
- Clipping?.Dispose ();
bmp?.Dispose ();
disposed = true;
}
/// are repeated at each cached levels of the tree with correspondig coordinate system. This is done
/// in a dedicated step of the update between layouting and drawing.
/// </summary>
- public Region Clipping;
+ public Rectangles Clipping = new Rectangles();
#region IValueChange implementation
/// <summary>
/// action.
/// </summary>
protected Widget () {
- Clipping = new Region ();
#if DEBUG_LOG
GraphicObjects.Add (this);
DebugLog.AddEvent(DbgEvtType.GOClassCreation, this);
/// <summary>
/// Font being used in many controls, it is defined in the base GraphicObject class.
/// </summary>
- [DesignCategory ("Appearance")][DefaultValue("sans, 12")]
+ [DesignCategory ("Appearance")][DefaultValue("droid, 10")]
public virtual Font Font {
get { return font; }
set {
if (r.Bottom > cb.Bottom)
r.Height -= r.Bottom - cb.Bottom;
if (cacheEnabled && !IsDirty)
- Clipping.UnionRectangle (r);
+ Clipping.AddRectangle (r);
if (Parent == null)
return;
Widget p = Parent as Widget;
ctx.SetSourceSurface (bmp, rb.X, rb.Y);
ctx.Paint ();
- Clipping.Dispose ();
- Clipping = new Region ();
+ Clipping.Reset ();
#if DEBUG_LOG
dbgEvt.end = DebugLog.chrono.ElapsedTicks;
#endif
public int DragImageWidth, DragImageHeight, DragImageX, DragImageY;
public void ClearDragImage () {
lock (UpdateMutex) {
- clipping.UnionRectangle(new Rectangle (DragImageX, DragImageY, DragImageWidth, DragImageHeight));
+ clipping.AddRectangle(new Rectangle (DragImageX, DragImageY, DragImageWidth, DragImageHeight));
DragImage.Dispose();
DragImage = null;
}
/// <summary>Client rectangle in the host context</summary>
protected Rectangle clientRectangle;
/// <summary>Clipping rectangles on the root context</summary>
- Region clipping = new Region();
+ Rectangles clipping = new Rectangles();
/// <summary>Main Cairo context</summary>
Context ctx;
#endregion
DebugLog.AddEvent (DbgEvtType.IFaceStartDrawing);
#endif
if (DragImage != null)
- clipping.UnionRectangle(new Rectangle (DragImageX, DragImageY, DragImageWidth, DragImageHeight));
+ clipping.AddRectangle(new Rectangle (DragImageX, DragImageY, DragImageWidth, DragImageHeight));
using (surf = new ImageSurface (bmp, Format.Argb32, ClientRectangle.Width, ClientRectangle.Height, ClientRectangle.Width * 4)) {
using (ctx = new Context (surf)) {
if (!clipping.IsEmpty) {
IsDirty = true;
- 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;
+ clipping.clearAndClip (ctx);
for (int i = GraphicTree.Count - 1; i >= 0; i--) {
Widget p = GraphicTree[i];
if (!p.Visible)
continue;
- if (clipping.Contains (p.Slot) == RegionOverlap.Out)
+ if (!clipping.intersect (p.Slot))
continue;
ctx.Save ();
#if DEBUG_CLIP_RECTANGLE
ctx.LineWidth = 1;
- ctx.SetSourceColor(Color.Magenta.AdjustAlpha (0.5));
- for (int i = 0; i < clipping.NumRectangles; i++)
- ctx.Rectangle(clipping.GetRectangle(i));
+ clipping.stroke (ctx, Color.Magenta.AdjustAlpha (0.5));
ctx.Stroke ();
#endif
- clipping.Dispose ();
- clipping = new Region ();
+ clipping.Reset ();
//}
//surf.WriteToPng (@"/mnt/data/test.png");
return true;
}
public void RegisterClip(Rectangle r){
- clipping.UnionRectangle (r);
+ clipping.AddRectangle (r);
}
public bool ArrangeChildren { get { return false; }}
public int LayoutingTries {
--- /dev/null
+//
+// Rectangles.cs
+//
+// Author:
+// Jean-Philippe Bruyère <jp.bruyere@hotmail.com>
+//
+// 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.Collections.Generic;
+using Crow.Cairo;
+
+namespace Crow {
+ public class Rectangles
+ {
+ public List<Rectangle> list = new List<Rectangle>();
+ public int count
+ {
+ get { return list.Count; }
+ }
+ public bool IsEmpty => list.Count == 0;
+
+ public void AddRectangle(Rectangle r)
+ {
+ if (doesNotContain (r)) {
+ list.Add (r);
+ boundsUpToDate = false;
+ }
+ }
+ public void Reset()
+ {
+ list = new List<Rectangle>();
+ _bounds = Rectangle.Empty;
+ boundsUpToDate = true;
+ }
+ bool doesNotContain(Rectangle r)
+ {
+ foreach (Rectangle rInList in list)
+ if (rInList.ContainsOrIsEqual(r))
+ return false;
+ return true;
+ }
+
+ public bool intersect(Rectangle r)
+ {
+ foreach (Rectangle rInList in list)
+ if (rInList.Intersect(r))
+ return true;
+ return false;
+ }
+ public void stroke(Context ctx, Color c)
+ {
+ foreach (Rectangle r in list)
+ ctx.Rectangle(r);
+
+ ctx.SetSourceColor(c);
+
+ ctx.LineWidth = 2;
+ ctx.Stroke ();
+ }
+ public void clearAndClip(Context ctx)
+ {
+ if (list.Count == 0)
+ return;
+ foreach (Rectangle r in list)
+ ctx.Rectangle(r);
+
+ ctx.ClipPreserve();
+ ctx.Operator = Operator.Clear;
+ ctx.Fill();
+ ctx.Operator = Operator.Over;
+ }
+
+ public void clip(Context ctx)
+ {
+ foreach (Rectangle r in list)
+ ctx.Rectangle(r);
+
+ ctx.Clip();
+ }
+
+ Rectangle _bounds;
+ bool boundsUpToDate = true;
+ public Rectangle Bounds {
+ get {
+ if (!boundsUpToDate) {
+ if (list.Count > 0) {
+ _bounds = list [0];
+ for (int i = 1; i < list.Count; i++) {
+ _bounds += list [i];
+ }
+ } else
+ _bounds = Rectangle.Empty;
+ boundsUpToDate = true;
+ }
+ return _bounds;
+ }
+ }
+ public void clear(Context ctx)
+ {
+ foreach (Rectangle r in list)
+ ctx.Rectangle(r);
+ ctx.Operator = Operator.Clear;
+ ctx.Fill();
+ ctx.Operator = Operator.Over;
+ }
+ public override string ToString ()
+ {
+ string tmp = "";
+ foreach (Rectangle r in list) {
+ tmp += r.ToString ();
+ }
+ return tmp;
+ }
+ }
+}