Exemple #1
0
        void DrawTab(Context ctx, DockNotebookTab tab, Gdk.Rectangle allocation, Gdk.Rectangle tabBounds, bool highlight, bool active, bool dragging, Pango.Layout la)
        {
            // This logic is stupid to have here, should be in the caller!
            if (dragging)
            {
                tabBounds.X = (int)(tabBounds.X + (dragX - tabBounds.X) * dragXProgress);
                tabBounds.X = Clamp(tabBounds.X, tabStartX, tabEndX - tabBounds.Width);
            }
            double rightPadding = (active ? TabActivePadding.Right : TabPadding.Right) - (LeanWidth / 2);

            rightPadding = (rightPadding * Math.Min(1.0, Math.Max(0.5, (tabBounds.Width - 30) / 70.0)));
            double leftPadding = (active ? TabActivePadding.Left : TabPadding.Left) - (LeanWidth / 2);

            leftPadding = (leftPadding * Math.Min(1.0, Math.Max(0.5, (tabBounds.Width - 30) / 70.0)));
            double bottomPadding = active ? TabActivePadding.Bottom : TabPadding.Bottom;

            DrawTabBackground(this, ctx, allocation, tabBounds.Width, tabBounds.X, active);

            ctx.LineWidth = 1;
            ctx.NewPath();

            // Render Close Button (do this first so we can tell how much text to render)

            var closeButtonAlloation = new Cairo.Rectangle(tabBounds.Right - rightPadding - (tabCloseImage.Width / 2) - CloseButtonMarginRight,
                                                           tabBounds.Height - bottomPadding - tabCloseImage.Height - CloseButtonMarginBottom,
                                                           tabCloseImage.Width, tabCloseImage.Height);

            tab.CloseButtonActiveArea = closeButtonAlloation.Inflate(2, 2);

            bool closeButtonHovered = tracker.Hovered && tab.CloseButtonActiveArea.Contains(tracker.MousePosition);
            bool tabHovered         = tracker.Hovered && tab.Allocation.Contains(tracker.MousePosition);
            bool drawCloseButton    = active || tabHovered;

            if (!closeButtonHovered && tab.DirtyStrength > 0.5)
            {
                ctx.DrawImage(this, tabDirtyImage, closeButtonAlloation.X, closeButtonAlloation.Y);
                drawCloseButton = false;
            }

            if (drawCloseButton)
            {
                ctx.DrawImage(this, tabCloseImage.WithAlpha((closeButtonHovered ? 1.0 : 0.5) * tab.Opacity), closeButtonAlloation.X, closeButtonAlloation.Y);
            }

            // Render Text
            double tw = tabBounds.Width - (leftPadding + rightPadding);

            if (drawCloseButton || tab.DirtyStrength > 0.5)
            {
                tw -= closeButtonAlloation.Width / 2;
            }

            double tx       = tabBounds.X + leftPadding;
            var    baseline = la.GetLine(0).Layout.GetPixelBaseline();
            double ty       = tabBounds.Height - bottomPadding - baseline;

            ctx.MoveTo(tx, ty);
            if (!MonoDevelop.Core.Platform.IsMac && !MonoDevelop.Core.Platform.IsWindows)
            {
                // This is a work around for a linux specific problem.
                // A bug in the proprietary ATI driver caused TAB text not to draw.
                // If that bug get's fixed remove this HACK asap.
                la.Ellipsize = Pango.EllipsizeMode.End;
                la.Width     = (int)(tw * Pango.Scale.PangoScale);
                ctx.SetSourceColor((tab.Notify ? Styles.TabBarNotifyTextColor : (active ? Styles.TabBarActiveTextColor : Styles.TabBarInactiveTextColor)).ToCairoColor());
                Pango.CairoHelper.ShowLayout(ctx, la.GetLine(0).Layout);
            }
            else
            {
                // ellipses are for space wasting ..., we cant afford that
                using (var lg = new LinearGradient(tx + tw - 10, 0, tx + tw, 0)) {
                    var color = (tab.Notify ? Styles.TabBarNotifyTextColor : (active ? Styles.TabBarActiveTextColor : Styles.TabBarInactiveTextColor)).ToCairoColor();
                    color = color.MultiplyAlpha(tab.Opacity);
                    lg.AddColorStop(0, color);
                    color.A = 0;
                    lg.AddColorStop(1, color);
                    ctx.SetSource(lg);
                    Pango.CairoHelper.ShowLayout(ctx, la.GetLine(0).Layout);
                }
            }
            la.Dispose();
        }
		void DrawTab (Context ctx, DockNotebookTab tab, Gdk.Rectangle allocation, Gdk.Rectangle tabBounds, bool highlight, bool active, bool dragging, Pango.Layout la)
		{
			// This logic is stupid to have here, should be in the caller!
			if (dragging) {
				tabBounds.X = (int)(tabBounds.X + (dragX - tabBounds.X) * dragXProgress);
				tabBounds.X = Clamp (tabBounds.X, tabStartX, tabEndX - tabBounds.Width);
			}
			double rightPadding = (active ? TabActivePadding.Right : TabPadding.Right) - (LeanWidth / 2);
			rightPadding = (rightPadding * Math.Min (1.0, Math.Max (0.5, (tabBounds.Width - 30) / 70.0)));
			double leftPadding = (active ? TabActivePadding.Left : TabPadding.Left) - (LeanWidth / 2);
			leftPadding = (leftPadding * Math.Min (1.0, Math.Max (0.5, (tabBounds.Width - 30) / 70.0)));
			double bottomPadding = active ? TabActivePadding.Bottom : TabPadding.Bottom;

			DrawTabBackground (this, ctx, allocation, tabBounds.Width, tabBounds.X, active);

			ctx.LineWidth = 1;
			ctx.NewPath ();

			// Render Close Button (do this first so we can tell how much text to render)

			var closeButtonAlloation = new Cairo.Rectangle (tabBounds.Right - rightPadding - (tabCloseImage.Width / 2) - CloseButtonMarginRight,
			                                 tabBounds.Height - bottomPadding - tabCloseImage.Height - CloseButtonMarginBottom,
			                                 tabCloseImage.Width, tabCloseImage.Height);
			
			tab.CloseButtonActiveArea = closeButtonAlloation.Inflate (2, 2);

			bool closeButtonHovered = tracker.Hovered && tab.CloseButtonActiveArea.Contains (tracker.MousePosition);
			bool tabHovered = tracker.Hovered && tab.Allocation.Contains (tracker.MousePosition);
			bool drawCloseButton = active || tabHovered;

			if (!closeButtonHovered && tab.DirtyStrength > 0.5) {
				ctx.DrawImage (this, tabDirtyImage, closeButtonAlloation.X, closeButtonAlloation.Y);
				drawCloseButton = false;
			}

			if (drawCloseButton)
				ctx.DrawImage (this, tabCloseImage.WithAlpha ((closeButtonHovered ? 1.0 : 0.5) * tab.Opacity), closeButtonAlloation.X, closeButtonAlloation.Y);
			
			// Render Text
			double tw = tabBounds.Width - (leftPadding + rightPadding);
			if (drawCloseButton || tab.DirtyStrength > 0.5)
				tw -= closeButtonAlloation.Width / 2;

			double tx = tabBounds.X + leftPadding;
			var baseline = la.GetLine (0).Layout.GetPixelBaseline ();
			double ty = tabBounds.Height - bottomPadding - baseline;

			ctx.MoveTo (tx, ty);
			if (!MonoDevelop.Core.Platform.IsMac && !MonoDevelop.Core.Platform.IsWindows) {
				// This is a work around for a linux specific problem.
				// A bug in the proprietary ATI driver caused TAB text not to draw.
				// If that bug get's fixed remove this HACK asap.
				la.Ellipsize = Pango.EllipsizeMode.End;
				la.Width = (int)(tw * Pango.Scale.PangoScale);
				ctx.SetSourceColor ((tab.Notify ? Styles.TabBarNotifyTextColor : (active ? Styles.TabBarActiveTextColor : Styles.TabBarInactiveTextColor)).ToCairoColor ());
				Pango.CairoHelper.ShowLayout (ctx, la.GetLine (0).Layout);
			} else {
				// ellipses are for space wasting ..., we cant afford that
				using (var lg = new LinearGradient (tx + tw - 10, 0, tx + tw, 0)) {
					var color = (tab.Notify ? Styles.TabBarNotifyTextColor : (active ? Styles.TabBarActiveTextColor : Styles.TabBarInactiveTextColor)).ToCairoColor ();
					color = color.MultiplyAlpha (tab.Opacity);
					lg.AddColorStop (0, color);
					color.A = 0;
					lg.AddColorStop (1, color);
					ctx.SetSource (lg);
					Pango.CairoHelper.ShowLayout (ctx, la.GetLine (0).Layout);
				}
			}
            la.Dispose ();
		}
Exemple #3
0
        /// <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));
            }
        }
Exemple #4
0
        /// <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);
        }
Exemple #5
0
		/// <summary>
		/// Draws the hover point, if any.
		/// </summary>
		/// <param name="g"></param>
		protected void DrawHoverPoint(Context g)
		{
			ShapeEngine activeEngine = ActiveShapeEngine;

			if (activeEngine != null)
			{
				last_control_pt_size = Math.Min(activeEngine.BrushWidth + 1, 5);
			}
			else
			{
				last_control_pt_size = Math.Min(BrushWidth + 1, 5);
			}

			double controlPointOffset = (double)last_control_pt_size / 2d;

			//Verify that the user isn't changing the tension of a control point and that there is a hover point to draw.
			if (!changing_tension && hover_point.X > -1d)
			{
				Rectangle hoverOuterEllipseRect = new Rectangle(
					hover_point.X - controlPointOffset * 3d, hover_point.Y - controlPointOffset * 3d,
					controlPointOffset * 6d, controlPointOffset * 6d);

				g.FillStrokedEllipse(hoverOuterEllipseRect, hover_color, hover_color, 1);

				g.FillStrokedEllipse(new Rectangle(
					hover_point.X - controlPointOffset, hover_point.Y - controlPointOffset,
					last_control_pt_size, last_control_pt_size), hover_color, hover_color, (int)last_control_pt_size);


				hoverOuterEllipseRect = hoverOuterEllipseRect.Inflate(1, 1);

				//Since the hover point can be outside of the active shape's bounds (hovering over a different shape), a special
				//invalidation call needs to be made for the hover point in order to ensure its visibility at all times.
				PintaCore.Workspace.Invalidate(hoverOuterEllipseRect.ToGdkRectangle());

				last_hover = hoverOuterEllipseRect;
				last_hover = last_hover.Value.Clamp();
			}
		}
Exemple #6
0
		private void InvalidateAfterDraw(Rectangle dirty)
		{
			Document doc = PintaCore.Workspace.ActiveDocument;

			//Inflate to accomodate for previously drawn control points, if any.
			int inflate = (int)(last_control_pt_size * 8d);
			dirty = dirty.Inflate(inflate, inflate);

			// Increase the size of the dirty rect to account for antialiasing.
			if (owner.UseAntialiasing)
			{
				dirty = dirty.Inflate(1, 1);
			}

			//Combine, clamp, and invalidate the dirty Rectangle.
			dirty = ((Rectangle?)dirty).UnionRectangles(last_dirty).Value;
			dirty = dirty.Clamp();
			doc.Workspace.Invalidate(dirty.ToGdkRectangle());

			last_dirty = dirty;
		}