예제 #1
0
 // Convert an Xsharp.Region to System.Drawing.Region
 internal static System.Drawing.Region RegionToDrawingRegion
     (Xsharp.Region region)
 {
     Xsharp.Rectangle[]    rectangles = region.GetRectangles();
     System.Drawing.Region newRegion  = new System.Drawing.Region();
     newRegion.MakeEmpty();
     for (int i = 0; i < rectangles.Length; i++)
     {
         Xsharp.Rectangle rect = rectangles[i];
         newRegion.Union(new System.Drawing.Rectangle
                             (rect.x, rect.y, rect.width, rect.height));
     }
     return(newRegion);
 }
예제 #2
0
	/// <summary>
	/// <para>Construct a new <see cref="T:Xsharp.Region"/>
	/// instance that is initially set to the same area as
	/// a rectangle.</para>
	/// </summary>
	///
	/// <param name="rect">
	/// <para>The rectangle to set the region to initially.</para>
	/// </param>
	///
	/// <exception cref="T:Xsharp.XException">
	/// <para>Raised if the rectangle co-ordinates are out of range.</para>
	/// </exception>
	public Region(Rectangle rect)
			{
				lock(typeof(Region))
				{
					region = Xlib.XCreateRegion();
					if(region == IntPtr.Zero)
					{
						Display.OutOfMemory();
					}
					Union(rect.x, rect.y, rect.width, rect.height);
				}
			}
예제 #3
0
	/// <summary>
	/// <para>Xor a rectangle with this region.</para>
	/// </summary>
	///
	/// <param name="rect">
	/// <para>The rectangle to xor with this region.</para>
	/// </param>
	///
	/// <exception cref="T:Xsharp.XException">
	/// <para>Raised if the rectangle co-ordinates are out of range.</para>
	/// </exception>
	///
	/// <remarks>
	/// <para>If this region has been disposed, then it will be treated
	/// as empty prior to the xor operation.</para>
	/// </remarks>
	public void Xor(Rectangle rect)
			{
				lock(typeof(Region))
				{
					if(region == IntPtr.Zero)
					{
						region = Xlib.XCreateRegion();
						if(region == IntPtr.Zero)
						{
							Display.OutOfMemory();
						}
					}
					XRectangle xrect = new XRectangle
						(rect.x, rect.y, rect.width, rect.height);
					IntPtr reg = Xlib.XCreateRegion();
					if(reg == IntPtr.Zero)
					{
						Display.OutOfMemory();
					}
					Xlib.XUnionRectWithRegion(ref xrect, reg, reg);
					Xlib.XXorRegion(region, reg, region);
					Xlib.XDestroyRegion(reg);
				}
			}
예제 #4
0
	/// <summary>
	/// <para>Get the list of rectangles that defines this region.</para>
	/// </summary>
	///
	/// <returns>
	/// <para>An array of <see cref="T:Xsharp.Rectangle"/> instances
	/// corresponding to the rectangles that make up the region.
	/// Returns a zero-length array if the region is empty.</para>
	/// </returns>
	public Rectangle[] GetRectangles()
			{
				lock(typeof(Region))
				{
					if(region == IntPtr.Zero)
					{
						return new Rectangle [0];
					}
					else
					{
						Rectangle[] rects;
						XRectangle xrect;
						int size, index;
						size = Xlib.XSharpGetRegionSize(region);
						rects = new Rectangle [size];
						for(index = 0; index < size; ++index)
						{
							Xlib.XSharpGetRegionRect(region, index, out xrect);
							rects[index].x = xrect.x;
							rects[index].y = xrect.y;
							rects[index].width = xrect.width;
							rects[index].height = xrect.height;
						}
						return rects;
					}
				}
			}
예제 #5
0
	/// <summary>
	/// <para>Get the smallest rectangle that completely contains
	/// this region.</para>
	/// </summary>
	///
	/// <returns>
	/// <para>A <see cref="T:Xsharp.Rectangle"/> instance corresponding
	/// to the smallest rectangle that contains the region.</para>
	/// </returns>
	public Rectangle ClipBox()
			{
				lock(typeof(Region))
				{
					Rectangle rect;
					if(region == IntPtr.Zero)
					{
						rect = new Rectangle(0, 0, 0, 0);
					}
					else
					{
						XRectangle xrect;
						Xlib.XClipBox(region, out xrect);
						rect = new Rectangle(xrect.x, xrect.y,
											 xrect.width, xrect.height);
					}
					return rect;
				}
			}
예제 #6
0
	/// <summary>
	/// <para>Determine if a rectangle is overlaps with this region.</para>
	/// </summary>
	///
	/// <param name="rect">
	/// <para>The rectangle to test against this region.</para>
	/// </param>
	///
	/// <returns>
	/// <para>Returns <see langword="true"/> if the rectangle overlaps
	/// with this region; <see langword="false"/> otherwise.</para>
	/// </returns>
	public bool Overlaps(Rectangle rect)
			{
				lock(typeof(Region))
				{
					if(region == IntPtr.Zero)
					{
						return false;
					}
					else
					{
						return (Xlib.XRectInRegion(region, rect.x, rect.y,
												   (uint)(rect.width),
												   (uint)(rect.height))
										!= 0);	// RectangleOut
					}
				}
			}
예제 #7
0
	/// <summary>
	/// <para>Determine if a rectangle is completely contained
	/// in this region.</para>
	/// </summary>
	///
	/// <param name="rect">
	/// <para>The rectangle to test against this region.</para>
	/// </param>
	///
	/// <returns>
	/// <para>Returns <see langword="true"/> if the rectangle is completely
	/// contained within this region; <see langword="false"/> otherwise.</para>
	/// </returns>
	public bool Contains(Rectangle rect)
			{
				lock(typeof(Region))
				{
					if(region == IntPtr.Zero)
					{
						return false;
					}
					else
					{
						return (Xlib.XRectInRegion(region, rect.x, rect.y,
												   (uint)(rect.width),
												   (uint)(rect.height))
										== 1);	// RectangleIn
					}
				}
			}
예제 #8
0
	/// <summary>
	/// <para>Draw a rectangle.</para>
	/// </summary>
	///
	/// <param name="rect">
	/// <para>The position and size of the rectangle.</para>
	/// </param>
	///
	/// <exception cref="T:Xsharp.XException">
	/// <para>One of the co-ordinate or size values is out of range.</para>
	/// </exception>
	public void DrawRectangle(Rectangle rect)
			{
				DrawRectangle(rect.x, rect.y, rect.width, rect.height);
			}
	// 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);
				}
			}
예제 #10
0
	// Draw the caption buttons in their current state.  Returns the
	// number of pixels on the right of the caption that are occupied
	// by the buttons.
	private static int DrawCaptionButtons
				(Graphics graphics, Rectangle rect,
				 CaptionFlags flags, CaptionFlags buttonsToDraw)
			{
				int subtract = 2;
				if((flags & CaptionFlags.HasClose) != 0)
				{
					subtract += DrawCaptionButton
						(graphics, rect, subtract,
						 ((flags & CaptionFlags.ClosePressed) != 0),
						 ((buttonsToDraw & CaptionFlags.HasClose) != 0),
						 graphics.dpy.bitmaps.Close);
					if((flags & (CaptionFlags.HasMaximize |
								 CaptionFlags.HasRestore |
								 CaptionFlags.HasMinimize)) != 0)
					{
						// Leave a gap between the close button and the others.
						subtract += 2;
					}
				}
				if((flags & CaptionFlags.HasMaximize) != 0)
				{
					subtract += DrawCaptionButton
						(graphics, rect, subtract,
						 ((flags & CaptionFlags.MaximizePressed) != 0),
						 ((buttonsToDraw & CaptionFlags.HasMaximize) != 0),
						 graphics.dpy.bitmaps.Maximize);
				}
				if((flags & CaptionFlags.HasRestore) != 0)
				{
					subtract += DrawCaptionButton
						(graphics, rect, subtract,
						 ((flags & CaptionFlags.RestorePressed) != 0),
						 ((buttonsToDraw & CaptionFlags.HasRestore) != 0),
						 graphics.dpy.bitmaps.Restore);
				}
				if((flags & CaptionFlags.HasMinimize) != 0)
				{
					subtract += DrawCaptionButton
						(graphics, rect, subtract,
						 ((flags & CaptionFlags.MinimizePressed) != 0),
						 ((buttonsToDraw & CaptionFlags.HasMinimize) != 0),
						 graphics.dpy.bitmaps.Minimize);
				}
				if((flags & CaptionFlags.HasHelp) != 0)
				{
					// Leave a gap between the help button and the others.
					subtract += 2;
					subtract += DrawCaptionButton
						(graphics, rect, subtract,
						 ((flags & CaptionFlags.HelpPressed) != 0),
						 ((buttonsToDraw & CaptionFlags.HasHelp) != 0),
						 graphics.dpy.bitmaps.Help);
				}
				if(subtract > 2)
				{
					// Leave a gap between the buttons and the text.
					return subtract + 2;
				}
				else
				{
					// There are no buttons, so no need for an extra gap.
					return 2;
				}
			}
예제 #11
0
	// Draw a caption button.  Returns the width of the button.
	private static int DrawCaptionButton
					(Graphics graphics, Rectangle rect,
					 int subtract, bool pressed, bool draw,
					 XPixmap buttonPixmap)
			{
				int buttonSize = rect.height - 4;
				int x = rect.x + rect.width - subtract - buttonSize;
				int y = rect.y + 2;
				if(draw)
				{
					if(pressed)
					{
						graphics.DrawEffect(x, y, buttonSize, buttonSize,
											Effect.CaptionButtonIndented);
						++x;
						++y;
					}
					else
					{
						graphics.DrawEffect(x, y, buttonSize, buttonSize,
											Effect.CaptionButtonRaised);
					}
					x += (buttonSize - 9) / 2;
					y += (buttonSize - 9) / 2;
					graphics.DrawBitmap(x, y, 9, 9, buttonPixmap);
				}
				return buttonSize;
			}
예제 #12
0
	// Process a minimize event on the child.
	private void MinimizeChild()
			{
				// Bail out if the child is already iconic.
				if(child.iconic)
				{
					return;
				}

				// Mark the child as iconic.
				child.iconic = true;

				// Save the restore position if we aren't maximized.
				if(!(child.maximized))
				{
					restoreX = x;
					restoreY = y;
					restoreWidth = width;
					restoreHeight = height;
				}

				// Resize the caption widget to the minimized size.
				Rectangle rect = new Rectangle
					(0, 0, MinimizedWidth, captionHeight + FrameBorderSize);
				((MdiClientWidget)Parent).PlaceMinimizedRectangle
					(ref rect, this);
				MoveResize(rect.x, rect.y, rect.width, rect.height);

				// Unmap the child window.
				try
				{
					IntPtr display = dpy.Lock();
					Xlib.XUnmapWindow(display, child.GetWidgetHandle());
				}
				finally
				{
					dpy.Unlock();
				}

				// Lower this window and select a new active window.
				Lower();

				// Update the decorations to match the new flags.
				UpdateDecorations();
			}
예제 #13
0
	/// <summary>
	/// <para>Fill a list of rectangles.</para>
	/// </summary>
	///
	/// <param name="rects">
	/// <para>The list of rectangles to be drawn.</para>
	/// </param>
	///
	/// <exception cref="T:System.ArgumentNullException">
	/// <para>Raised if <paramref name="rects"/> is <see langword="null"/>.
	/// </para>
	/// </exception>
	///
	/// <exception cref="T:Xsharp.XException">
	/// <para>One of the co-ordinate or size values is out of range, or
	/// <paramref name="rects"/> has less than 1 element.</para>
	/// </exception>
	public void FillRectangles(Rectangle[] rects)
			{
				int len;

				// Validate the parameter.
				if(rects == null)
				{
					throw new ArgumentNullException("rects");
				}
				len = rects.Length;
				if(len < 1)
				{
					throw new XException(S._("X_Need1Rect"));
				}
				else if(len > ((dpy.MaxRequestSize() - 3) / 2))
				{
					throw new XException(S._("X_MaxReqSizeExceeded"));
				}

				// Convert the "Rectangle" array into an "XRectangle" array.
				XRectangle[] xrects = new XRectangle [len];
				int r;
				for(r = 0; r < len; ++r)
				{
					xrects[r] = new XRectangle(rects[r].x, rects[r].y,
											   rects[r].width,
											   rects[r].height);
				}

				// Draw the rectangles.
				try
				{
					IntPtr display = Lock();
					Xlib.XFillRectangles(display, drawableHandle, gc,
										 xrects, len);
				}
				finally
				{
					dpy.Unlock();
				}
			}
예제 #14
0
	/// <summary>
	/// <para>Fill a rectangle.</para>
	/// </summary>
	///
	/// <param name="rect">
	/// <para>The position and size of the rectangle.</para>
	/// </param>
	///
	/// <exception cref="T:Xsharp.XException">
	/// <para>One of the co-ordinate or size values is out of range.</para>
	/// </exception>
	public void FillRectangle(Rectangle rect)
			{
				FillRectangle(rect.x, rect.y, rect.width, rect.height);
			}
예제 #15
0
	// Change the state of a caption button.  Returns true if the
	// button was pressed before we changed its state.
	private bool ChangeButtonState(HitTest hitTest, bool pressed)
			{
				// Determine what change we need to apply.
				CaptionFlags buttonsToDraw = (CaptionFlags)0;
				CaptionFlags pressedState = (CaptionFlags)0;
				CaptionFlags origFlags = flags;
				switch(hitTest)
				{
					case HitTest.Close:
					{
						buttonsToDraw = CaptionFlags.HasClose;
						pressedState = CaptionFlags.ClosePressed;
					}
					break;

					case HitTest.Maximize:
					{
						buttonsToDraw = CaptionFlags.HasMaximize;
						pressedState = CaptionFlags.MaximizePressed;
					}
					break;

					case HitTest.Minimize:
					{
						buttonsToDraw = CaptionFlags.HasMinimize;
						pressedState = CaptionFlags.MinimizePressed;
					}
					break;

					case HitTest.Restore:
					{
						buttonsToDraw = CaptionFlags.HasRestore;
						pressedState = CaptionFlags.RestorePressed;
					}
					break;

					case HitTest.Help:
					{
						buttonsToDraw = CaptionFlags.HasHelp;
						pressedState = CaptionFlags.HelpPressed;
					}
					break;
				}
				if(pressed)
				{
					flags |= pressedState;
				}
				else
				{
					flags &= ~pressedState;
				}

				// Redraw the caption buttons to match the state change.
				if(flags != origFlags)
				{
					Rectangle rect = new Rectangle
						(FrameBorderSize, FrameBorderSize,
						 width - FrameBorderSize * 2,
						 captionHeight - FrameBorderSize);
					using(Graphics graphics = new Graphics(this))
					{
						DrawCaptionButtons
							(graphics, rect, flags, buttonsToDraw);
					}
				}
				return ((origFlags & pressedState) != 0);
			}
	// Place a minimized window rectangle.
	internal void PlaceMinimizedRectangle(ref Rectangle rect, Widget placed)
			{
				// Create a region that consists of all minimized areas.
				Region region = new Region();
				Widget current = TopChild;
				while(current != null)
				{
					if(current is CaptionWidget && current.IsMapped &&
					   ((CaptionWidget)current).Child.IsIconic)
					{
						if(current != placed)
						{
							region.Union
								(current.x, current.y,
								 current.width, current.height);
						}
					}
					current = current.NextBelow;
				}

				// Place the minimized rectangle.
				int yplace = height - rect.height;
				int xplace = 0;
				for(;;)
				{
					// Move up to the next line if we've overflowed this one.
					if((xplace + rect.width) > width && width >= rect.width)
					{
						yplace -= rect.height;
						xplace = 0;
					}

					// Determine if the rectangle overlaps the region.
					// If it doesn't, then we have found the best location.
					rect.x = xplace;
					rect.y = yplace;
					if(!region.Overlaps(rect))
					{
						region.Dispose();
						return;
					}

					// Move on to the next candidate.
					xplace += rect.width;
				}
			}
예제 #17
0
	/// <summary>
	/// <para>Clear a rectangular area within the drawable to
	/// its background color.</para>
	/// </summary>
	///
	/// <param name="rect">
	/// <para>The rectangle to be cleared.</para>
	/// </param>
	///
	/// <remarks>
	/// <para>If the drawable is an input-output widget, it uses the
	/// background color (or pixmap) of the widget, not the background
	/// color of the graphics object.</para>
	///
	/// <para>If the graphics object has an active clipping region, then the
	/// cleared area will be clipped to the region.</para>
	/// </remarks>
	///
	/// <exception cref="T:Xsharp.XException">
	/// <para>One of the co-ordinate or size values is out of range.</para>
	/// </exception>
	public void Clear(Rectangle rect)
			{
				Clear(rect.x, rect.y, rect.width, rect.height);
			}