// Clear a region to the background and optionally queue expose events. private bool ClearRegion(Region region, XBool exposures) { // Intersect the region with the widget boundaries. region.Intersect(0, 0, width, height); // Remove areas that are occupied by mapped child widgets. Widget child = TopChild; while(child != null) { if(child.mapped) { region.Subtract(child.x, child.y, child.width, child.height); } child = child.NextBelow; } // Bail out if the region is now empty. if(region.IsEmpty()) { return false; } // Lock down the display and send the "XClearArea" requests. try { IntPtr display = dpy.Lock(); XWindow handle = GetWidgetHandle(); IntPtr xregion = region.GetRegion(); XRectangle xrect; int size, index; size = Xlib.XSharpGetRegionSize(xregion); for(index = 0; index < size; ++index) { Xlib.XSharpGetRegionRect(xregion, index, out xrect); Xlib.XClearArea(display, handle, xrect.x, xrect.y, xrect.width, xrect.height, exposures); } } finally { dpy.Unlock(); } return true; }
/* * <summary><p>Invalidate the given region and flush the request</p></summary> */ private void Invalidate(Region region) { if (drawBackground) { ClearRegion(region, XBool.True); } else { /* Don't flush to the X server cause we don't want it to draw the background */ region.Intersect(0, 0, width, height); if (exposeRegion == null) { exposeRegion = region; dpy.AddPendingExpose(this); } else { exposeRegion.Union(region); region.Dispose(); } } }
// Paint this widget in response to an "Expose" event. protected override void OnPaint(Graphics graphics) { // Draw the thick 3D border around the outside first. graphics.DrawEffect(0, 0, width, height, Effect.Raised); // Get the rectangle containing the caption area. Rectangle rect = new Rectangle (FrameBorderSize, FrameBorderSize, width - FrameBorderSize * 2, captionHeight - FrameBorderSize); // If the rectangle does not overlap the expose region, // then there is no point drawing the main caption area. if(!graphics.ExposeRegion.Overlaps(rect)) { return; } // Get the colors to use for the foreground and background. Color foreground, background, endBackground; if((flags & CaptionFlags.Active) != 0) { foreground = new Color(StandardColor.HighlightForeground); background = new Color(StandardColor.HighlightBackground); endBackground = new Color(StandardColor.HighlightEndBackground); } else { foreground = new Color(StandardColor.Background); background = new Color(StandardColor.BottomShadow); endBackground = new Color(StandardColor.EndBackground); } // Create a gradient for the title bar, if necessary. if(gradient != null && (gradient.Width != rect.width || gradient.Height != rect.height)) { // The size has changed and we need a new gradient. gradient.Dispose(); gradient = null; } if(gradient == null && screen.DefaultDepth >= 15) { DotGNU.Images.Image image = CreateGradient (rect.width, rect.height, background, endBackground); gradient = new Xsharp.Image(screen, image.GetFrame(0)); image.Dispose(); } // Clear the caption background. if(gradient == null) { graphics.Foreground = background; graphics.SetFillSolid(); graphics.FillRectangle(rect); } else { graphics.SetFillTiled(gradient.Pixmap, rect.x, rect.y); graphics.FillRectangle(rect); graphics.SetFillSolid(); } // Draw the caption buttons and then subtract that // region off the caption rectangle so we don't get // bleed through when we draw the caption text. rect.width -= DrawCaptionButtons (graphics, rect, flags, (CaptionFlags)(~0)); // Bail out if the rectangle is too small for the text. if(rect.width <= 2) { return; } // Position the caption text. Font font = GetCaptionFont(); FontExtents extents = font.GetFontExtents(graphics); int textY = (rect.height - extents.Ascent) / 2; textY += rect.y + extents.Ascent; // Draw the caption text, clipped to the caption area // so that it won't overwrite the buttons on the right. using(Region region = new Region(graphics.ExposeRegion)) { region.Intersect(rect); graphics.SetClipRegion(region); graphics.Foreground = foreground; graphics.DrawString(rect.x + 2, textY, child.Name, font); } }