Re: [Mono-winforms-list] [Patch] Invalidate non visible areas in scrolling

2008-01-21 Thread Jonathan Pobst
Sure, either will work.  In the current implementation, bmp_g will never 
be null anyways, because it is instantiated when it is declared. 
However, in the future, I want to make the variable ThreadStatic so it 
is thread safe.  Then this getter will come into play.

Jon


Geoff Norton wrote:
> Jon,
> 
>   You implemented this as:
> 
> if (bmp_g == null) {
> bmp = new Bitmap (1, 1, 
> System.Drawing.Imaging.PixelFormat.Format32bppArgb);
> bmp_g = Graphics.FromImage (bmp);
> }
> 
> We should likely switch this to
> 
> if (bmp_g == null) {
> bmp_g = Graphics.FromHwnd (IntPtr.Zero);
> }
> 
> (and rename bmp_g to root_g or some such).
> 
> Our implementation currently wont matter for this for things like dpi; 
> but device independent scaling int he future will likely work better in 
> the latter case.
> 
> Thoughts?
> 
> -g
> 
> ps> I just commited the support today for mac/x11 support of that Hwnd case
> 
> On 21-Jan-08, at 8:25 PM, Jonathan Pobst wrote:
> 
>> I just added a public property called Hwnd.GraphicsContext that is a
>> cached Graphics we keep around for measuring and such.  If you don't
>> need a specific Graphics, you can just use this one.
>>
>> Jon
>>
>>
>> Carlos Alberto Cortez wrote:
>>> Hey Chris,
>>>
>>> Attached is an updated patch that basically incorporates all the things
>>> you mentioned in your last mail:
>>>
>>> * Determines the visible rectangle, and intersects it with the required
>>> area (this is, we copy only the visible area).
>>> - First by determining the visible area based on its size and its
>>> parents.
>>> - Second, by looking for toplevel windows that intersect the window,
>>> and excluding that area.
>>>
>>> * Then compute the destination rectangle, by applying the
>>> XAmount/YAmount values and intersecting it with the area passed to
>>> ScrollWindow (thus we clip it as needed). This is the way Gdk does it.
>>>
>>> * Finally, exclude the destination rectangle from the total requested
>>> area, and pass it to AddExpose method.
>>>
>>> With this patch everyting is working as expected, but I have some
>>> issues:
>>>
>>> * Region needs a Graphics instance to return its Bounds, which *could*
>>> be expensive.
>>> * After taking a look at the way scrolling is done in Gdk, it *seems*
>>> that the Region implementation lack some of the functionality we need
>>> (like, returning in a simple operation the Rectangles describing the
>>> region).
>>>
>>> Comments?
>>>
>>> Carlos.
>>>
>>>
>>> 
>>>
>>> ___
>>> Mono-winforms-list maillist  -  Mono-winforms-list@lists.ximian.com
>>> http://lists.ximian.com/mailman/listinfo/mono-winforms-list
>>
>> ___
>> Mono-winforms-list maillist  -  Mono-winforms-list@lists.ximian.com
>> http://lists.ximian.com/mailman/listinfo/mono-winforms-list
> 
> 
> 

___
Mono-winforms-list maillist  -  Mono-winforms-list@lists.ximian.com
http://lists.ximian.com/mailman/listinfo/mono-winforms-list


Re: [Mono-winforms-list] [Patch] Invalidate non visible areas in scrolling

2008-01-21 Thread Geoff Norton
Jon,

   You implemented this as:

 if (bmp_g == null) {
 bmp = new Bitmap (1, 1,  
System.Drawing.Imaging.PixelFormat.Format32bppArgb);
 bmp_g = Graphics.FromImage  
(bmp);
 }

We should likely switch this to

if (bmp_g == null) {
bmp_g = Graphics.FromHwnd (IntPtr.Zero);
}

(and rename bmp_g to root_g or some such).

Our implementation currently wont matter for this for things like dpi;  
but device independent scaling int he future will likely work better  
in the latter case.

Thoughts?

-g

ps> I just commited the support today for mac/x11 support of that Hwnd  
case

On 21-Jan-08, at 8:25 PM, Jonathan Pobst wrote:

> I just added a public property called Hwnd.GraphicsContext that is a
> cached Graphics we keep around for measuring and such.  If you don't
> need a specific Graphics, you can just use this one.
>
> Jon
>
>
> Carlos Alberto Cortez wrote:
>> Hey Chris,
>>
>> Attached is an updated patch that basically incorporates all the  
>> things
>> you mentioned in your last mail:
>>
>> * Determines the visible rectangle, and intersects it with the  
>> required
>> area (this is, we copy only the visible area).
>>  - First by determining the visible area based on its size and its
>> parents.
>>  - Second, by looking for toplevel windows that intersect the window,
>> and excluding that area.
>>
>> * Then compute the destination rectangle, by applying the
>> XAmount/YAmount values and intersecting it with the area passed to
>> ScrollWindow (thus we clip it as needed). This is the way Gdk does  
>> it.
>>
>> * Finally, exclude the destination rectangle from the total requested
>> area, and pass it to AddExpose method.
>>
>> With this patch everyting is working as expected, but I have some
>> issues:
>>
>> * Region needs a Graphics instance to return its Bounds, which  
>> *could*
>> be expensive.
>> * After taking a look at the way scrolling is done in Gdk, it *seems*
>> that the Region implementation lack some of the functionality we need
>> (like, returning in a simple operation the Rectangles describing the
>> region).
>>
>> Comments?
>>
>> Carlos.
>>
>>
>> 
>>
>> ___
>> Mono-winforms-list maillist  -  Mono-winforms-list@lists.ximian.com
>> http://lists.ximian.com/mailman/listinfo/mono-winforms-list
>
> ___
> Mono-winforms-list maillist  -  Mono-winforms-list@lists.ximian.com
> http://lists.ximian.com/mailman/listinfo/mono-winforms-list

___
Mono-winforms-list maillist  -  Mono-winforms-list@lists.ximian.com
http://lists.ximian.com/mailman/listinfo/mono-winforms-list


Re: [Mono-winforms-list] [Patch] Invalidate non visible areas in scrolling

2008-01-21 Thread Carlos Alberto Cortez
Ah!, perfect!

We wll be using that one, instead.

Carlos.


El lun, 21-01-2008 a las 19:25 -0600, Jonathan Pobst escribió:
> I just added a public property called Hwnd.GraphicsContext that is a 
> cached Graphics we keep around for measuring and such.  If you don't 
> need a specific Graphics, you can just use this one.
> 
> Jon
> 
> 
> Carlos Alberto Cortez wrote:
> > Hey Chris,
> > 
> > Attached is an updated patch that basically incorporates all the things
> > you mentioned in your last mail:
> > 
> > * Determines the visible rectangle, and intersects it with the required
> > area (this is, we copy only the visible area).
> > - First by determining the visible area based on its size and its
> > parents.
> > - Second, by looking for toplevel windows that intersect the window,
> > and excluding that area.
> > 
> > * Then compute the destination rectangle, by applying the
> > XAmount/YAmount values and intersecting it with the area passed to
> > ScrollWindow (thus we clip it as needed). This is the way Gdk does it.
> > 
> > * Finally, exclude the destination rectangle from the total requested
> > area, and pass it to AddExpose method.
> > 
> > With this patch everyting is working as expected, but I have some
> > issues:
> > 
> > * Region needs a Graphics instance to return its Bounds, which *could*
> > be expensive.
> > * After taking a look at the way scrolling is done in Gdk, it *seems*
> > that the Region implementation lack some of the functionality we need
> > (like, returning in a simple operation the Rectangles describing the
> > region).
> > 
> > Comments?
> > 
> > Carlos.
> > 
> > 
> > 
> > 
> > ___
> > Mono-winforms-list maillist  -  Mono-winforms-list@lists.ximian.com
> > http://lists.ximian.com/mailman/listinfo/mono-winforms-list
> 

___
Mono-winforms-list maillist  -  Mono-winforms-list@lists.ximian.com
http://lists.ximian.com/mailman/listinfo/mono-winforms-list


Re: [Mono-winforms-list] [Patch] Invalidate non visible areas in scrolling

2008-01-21 Thread Jonathan Pobst
I just added a public property called Hwnd.GraphicsContext that is a 
cached Graphics we keep around for measuring and such.  If you don't 
need a specific Graphics, you can just use this one.

Jon


Carlos Alberto Cortez wrote:
> Hey Chris,
> 
> Attached is an updated patch that basically incorporates all the things
> you mentioned in your last mail:
> 
> * Determines the visible rectangle, and intersects it with the required
> area (this is, we copy only the visible area).
>   - First by determining the visible area based on its size and its
> parents.
>   - Second, by looking for toplevel windows that intersect the window,
> and excluding that area.
> 
> * Then compute the destination rectangle, by applying the
> XAmount/YAmount values and intersecting it with the area passed to
> ScrollWindow (thus we clip it as needed). This is the way Gdk does it.
> 
> * Finally, exclude the destination rectangle from the total requested
> area, and pass it to AddExpose method.
> 
> With this patch everyting is working as expected, but I have some
> issues:
> 
> * Region needs a Graphics instance to return its Bounds, which *could*
> be expensive.
> * After taking a look at the way scrolling is done in Gdk, it *seems*
> that the Region implementation lack some of the functionality we need
> (like, returning in a simple operation the Rectangles describing the
> region).
> 
> Comments?
> 
> Carlos.
> 
> 
> 
> 
> ___
> Mono-winforms-list maillist  -  Mono-winforms-list@lists.ximian.com
> http://lists.ximian.com/mailman/listinfo/mono-winforms-list

___
Mono-winforms-list maillist  -  Mono-winforms-list@lists.ximian.com
http://lists.ximian.com/mailman/listinfo/mono-winforms-list


[Mono-winforms-list] [Patch] Invalidate non visible areas in scrolling

2008-01-21 Thread Carlos Alberto Cortez
Hey Chris,

Attached is an updated patch that basically incorporates all the things
you mentioned in your last mail:

* Determines the visible rectangle, and intersects it with the required
area (this is, we copy only the visible area).
- First by determining the visible area based on its size and its
parents.
- Second, by looking for toplevel windows that intersect the window,
and excluding that area.

* Then compute the destination rectangle, by applying the
XAmount/YAmount values and intersecting it with the area passed to
ScrollWindow (thus we clip it as needed). This is the way Gdk does it.

* Finally, exclude the destination rectangle from the total requested
area, and pass it to AddExpose method.

With this patch everyting is working as expected, but I have some
issues:

* Region needs a Graphics instance to return its Bounds, which *could*
be expensive.
* After taking a look at the way scrolling is done in Gdk, it *seems*
that the Region implementation lack some of the functionality we need
(like, returning in a simple operation the Rectangles describing the
region).

Comments?

Carlos.
Index: XplatUIX11.cs
===
--- XplatUIX11.cs	(revisión: 93328)
+++ XplatUIX11.cs	(copia de trabajo)
@@ -4791,48 +4791,21 @@
 
 			gc = XCreateGC(DisplayHandle, hwnd.client_window, IntPtr.Zero, ref gc_values);
 
-			int src_x, src_y;
-			int dest_x, dest_y;
-			int width, height;
+			Rectangle visible_rect = GetTotalVisibleArea (hwnd.client_window);
+			visible_rect.Intersect (area);
 
-			if (YAmount > 0) {
-src_y = area.Y;
-height = area.Height - YAmount;
-dest_y = area.Y + YAmount;
-			}
-			else {
-src_y = area.Y - YAmount;
-height = area.Height + YAmount;
-dest_y = area.Y;
-			}
+			Rectangle dest_rect = visible_rect;
+			dest_rect.Y += YAmount;
+			dest_rect.X += XAmount;
+			dest_rect.Intersect (area);
 
-			if (XAmount > 0) {
-src_x = area.X;
-width = area.Width - XAmount;
-dest_x = area.X + XAmount;
-			}
-			else {
-src_x = area.X - XAmount;
-width = area.Width + XAmount;
-dest_x = area.X;
-			}
+			Point src = new Point (dest_rect.X - XAmount, dest_rect.Y - YAmount);
+			XCopyArea (DisplayHandle, hwnd.client_window, hwnd.client_window, gc, src.X, src.Y, 
+	dest_rect.Width, dest_rect.Height, dest_rect.X, dest_rect.Y);
 
-			XCopyArea(DisplayHandle, hwnd.client_window, hwnd.client_window, gc, src_x, src_y, width, height, dest_x, dest_y);
+			Rectangle dirty_area = GetDirtyArea (area, dest_rect, XAmount, YAmount);
+			AddExpose (hwnd, true, dirty_area.X, dirty_area.Y, dirty_area.Width, dirty_area.Height);
 
-			// Generate an expose for the area exposed by the horizontal scroll
-			// We don't use AddExpose since we're 
-			if (XAmount > 0) {
-AddExpose(hwnd, true, area.X, area.Y, XAmount, area.Height);
-			} else if (XAmount < 0) {
-AddExpose(hwnd, true, XAmount + area.X + area.Width, area.Y, -XAmount, area.Height);
-			}
-
-			// Generate an expose for the area exposed by the vertical scroll
-			if (YAmount > 0) {
-AddExpose(hwnd, true, area.X, area.Y, area.Width, YAmount);
-			} else if (YAmount < 0) {
-AddExpose(hwnd, true, area.X, YAmount + area.Y + area.Height, area.Width, -YAmount);
-			}
 			XFreeGC(DisplayHandle, gc);
 		}
 
@@ -4848,6 +4821,127 @@
 			ScrollWindow(handle, rect, XAmount, YAmount, with_children);
 		}
 
+		Rectangle GetDirtyArea (Rectangle total_area, Rectangle valid_area, int XAmount, int YAmount)
+		{
+			Rectangle dirty_area = total_area;
+
+			if (YAmount > 0)
+dirty_area.Height = total_area.Height - valid_area.Height;
+			else if (YAmount < 0) {
+dirty_area.Height = total_area.Height - valid_area.Height;
+dirty_area.Y = total_area.Y + valid_area.Height;
+			}
+
+			if (XAmount > 0)
+dirty_area.Width -= valid_area.Width;
+			else if (XAmount < 0) {
+dirty_area.Width -= valid_area.Width;
+dirty_area.X += valid_area.Width;
+			}
+
+			return dirty_area;
+		}
+
+		Rectangle GetTotalVisibleArea (IntPtr handle)
+		{
+			Control c = Control.FromHandle (handle);
+
+			Rectangle visible_area = c.ClientRectangle;
+			visible_area.Location = c.PointToScreen (Point.Empty);
+
+			for (Control parent = c.Parent; parent != null; parent = parent.Parent) {
+Rectangle r = parent.ClientRectangle;
+r.Location = parent.PointToScreen (Point.Empty);
+
+visible_area.Intersect (r);
+			}
+
+			// If region is null, the entire area is visible.
+			// Get the area not obscured otherwise.
+			Region visible_region = GetVisibleRegion (c, visible_area);
+			if (visible_region != null) {
+Graphics g = c.CreateGraphics ();
+RectangleF rectf = visible_region.GetBounds (g);
+visible_area = new Rectangle ((int) rectf.X, (int) rectf.Y,
+		(int) rectf.Width, (int) rectf.Height);
+
+visible_region.Dispose ();
+g.Dispose ();
+			}
+
+			visible_area.Location = c.PointToClient (visible_area.Location);
+			return vis