public Box(GroupSelector selector, int item) { bounds.Height = selector.background.Height; bounds.Y = selector.background.Y; bounds.X = selector.BoxX (item); bounds.Width = Math.Max (selector.BoxX (item + 1) - bounds.X, 1); if (item < 0 || item > selector.box_counts.Length - 1) return; double percent = selector.box_counts [item] / (double) Math.Max (selector.box_count_max, 1); bar = bounds; bar.Height = (int) Math.Ceiling ((bounds.Height - selector.box_top_padding) * percent); bar.Y += bounds.Height - bar.Height - 1; bar.Inflate (- selector.box_spacing, 0); }
private void InflateAndInvalidate(Rectangle passedRectangle) { //Create a new instance to preserve the passed Rectangle. Rectangle r = new Rectangle(passedRectangle.Location, passedRectangle.Size); r.Inflate(1, 1); PintaCore.Workspace.Invalidate(r); }
/// <summary> /// Create a cursor icon with a shape that visually represents the tool's thickness. /// </summary> /// <param name="imgName">A string containing the name of the tool's icon image to use.</param> /// <param name="shape">The shape to draw.</param> /// <param name="shapeWidth">The width of the shape.</param> /// <param name="imgToShapeX">The horizontal distance between the image's top-left corner and the shape center.</param> /// <param name="imgToShapeX">The verical distance between the image's top-left corner and the shape center.</param> /// <param name="shapeX">The X position in the returned Pixbuf that will be the center of the shape.</param> /// <param name="shapeY">The Y position in the returned Pixbuf that will be the center of the shape.</param> /// <returns>The new cursor icon with an shape that represents the tool's thickness.</returns> protected Gdk.Pixbuf CreateIconWithShape(string imgName, CursorShape shape, int shapeWidth, int imgToShapeX, int imgToShapeY, out int shapeX, out int shapeY) { Gdk.Pixbuf img = PintaCore.Resources.GetIcon(imgName); double zoom = 1d; if (PintaCore.Workspace.HasOpenDocuments) { zoom = Math.Min(30d, PintaCore.Workspace.ActiveDocument.Workspace.Scale); } shapeWidth = (int)Math.Min(800d, ((double)shapeWidth) * zoom); int halfOfShapeWidth = shapeWidth / 2; // Calculate bounding boxes around the both image and shape // relative to the image top-left corner. Gdk.Rectangle imgBBox = new Gdk.Rectangle(0, 0, img.Width, img.Height); Gdk.Rectangle shapeBBox = new Gdk.Rectangle( imgToShapeX - halfOfShapeWidth, imgToShapeY - halfOfShapeWidth, shapeWidth, shapeWidth); // Inflate shape bounding box to allow for anti-aliasing shapeBBox.Inflate(2, 2); // To determine required size of icon, // find union of the image and shape bounding boxes // (still relative to image top-left corner) Gdk.Rectangle iconBBox = imgBBox.Union (shapeBBox); // Image top-left corner in icon co-ordinates int imgX = imgBBox.Left - iconBBox.Left; int imgY = imgBBox.Top - iconBBox.Top; // Shape center point in icon co-ordinates shapeX = imgToShapeX - iconBBox.Left; shapeY = imgToShapeY - iconBBox.Top; ImageSurface i = new ImageSurface(Format.ARGB32, iconBBox.Width, iconBBox.Height); using (Context g = new Context(i)) { // Don't show shape if shapeWidth less than 3, if (shapeWidth > 3) { int diam = Math.Max (1, shapeWidth - 2); Cairo.Rectangle shapeRect = new Cairo.Rectangle(shapeX - halfOfShapeWidth, shapeY - halfOfShapeWidth, diam, diam); Cairo.Color outerColor = new Cairo.Color (255, 255, 255, 0.5); Cairo.Color innerColor = new Cairo.Color (0, 0, 0); switch (shape) { case CursorShape.Ellipse: g.DrawEllipse(shapeRect, outerColor, 1); shapeRect = shapeRect.Inflate (-1, -1); g.DrawEllipse(shapeRect, innerColor, 1); break; case CursorShape.Rectangle: g.DrawRectangle(shapeRect, outerColor, 1); shapeRect = shapeRect.Inflate (-1, -1); g.DrawRectangle(shapeRect, innerColor, 1); break; } } // Draw the image g.DrawPixbuf(img, new Cairo.Point(imgX, imgY)); } return CairoExtensions.ToPixbuf(i); }
/// <summary> /// Create a cursor icon with a shape that visually represents the tool's thickness. /// </summary> /// <param name="imgName">A string containing the name of the tool's icon image to use.</param> /// <param name="shape">The shape to draw.</param> /// <param name="shapeWidth">The width of the shape.</param> /// <param name="imgToShapeX">The horizontal distance between the image's top-left corner and the shape center.</param> /// <param name="imgToShapeY">The verical distance between the image's top-left corner and the shape center.</param> /// <param name="shapeX">The X position in the returned Pixbuf that will be the center of the shape.</param> /// <param name="shapeY">The Y position in the returned Pixbuf that will be the center of the shape.</param> /// <returns>The new cursor icon with an shape that represents the tool's thickness.</returns> protected Gdk.Pixbuf CreateIconWithShape(string imgName, CursorShape shape, int shapeWidth, int imgToShapeX, int imgToShapeY, out int shapeX, out int shapeY) { Gdk.Pixbuf img = PintaCore.Resources.GetIcon(imgName); double zoom = 1d; if (PintaCore.Workspace.HasOpenDocuments) { zoom = Math.Min(30d, PintaCore.Workspace.ActiveDocument.Workspace.Scale); } shapeWidth = (int)Math.Min(800d, ((double)shapeWidth) * zoom); int halfOfShapeWidth = shapeWidth / 2; // Calculate bounding boxes around the both image and shape // relative to the image top-left corner. Gdk.Rectangle imgBBox = new Gdk.Rectangle(0, 0, img.Width, img.Height); Gdk.Rectangle shapeBBox = new Gdk.Rectangle( imgToShapeX - halfOfShapeWidth, imgToShapeY - halfOfShapeWidth, shapeWidth, shapeWidth); // Inflate shape bounding box to allow for anti-aliasing shapeBBox.Inflate(2, 2); // To determine required size of icon, // find union of the image and shape bounding boxes // (still relative to image top-left corner) Gdk.Rectangle iconBBox = imgBBox.Union(shapeBBox); // Image top-left corner in icon co-ordinates int imgX = imgBBox.Left - iconBBox.Left; int imgY = imgBBox.Top - iconBBox.Top; // Shape center point in icon co-ordinates shapeX = imgToShapeX - iconBBox.Left; shapeY = imgToShapeY - iconBBox.Top; using (ImageSurface i = new ImageSurface(Format.ARGB32, iconBBox.Width, iconBBox.Height)) { using (Context g = new Context(i)) { // Don't show shape if shapeWidth less than 3, if (shapeWidth > 3) { int diam = Math.Max(1, shapeWidth - 2); Cairo.Rectangle shapeRect = new Cairo.Rectangle(shapeX - halfOfShapeWidth, shapeY - halfOfShapeWidth, diam, diam); Cairo.Color outerColor = new Cairo.Color(255, 255, 255, 0.75); Cairo.Color innerColor = new Cairo.Color(0, 0, 0); switch (shape) { case CursorShape.Ellipse: g.DrawEllipse(shapeRect, outerColor, 2); shapeRect = shapeRect.Inflate(-1, -1); g.DrawEllipse(shapeRect, innerColor, 1); break; case CursorShape.Rectangle: g.DrawRectangle(shapeRect, outerColor, 1); shapeRect = shapeRect.Inflate(-1, -1); g.DrawRectangle(shapeRect, innerColor, 1); break; } } // Draw the image g.DrawPixbuf(img, new Cairo.Point(imgX, imgY)); } return(CairoExtensions.ToPixbuf(i)); } }
public void RepositionWindow(Gdk.Rectangle?newCaret = null) { if (parent == null) { return; } int x, y; if (newCaret.HasValue) //Update caret if parameter is given { currentCaret = newCaret.Value; } Gdk.Rectangle caret = currentCaret; Gdk.Window window = targetWindow; if (targetWindow == null) { return; } PopupPosition position = Theme.TargetPosition; this.position = Theme.TargetPosition; UpdatePadding(); window.GetOrigin(out x, out y); var alloc = parent.Allocation; if (eventProvided) { caret.X = x; caret.Y = y; caret.Width = caret.Height = 1; } else { if (caret.Equals(Gdk.Rectangle.Zero)) { caret = new Gdk.Rectangle(0, 0, alloc.Width, alloc.Height); } caret = GtkUtil.ToScreenCoordinates(parent, parent.GdkWindow, caret); } Gtk.Requisition request = SizeRequest(); var screen = parent.Screen; Gdk.Rectangle geometry = GtkWorkarounds.GetUsableMonitorGeometry(screen, screen.GetMonitorAtPoint(x, y)); // Add some spacing between the screen border and the popover window geometry.Inflate(-5, -5); // Flip the orientation if the window doesn't fit the screen. int intPos = (int)position; switch ((PopupPosition)(intPos & 0x0f)) { case PopupPosition.Top: if (caret.Bottom + request.Height > geometry.Bottom) { intPos = (intPos & 0xf0) | (int)PopupPosition.Bottom; } break; case PopupPosition.Bottom: if (caret.Top - request.Height < geometry.X) { intPos = (intPos & 0xf0) | (int)PopupPosition.Top; } break; case PopupPosition.Right: if (caret.X - request.Width < geometry.X) { intPos = (intPos & 0xf0) | (int)PopupPosition.Left; } break; case PopupPosition.Left: if (caret.Right + request.Width > geometry.Right) { intPos = (intPos & 0xf0) | (int)PopupPosition.Right; } break; } position = (PopupPosition)intPos; UpdatePadding(); // Calculate base coordinate switch ((PopupPosition)((int)position & 0x0f)) { case PopupPosition.Top: y = caret.Bottom; break; case PopupPosition.Bottom: y = caret.Y - request.Height; break; case PopupPosition.Right: x = caret.X - request.Width; break; case PopupPosition.Left: x = caret.Right; break; } int offset; if ((position & PopupPosition.Top) != 0 || (position & PopupPosition.Bottom) != 0) { if (((int)position & 0x10) != 0) { x = caret.X - MinArrowSpacing - Theme.ArrowWidth / 2; } else if (((int)position & 0x20) != 0) { x = caret.Right - request.Width + MinArrowSpacing + Theme.ArrowWidth / 2; } else { x = caret.X + (caret.Width - request.Width) / 2; } if (x < geometry.Left) { x = geometry.Left; } else if (x + request.Width > geometry.Right) { x = geometry.Right - request.Width; } offset = caret.X + caret.Width / 2 - x; if (offset - Theme.ArrowWidth / 2 < MinArrowSpacing) { offset = MinArrowSpacing + Theme.ArrowWidth / 2; } if (offset > request.Width - MinArrowSpacing - Theme.ArrowWidth / 2) { offset = request.Width - MinArrowSpacing - Theme.ArrowWidth / 2; } } else { if (((int)position & 0x10) != 0) { y = caret.Y - MinArrowSpacing - Theme.ArrowWidth / 2; } else if (((int)position & 0x20) != 0) { y = caret.Bottom - request.Height + MinArrowSpacing + Theme.ArrowWidth / 2; } else { y = caret.Y + (caret.Height - request.Height) / 2; } if (y < geometry.Top) { y = geometry.Top; } else if (y + request.Height > geometry.Bottom) { y = geometry.Bottom - request.Height; } if (MaximumYTopBound > 0) { y = Math.Max(MaximumYTopBound, y); } offset = caret.Y + caret.Height / 2 - y; if (offset - Theme.ArrowWidth / 2 < MinArrowSpacing) { offset = MinArrowSpacing + Theme.ArrowWidth / 2; } if (offset > request.Height - MinArrowSpacing - Theme.ArrowWidth / 2) { offset = request.Height - MinArrowSpacing - Theme.ArrowWidth / 2; } } Theme.ArrowOffset = offset; this.position = position; UpdatePadding(); Move(x, y); Show(); if (!ShowWindowShadow) { DesktopService.RemoveWindowShadow(this); } }
// VERY SLOW, only use on cached renders public static void RenderOuterShadow(this Cairo.Context self, Gdk.Rectangle area, int size, int rounding, double strength) { area.Inflate(-1, -1); size++; int doubleRounding = rounding * 2; // left side self.Rectangle(area.X - size, area.Y + rounding, size, area.Height - doubleRounding - 1); using (var lg = new LinearGradient(area.X, 0, area.X - size, 0)) { ShadowGradient(lg, strength); self.SetSource(lg); self.Fill(); } // right side self.Rectangle(area.Right, area.Y + rounding, size, area.Height - doubleRounding - 1); using (var lg = new LinearGradient(area.Right, 0, area.Right + size, 0)) { ShadowGradient(lg, strength); self.SetSource(lg); self.Fill(); } // top side self.Rectangle(area.X + rounding, area.Y - size, area.Width - doubleRounding - 1, size); using (var lg = new LinearGradient(0, area.Y, 0, area.Y - size)) { ShadowGradient(lg, strength); self.SetSource(lg); self.Fill(); } // bottom side self.Rectangle(area.X + rounding, area.Bottom, area.Width - doubleRounding - 1, size); using (var lg = new LinearGradient(0, area.Bottom, 0, area.Bottom + size)) { ShadowGradient(lg, strength); self.SetSource(lg); self.Fill(); } // top left corner self.Rectangle(area.X - size, area.Y - size, size + rounding, size + rounding); using (var rg = new RadialGradient(area.X + rounding, area.Y + rounding, rounding, area.X + rounding, area.Y + rounding, size + rounding)) { ShadowGradient(rg, strength); self.SetSource(rg); self.Fill(); } // top right corner self.Rectangle(area.Right - rounding, area.Y - size, size + rounding, size + rounding); using (var rg = new RadialGradient(area.Right - rounding, area.Y + rounding, rounding, area.Right - rounding, area.Y + rounding, size + rounding)) { ShadowGradient(rg, strength); self.SetSource(rg); self.Fill(); } // bottom left corner self.Rectangle(area.X - size, area.Bottom - rounding, size + rounding, size + rounding); using (var rg = new RadialGradient(area.X + rounding, area.Bottom - rounding, rounding, area.X + rounding, area.Bottom - rounding, size + rounding)) { ShadowGradient(rg, strength); self.SetSource(rg); self.Fill(); } // bottom right corner self.Rectangle(area.Right - rounding, area.Bottom - rounding, size + rounding, size + rounding); using (var rg = new RadialGradient(area.Right - rounding, area.Bottom - rounding, rounding, area.Right - rounding, area.Bottom - rounding, size + rounding)) { ShadowGradient(rg, strength); self.SetSource(rg); self.Fill(); } }
public virtual void RepositionWindow(Gdk.Rectangle?newCaret = null) { if (!HasParent || IsDestroyed) { return; } if (newCaret.HasValue) //Update caret if parameter is given { currentCaret = newCaret.Value; } Gdk.Rectangle caret = currentCaret; if (targetWindowOrigin.X < 0) { return; } int x = targetWindowOrigin.X; int y = targetWindowOrigin.Y; PopupPosition position = Theme.TargetPosition; this.position = Theme.TargetPosition; UpdatePadding(); var psize = GetParentSize(); if (eventProvided) { caret.X = x; caret.Y = y; caret.Width = caret.Height = 1; } else { if (caret.Equals(Gdk.Rectangle.Zero)) { caret = new Gdk.Rectangle(0, 0, psize.Width, psize.Height); } caret = GetScreenCoordinates(caret); } caret.Inflate(CaretSpacing, CaretSpacing); if (!Core.Platform.IsWindows) { caret.Inflate(-1, -1); } Gtk.Requisition request = SizeRequest(); Gdk.Rectangle geometry = GetUsableMonitorGeometry(caret); // Add some spacing between the screen border and the popover window geometry.Inflate(-5, -5); // Flip the orientation if the window doesn't fit the screen. int intPos = (int)position; switch ((PopupPosition)(intPos & 0x0f)) { case PopupPosition.Top: if (caret.Bottom + request.Height > geometry.Bottom) { intPos = (intPos & 0xf0) | (int)PopupPosition.Bottom; } break; case PopupPosition.Bottom: if (caret.Top - request.Height < geometry.X) { intPos = (intPos & 0xf0) | (int)PopupPosition.Top; } break; case PopupPosition.Right: if (caret.X - request.Width < geometry.X) { intPos = (intPos & 0xf0) | (int)PopupPosition.Left; } break; case PopupPosition.Left: if (caret.Right + request.Width > geometry.Right) { intPos = (intPos & 0xf0) | (int)PopupPosition.Right; } break; } position = (PopupPosition)intPos; UpdatePadding(); // Calculate base coordinate switch ((PopupPosition)((int)position & 0x0f)) { case PopupPosition.Top: y = caret.Bottom + 1; break; case PopupPosition.Bottom: y = caret.Y - request.Height; break; case PopupPosition.Right: x = caret.X - request.Width; break; case PopupPosition.Left: x = caret.Right + 1; break; } int offset; if ((position & PopupPosition.Top) != 0 || (position & PopupPosition.Bottom) != 0) { if (((int)position & 0x10) != 0) { x = caret.X - MinArrowSpacing - Theme.ArrowWidth / 2; } else if (((int)position & 0x20) != 0) { x = caret.Right - request.Width + MinArrowSpacing + Theme.ArrowWidth / 2; } else { x = caret.X + (caret.Width - request.Width) / 2; } if (x < geometry.Left) { x = geometry.Left; } else if (x + request.Width > geometry.Right) { x = geometry.Right - request.Width; } offset = caret.X + caret.Width / 2 - x; if (offset - Theme.ArrowWidth / 2 < MinArrowSpacing) { offset = MinArrowSpacing + Theme.ArrowWidth / 2; } if (offset > request.Width - MinArrowSpacing - Theme.ArrowWidth / 2) { offset = request.Width - MinArrowSpacing - Theme.ArrowWidth / 2; } } else { if (((int)position & 0x10) != 0) { y = caret.Y - MinArrowSpacing - Theme.ArrowWidth / 2; } else if (((int)position & 0x20) != 0) { y = caret.Bottom - request.Height + MinArrowSpacing + Theme.ArrowWidth / 2; } else { y = caret.Y + (caret.Height - request.Height) / 2; } if (y < geometry.Top) { y = geometry.Top; } else if (y + request.Height > geometry.Bottom) { y = geometry.Bottom - request.Height; } if (MaximumYTopBound > 0) { y = Math.Max(MaximumYTopBound, y); } offset = caret.Y + caret.Height / 2 - y; if (offset - Theme.ArrowWidth / 2 < MinArrowSpacing) { offset = MinArrowSpacing + Theme.ArrowWidth / 2; } if (offset > request.Height - MinArrowSpacing - Theme.ArrowWidth / 2) { offset = request.Height - MinArrowSpacing - Theme.ArrowWidth / 2; } } Theme.ArrowOffset = offset; this.position = position; UpdatePadding(); Move(x, y); Show(); if (!ShowWindowShadow && !IsDestroyed) { IdeServices.DesktopService.RemoveWindowShadow(this); } }