예제 #1
0
        private void OnBeginPrint(object sender, Gtk.BeginPrintArgs args)
        {
            Gtk.PrintOperation op      = (Gtk.PrintOperation)sender;
            Gtk.PrintContext   context = args.Context;
            timestamp_footer = CreateTimestampLayout(context);

            // FIXME: These should be configurable settings later (UI Change)
            margin_top    = CmToPixel(1.5, context.DpiY);
            margin_left   = CmToPixel(1, context.DpiX);
            margin_right  = CmToPixel(1, context.DpiX);
            margin_bottom = 0;
            double max_height = Pango.Units.FromPixels((int)context.Height -
                                                       margin_top - margin_bottom - ComputeFooterHeight(context));

            Gtk.TextIter position;
            Gtk.TextIter end_iter;
            Buffer.GetBounds(out position, out end_iter);

            double page_height = 0;
            bool   done        = position.Compare(end_iter) >= 0;

            while (!done)
            {
                Gtk.TextIter line_end = position;
                if (!line_end.EndsLine())
                {
                    line_end.ForwardToLineEnd();
                }

                int paragraph_number = position.Line;
                int indentation;
                using (Pango.Layout layout = CreateParagraphLayout(
                           context, position, line_end, out indentation)) {
                    Pango.Rectangle ink_rect     = Pango.Rectangle.Zero;
                    Pango.Rectangle logical_rect = Pango.Rectangle.Zero;
                    for (int line_in_paragraph = 0; line_in_paragraph < layout.LineCount;
                         line_in_paragraph++)
                    {
                        Pango.LayoutLine line = layout.GetLine(line_in_paragraph);
                        line.GetExtents(ref ink_rect, ref logical_rect);

                        if (page_height + logical_rect.Height >= max_height)
                        {
                            PageBreak page_break = new PageBreak(
                                paragraph_number, line_in_paragraph);
                            page_breaks.Add(page_break);

                            page_height = 0;
                        }
                        page_height += logical_rect.Height;
                    }

                    position.ForwardLine();
                    done = position.Compare(end_iter) >= 0;
                }
            }

            op.NPages = page_breaks.Count + 1;
        }
예제 #2
0
        private void EllipsizeLayout(int width)
        {
            // no room to draw anything
            if (width < 1)
            {
                layout.SetMarkup("");
                return;
            }

            // plenty of room
            int lw, lh;

            layout.GetPixelSize(out lw, out lh);
            if (width > lw)
            {
                return;
            }

            // not enough room for ...
            int ell_w, ell_h;

            Pango.Layout ell = layout.Copy();
            ell.SetMarkup("...");
            ell.GetPixelSize(out ell_w, out ell_h);
            if (width < ell_w)
            {
                layout.SetMarkup("");
                return;
            }

            // subtract ellipses width
            width -= ell_w;

            int index, trailing;

            Pango.LayoutLine line = layout.GetLine(0);
            if (line.XToIndex(width * 1024, out index, out trailing))
            {
                // Console.WriteLine ("length: {0} index: {1} trailing: {2}", layout.Text.Length, index, trailing);
                // FIXME: breaks on accented chars
                if (index < layout.Text.Length)
                {
                    layout.SetMarkup(layout.Text.Substring(0, index) + "...");
                }
            }
        }
예제 #3
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();
        }
예제 #4
0
        void Setup(Pango.Layout layout)
        {
            Font.Apply(layout);
            layout.Width = (int)(MaximumSize.Width * Pango.Scale.PangoScale);
#if GTK3
            layout.Height = (int)(MaximumSize.Height * Pango.Scale.PangoScale);
#endif
            layout.Ellipsize = Trimming == FormattedTextTrimming.None ? Pango.EllipsizeMode.None : Pango.EllipsizeMode.End;
            switch (Wrap)
            {
            case FormattedTextWrapMode.None:
                // only draw one line!!
                layout.Wrap = Pango.WrapMode.Char;
#if GTK3
                layout.Height = (int)((double)layout.FontDescription.Size / (double)Pango.Scale.PangoScale);
#endif
                break;

            case FormattedTextWrapMode.Word:
                layout.Wrap = Pango.WrapMode.Word;
                break;

            case FormattedTextWrapMode.Character:
                layout.Wrap = Pango.WrapMode.Char;
                break;
            }
            switch (Alignment)
            {
            case FormattedTextAlignment.Left:
                layout.Alignment = Pango.Alignment.Left;
                break;

            case FormattedTextAlignment.Right:
                layout.Alignment = Pango.Alignment.Right;
                break;

            case FormattedTextAlignment.Center:
                layout.Alignment = Pango.Alignment.Center;
                break;

            case FormattedTextAlignment.Justify:
                layout.Alignment = Pango.Alignment.Left;
                layout.Justify   = true;
                break;
            }
            layout.SetText(Text);
            if (Wrap == FormattedTextWrapMode.None && layout.LineCount > 1)
            {
                // line includes the full last word so keep shrinking until it isn't wrapped
                var len = layout.GetLine(0).Length;
                while (len > 0 && layout.IsWrapped)
                {
                    layout.SetText(Text.Substring(0, len--));
                }
            }
            if (Trimming == FormattedTextTrimming.None && layout.LineCount > 1)
            {
                layout.GetPixelSize(out _, out var height);
                while (layout.LineCount > 1 && height > MaximumSize.Height)
                {
                    var lineCount = layout.LineCount;
                    var line      = layout.GetLine(lineCount - 1);
                    var len       = line.StartIndex;
                    layout.SetText(Text.Substring(0, len));
                    if (layout.LineCount == lineCount)
                    {
                        // need to trim off some characters or words from the current line
                        while (layout.LineCount == lineCount && --len > 0)
                        {
                            if (Wrap == FormattedTextWrapMode.Word)
                            {
                                // keep going till whitespace for wrapping.
                                while (len > 0 && !char.IsWhiteSpace(Text[len - 1]))
                                {
                                    len--;
                                }
                            }
                            layout.SetText(Text.Substring(0, len));
                        }
                    }
                    layout.GetPixelSize(out _, out height);
                }
            }
        }
예제 #5
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);
            }
            int padding = LeftRightPadding;

            padding = (int)(padding * Math.Min(1.0, Math.Max(0.5, (tabBounds.Width - 30) / 70.0)));

            ctx.LineWidth = 1;
            LayoutTabBorder(ctx, allocation, tabBounds.Width, tabBounds.X, 0, active);
            ctx.ClosePath();
            using (var gr = new LinearGradient(tabBounds.X, TopBarPadding, tabBounds.X, allocation.Bottom)) {
                if (active)
                {
                    gr.AddColorStop(0, Styles.BreadcrumbGradientStartColor.MultiplyAlpha(tab.Opacity));
                    gr.AddColorStop(1, Styles.BreadcrumbBackgroundColor.MultiplyAlpha(tab.Opacity));
                }
                else
                {
                    gr.AddColorStop(0, CairoExtensions.ParseColor("f4f4f4").MultiplyAlpha(tab.Opacity));
                    gr.AddColorStop(1, CairoExtensions.ParseColor("cecece").MultiplyAlpha(tab.Opacity));
                }
                ctx.SetSource(gr);
            }
            ctx.Fill();

            ctx.SetSourceColor(new Cairo.Color(1, 1, 1, .5).MultiplyAlpha(tab.Opacity));
            LayoutTabBorder(ctx, allocation, tabBounds.Width, tabBounds.X, 1, active);
            ctx.Stroke();

            ctx.SetSourceColor(Styles.BreadcrumbBorderColor.MultiplyAlpha(tab.Opacity));
            LayoutTabBorder(ctx, allocation, tabBounds.Width, tabBounds.X, 0, active);
            ctx.StrokePreserve();

            if (tab.GlowStrength > 0)
            {
                Gdk.Point mouse = tracker.MousePosition;
                using (var rg = new RadialGradient(mouse.X, tabBounds.Bottom, 0, mouse.X, tabBounds.Bottom, 100)) {
                    rg.AddColorStop(0, new Cairo.Color(1, 1, 1, 0.4 * tab.Opacity * tab.GlowStrength));
                    rg.AddColorStop(1, new Cairo.Color(1, 1, 1, 0));

                    ctx.SetSource(rg);
                    ctx.Fill();
                }
            }
            else
            {
                ctx.NewPath();
            }

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

            var ch    = allocation.Height - TopBarPadding - BottomBarPadding + CloseImageTopOffset;
            var crect = new Gdk.Rectangle(tabBounds.Right - padding - CloseButtonSize + 3,
                                          tabBounds.Y + TopBarPadding + (ch - CloseButtonSize) / 2,
                                          CloseButtonSize, CloseButtonSize);

            tab.CloseButtonAllocation = crect;
            tab.CloseButtonAllocation.Inflate(2, 2);

            bool closeButtonHovered = tracker.Hovered && tab.CloseButtonAllocation.Contains(tracker.MousePosition) && tab.WidthModifier >= 1.0f;
            bool drawCloseButton    = tabBounds.Width > 60 || highlight || closeButtonHovered;

            if (drawCloseButton)
            {
                DrawCloseButton(ctx, new Gdk.Point(crect.X + crect.Width / 2, crect.Y + crect.Height / 2), closeButtonHovered, tab.Opacity, tab.DirtyStrength);
            }

            // Render Text
            int w = tabBounds.Width - (padding * 2 + CloseButtonSize);

            if (!drawCloseButton)
            {
                w += CloseButtonSize;
            }

            int textStart = tabBounds.X + padding;

            ctx.MoveTo(textStart, tabBounds.Y + TopPadding + TextOffset + VerticalTextSize);
            if (!Platform.IsMac && !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)(w * Pango.Scale.PangoScale);
                ctx.SetSourceColor(tab.Notify ? new Cairo.Color(0, 0, 1) : Styles.TabBarActiveTextColor);
                Pango.CairoHelper.ShowLayoutLine(ctx, la.GetLine(0));
            }
            else
            {
                // ellipses are for space wasting ..., we cant afford that
                using (var lg = new LinearGradient(textStart + w - 5, 0, textStart + w + 3, 0)) {
                    var color = tab.Notify ? new Cairo.Color(0, 0, 1) : Styles.TabBarActiveTextColor;
                    color = color.MultiplyAlpha(tab.Opacity);
                    lg.AddColorStop(0, color);
                    color.A = 0;
                    lg.AddColorStop(1, color);
                    ctx.SetSource(lg);
                    Pango.CairoHelper.ShowLayoutLine(ctx, la.GetLine(0));
                }
            }
            la.Dispose();
        }
예제 #6
0
 public Pango.LayoutLine GetLine(int line)
 {
     return(layout.GetLine(line));
 }