Re: [Mono-winforms-list] [Patch] Invalidate non visible areas in scrolling
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
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
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
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
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