Example #1
0
        void HandleGtkSizeAllocated(object sender, SizeAllocatedArgs e)
        {
            var scale = GtkWorkarounds.GetScaleFactor(Widget);
            var size  = new System.Drawing.Size((int)(e.Allocation.Width * scale), (int)(e.Allocation.Height * scale));

            view.Size = size;
        }
            public void Start()
            {
                allocation = mode.Allocation;
                var swapSurface = mode.swapIndicatorSurface;

                if (swapSurface != null)
                {
                    if (swapSurface.Width == allocation.Width && swapSurface.Height == allocation.Height)
                    {
                        surface = swapSurface;
                    }
                    else
                    {
                        mode.DestroyIndicatorSwapSurface();
                    }
                }

                var displayScale = Core.Platform.IsMac ? GtkWorkarounds.GetScaleFactor(mode) : 1.0;

                if (surface == null)
                {
                    using (var similiar = CairoHelper.Create(IdeApp.Workbench.RootWindow.GdkWindow))
                        surface = new SurfaceWrapper(similiar, (int)(allocation.Width * displayScale), (int)(allocation.Height * displayScale));
                }

                searchResults = mode.TextEditor.TextViewMargin.SearchResults.ToList().GetEnumerator();
                allUsages     = mode.AllUsages.GetEnumerator();
                allTasks      = mode.AllTasks.GetEnumerator();
                cr            = new Cairo.Context(surface.Surface);
                cr.Scale(displayScale, displayScale);
                GLib.Idle.Add(RunHandler);
            }
Example #3
0
            NSImage GetDeviceImage(bool enabled)
            {
                if (ActiveRuntime == null || string.IsNullOrEmpty(ActiveRuntime.Image))
                {
                    return(enabled ? deviceImage : deviceImageDisabled);
                }
                if (ActiveRuntime.Image == lastDeviceIconId)
                {
                    return(enabled ? lastDeviceImage : lastDeviceImageDisabled);
                }

                lastDeviceIconId = ActiveRuntime.Image;
                var scale = GtkWorkarounds.GetScaleFactor(Ide.IdeApp.Workbench.RootWindow);

                Xwt.Drawing.Image baseIcon = ImageService.GetIcon(ActiveRuntime.Image, Gtk.IconSize.Menu);

                string [] styles, disabledStyles;
                if (IdeApp.Preferences.UserInterfaceTheme == Theme.Dark)
                {
                    styles         = new [] { "dark" };
                    disabledStyles = new [] { "dark", "disabled" };
                }
                else
                {
                    styles         = null;
                    disabledStyles = new [] { "disabled" };
                }

                lastDeviceImage         = FixImageServiceImage(baseIcon, scale, styles);
                lastDeviceImageDisabled = FixImageServiceImage(baseIcon, scale, disabledStyles);
                return(enabled ? lastDeviceImage : lastDeviceImageDisabled);
            }
            public void Start()
            {
                allocation = mode.Allocation;
                var swapSurface = mode.swapIndicatorSurface;

                if (swapSurface != null)
                {
                    if (swapSurface.Width == allocation.Width && swapSurface.Height == allocation.Height)
                    {
                        surface = swapSurface;
                    }
                    else
                    {
                        mode.DestroyIndicatorSwapSurface();
                    }
                }

                var displayScale = Core.Platform.IsMac ? GtkWorkarounds.GetScaleFactor(mode) : 1.0;

                if (surface == null)
                {
                    using (var similiar = CairoHelper.Create(IdeApp.Workbench.RootWindow.GdkWindow))
                        surface = new SurfaceWrapper(similiar, (int)(allocation.Width * displayScale), (int)(allocation.Height * displayScale));
                }
                state        = IndicatorDrawingState.Create();
                state.Width  = allocation.Width;
                state.Height = allocation.Height;
                state.SearchResults.AddRange(mode.TextEditor.TextViewMargin.SearchResults);
                state.Usages.AddRange(mode.AllUsages);
                state.Tasks.AddRange(mode.AllTasks);
                state.ColorCache [IndicatorDrawingState.UsageColor]       = SyntaxHighlightingService.GetColor(mode.TextEditor.EditorTheme, EditorThemeColors.Foreground);
                state.ColorCache [IndicatorDrawingState.UsageColor].Alpha = 0.4;

                state.ColorCache [IndicatorDrawingState.FocusColor] = Styles.FocusColor.ToCairoColor();

                state.ColorCache [IndicatorDrawingState.ChangingUsagesColor] = SyntaxHighlightingService.GetColor(mode.TextEditor.EditorTheme, EditorThemeColors.ChangingUsagesRectangle);
                if (state.ColorCache [IndicatorDrawingState.ChangingUsagesColor].Alpha == 0.0)
                {
                    state.ColorCache [IndicatorDrawingState.ChangingUsagesColor] = SyntaxHighlightingService.GetColor(mode.TextEditor.EditorTheme, EditorThemeColors.UsagesRectangle);
                }

                state.ColorCache [IndicatorDrawingState.UsagesRectangleColor] = SyntaxHighlightingService.GetColor(mode.TextEditor.EditorTheme, EditorThemeColors.UsagesRectangle);
                for (int i = 0; i < 4; i++)
                {
                    state.ColorCache [i].L = 0.4;
                }

                state.ColorCache [IndicatorDrawingState.UnderlineErrorColor]      = SyntaxHighlightingService.GetColor(mode.TextEditor.EditorTheme, EditorThemeColors.UnderlineError);
                state.ColorCache [IndicatorDrawingState.UnderlineWarningColor]    = SyntaxHighlightingService.GetColor(mode.TextEditor.EditorTheme, EditorThemeColors.UnderlineWarning);
                state.ColorCache [IndicatorDrawingState.UnderlineSuggestionColor] = SyntaxHighlightingService.GetColor(mode.TextEditor.EditorTheme, EditorThemeColors.UnderlineSuggestion);
                state.ColorCache [IndicatorDrawingState.BackgroundColor]          = SyntaxHighlightingService.GetColor(mode.TextEditor.EditorTheme, EditorThemeColors.Background);

                ResetEnumerators();

                cr = new Cairo.Context(surface.Surface);
                cr.Scale(displayScale, displayScale);
                GLib.Idle.Add(RunHandler);
            }
            int GetBufferYOffset()
            {
                var displayScale = Platform.IsWindows ? GtkWorkarounds.GetScaleFactor(this) : 1.0;
                int h            = (int)(backgroundPixbuf.ClipRegion.Clipbox.Height / displayScale) - Allocation.Height;

                if (h < 0)
                {
                    return(0);
                }
                return(Math.Max(0, (int)(h * (vadjustment.Value) / (vadjustment.Upper - vadjustment.Lower - vadjustment.PageSize))));
            }
Example #6
0
        void HandleGtkRealized(object sender, EventArgs e)
        {
            var scale = GtkWorkarounds.GetScaleFactor(Widget);
            var size  = new System.Drawing.Size((int)(Widget.Allocation.Width * scale), (int)(Widget.Allocation.Height * scale));

            view.Size = size;

            var    browser_handle = view.Handle;
            IntPtr window_handle  = (IntPtr)socket.Id;

            SetParent(browser_handle, window_handle);
        }
        protected override bool OnExposeEvent(Gdk.EventExpose e)
        {
            if (TextEditor == null)
            {
                return(true);
            }

            using (Cairo.Context cr = Gdk.CairoHelper.Create(e.Window)) {
                var allocation   = Allocation;
                var displayScale = Core.Platform.IsMac ? GtkWorkarounds.GetScaleFactor(this) : 1.0;
                cr.Scale(1 / displayScale, 1 / displayScale);
                if (indicatorSurface != null)
                {
                    cr.SetSourceSurface(indicatorSurface.Surface, 0, 0);
                    cr.Paint();
                }
                else
                {
                    CachedDraw(cr,
                               ref backgroundSurface,
                               allocation,
                               draw: (c, o) => DrawBackground(c, allocation), forceScale: displayScale);
                }
                if (TextEditor == null)
                {
                    return(true);
                }

                DrawCaret(cr);

                if (QuickTaskStrip.MergeScrollBarAndQuickTasks)
                {
                    DrawBar(cr);
                }
            }

            return(true);
        }
Example #8
0
        private void BuildWidget()
        {
            float yscale = 0.0f;

            if (MonoDevelop.Core.Platform.IsWindows)
            {
                yscale = (float)GtkWorkarounds.GetScaleFactor((Widget)this);
            }
            this.alignment = new Gtk.Alignment(0.5f, 0.5f, 1f, yscale);
            this.alignment.SetPadding(1U, 1U, 0U, 0U);
            this.VisibleWindow  = false;
            this.box            = new HBox();
            this.entry          = (Entry) new SearchEntry.FramelessEntry(this);
            this.filter_button  = new CSImageButton();
            this.clear_button   = new CSImageButton();
            this.entryAlignment = new Gtk.Alignment(0.5f, 0.5f, 1f, 1f);
            this.alignment.SetPadding(0U, 0U, 0U, 0U);
            this.entryAlignment.Add((Widget)this.entry);
            this.box.PackStart((Widget)this.filter_button, false, false, 0U);
            this.box.PackStart((Widget)this.entryAlignment, true, true, 0U);
            this.box.PackStart((Widget)this.clear_button, false, false, 0U);
            this.alignment.Add((Widget)this.box);
            this.Add((Widget)this.alignment);
            this.alignment.ShowAll();
            this.entry.StyleSet                   += new StyleSetHandler(this.OnInnerEntryStyleSet);
            this.entry.StateChanged               += new StateChangedHandler(this.OnInnerEntryStateChanged);
            this.entry.FocusInEvent               += new FocusInEventHandler(this.OnInnerEntryFocusEvent);
            this.entry.FocusOutEvent              += new FocusOutEventHandler(this.OnInnerEntryFocusEvent);
            this.entry.Changed                    += new EventHandler(this.OnInnerEntryChanged);
            this.entry.Activated                  += (EventHandler)((param0, param1) => this.NotifyActivated());
            this.filter_button.CanFocus            = false;
            this.clear_button.CanFocus             = false;
            this.filter_button.ButtonReleaseEvent += new ButtonReleaseEventHandler(this.OnButtonReleaseEvent);
            this.clear_button.ButtonReleaseEvent  += new ButtonReleaseEventHandler(this.OnButtonReleaseEvent);
            this.clear_button.Clicked             += new EventHandler(this.OnClearButtonClicked);
            this.ShowHideButtons();
        }
            void CreateBgBuffer()
            {
                DestroyBgBuffer();
                curWidth  = Allocation.Width;
                curHeight = Math.Max(Allocation.Height, (int)(lineHeight * (TextEditor.GetTextEditorData().VisibleLineCount)));
                if (GdkWindow == null || curWidth < 1 || curHeight < 1)
                {
                    return;
                }
                var displayScale = Platform.IsWindows ? GtkWorkarounds.GetScaleFactor(this) : 1.0;

                backgroundPixbuf = new Pixmap(GdkWindow, (int)(curWidth * displayScale), (int)(curHeight * displayScale));
                backgroundBuffer = new Pixmap(GdkWindow, (int)(curWidth * displayScale), (int)(curHeight * displayScale));

                if (TextEditor.ColorStyle != null)
                {
                    using (var cr = Gdk.CairoHelper.Create(backgroundPixbuf)) {
                        cr.Rectangle(0, 0, curWidth * displayScale, curHeight * displayScale);
                        cr.SetSourceColor(TextEditor.ColorStyle.PlainText.Background);
                        cr.Fill();
                    }
                }
                curUpdate = new BgBufferUpdate(this);
            }
Example #10
0
        void SetItemValues(NSMenuItem item, CommandInfo info, bool disabledVisible, string overrideLabel = null)
        {
            item.SetTitleWithMnemonic(GetCleanCommandText(info, overrideLabel));

            bool enabled = info.Enabled && (!IsGloballyDisabled || commandSource == CommandSource.ContextMenu);
            bool visible = info.Visible && (disabledVisible || info.Enabled);

            item.Enabled = enabled;
            item.Hidden  = !visible;

            string fileName = null;
            var    doc      = info.DataItem as Ide.Gui.Document;

            if (doc != null)
            {
                if (doc.IsFile)
                {
                    fileName = doc.FileName;
                }
                else
                {
                    // Designer documents have no file bound to them, but the document name
                    // could be a valid path
                    var docName = doc.Name;
                    if (!string.IsNullOrEmpty(docName) && System.IO.Path.IsPathRooted(docName) && System.IO.File.Exists(docName))
                    {
                        fileName = docName;
                    }
                }
            }
            else if (info.DataItem is NavigationHistoryItem)
            {
                var navDoc = ((NavigationHistoryItem)info.DataItem).NavigationPoint as DocumentNavigationPoint;
                if (navDoc != null)
                {
                    fileName = navDoc.FileName;
                }
            }
            else
            {
                var str = info.DataItem as string;
                if (str != null && System.IO.Path.IsPathRooted(str) && System.IO.File.Exists(str))
                {
                    fileName = str;
                }
            }

            if (!String.IsNullOrWhiteSpace(fileName))
            {
                item.ToolTip = fileName;
                Xwt.Drawing.Image icon = null;
                if (!info.Icon.IsNull)
                {
                    icon = Ide.ImageService.GetIcon(info.Icon, Gtk.IconSize.Menu);
                }
                if (icon == null)
                {
                    icon = Ide.DesktopService.GetIconForFile(fileName, Gtk.IconSize.Menu);
                }
                if (icon != null)
                {
                    var scale = GtkWorkarounds.GetScaleFactor(Ide.IdeApp.Workbench.RootWindow);

                    if (NSUserDefaults.StandardUserDefaults.StringForKey("AppleInterfaceStyle") == "Dark")
                    {
                        icon = icon.WithStyles("dark");
                    }
                    else
                    {
                        icon = icon.WithStyles("-dark");
                    }
                    item.Image          = icon.ToBitmap(scale).ToNSImage();
                    item.Image.Template = true;
                }
            }

            SetAccel(item, info.AccelKey);

            if (info.Checked)
            {
                item.State = NSCellStateValue.On;
            }
            else if (info.CheckedInconsistent)
            {
                item.State = NSCellStateValue.Mixed;
            }
            else
            {
                item.State = NSCellStateValue.Off;
            }
        }
Example #11
0
        protected override bool OnExposeEvent(Gdk.EventExpose args)
        {
            using (var context = Gdk.CairoHelper.Create(args.Window)) {
                var scalef = GtkWorkarounds.GetScaleFactor(this);
                context.LineWidth = 1;
                var alloc  = Allocation;
                int width  = alloc.Width;
                int height = alloc.Height;
                context.Rectangle(args.Area.X, args.Area.Y, args.Area.Width, args.Area.Height);
                var backgroundColor = Styles.CodeCompletion.BackgroundColor.ToCairoColor();
                var textColor       = Styles.CodeCompletion.TextColor.ToCairoColor();
                var categoryColor   = Styles.CodeCompletion.CategoryColor.ToCairoColor();
                context.SetSourceColor(backgroundColor);
                context.Fill();
                int xpos = iconTextSpacing;
                int yPos = (int)-vadj.Value;
                //when there are no matches, display a message to indicate that the completion list is still handling input
                if (filteredItems.Count == 0)
                {
                    context.Rectangle(0, yPos, width, height - yPos);
                    context.SetSourceColor(backgroundColor);
                    context.Stroke();
                    noMatchLayout.SetText(DataProvider.ItemCount == 0 ? NoSuggestionsMsg : NoMatchesMsg);
                    int lWidth, lHeight;
                    noMatchLayout.GetPixelSize(out lWidth, out lHeight);
                    context.SetSourceColor(textColor);
                    context.MoveTo((width - lWidth) / 2, yPos + (height - lHeight - yPos) / 2 - lHeight / 2);
                    Pango.CairoHelper.ShowLayout(context, noMatchLayout);
                    return(false);
                }

                Iterate(true, ref yPos, delegate(CategorizedCompletionItems category, int ypos) {
                    if (ypos >= height)
                    {
                        return;
                    }
                    if (ypos < -rowHeight)
                    {
                        return;
                    }

                    //	window.DrawRectangle (this.Style.BackgroundGC (StateType.Insensitive), true, 0, yPos, width, rowHeight);
                    int x = 2;
                    if (category.CompletionCategory != null && !string.IsNullOrEmpty(category.CompletionCategory.Icon))
                    {
                        var icon = ImageService.GetIcon(category.CompletionCategory.Icon, IconSize.Menu);
                        context.DrawImage(this, icon, 0, ypos);
                        x = (int)icon.Width + 4;
                    }
                    context.Rectangle(0, ypos, Allocation.Width, rowHeight);
                    context.SetSourceColor(backgroundColor);
                    context.Fill();


                    //					layout.SetMarkup ("<span weight='bold' foreground='#AAAAAA'>" + (category.CompletionCategory != null ? category.CompletionCategory.DisplayText : "Uncategorized") + "</span>");
                    //					window.DrawLayout (textGCInsensitive, x - 1, ypos + 1 + (rowHeight - py) / 2, layout);
                    //					layout.SetMarkup ("<span weight='bold'>" + (category.CompletionCategory != null ? category.CompletionCategory.DisplayText : "Uncategorized") + "</span>");
                    categoryLayout.SetMarkup((category.CompletionCategory != null ? category.CompletionCategory.DisplayText : "Uncategorized"));
                    int px, py;
                    categoryLayout.GetPixelSize(out px, out py);
                    context.MoveTo(x, ypos + (rowHeight - py) / 2);
                    context.SetSourceColor(categoryColor);
                    Pango.CairoHelper.ShowLayout(context, categoryLayout);
                }, delegate(CategorizedCompletionItems curCategory, int item, int itemidx, int ypos) {
                    if (ypos >= height)
                    {
                        return(false);
                    }
                    if (ypos < -rowHeight)
                    {
                        return(true);
                    }
                    const int categoryModeItemIndenting = 0;
                    if (InCategoryMode && curCategory != null && curCategory.CompletionCategory != null)
                    {
                        xpos = iconTextSpacing + categoryModeItemIndenting;
                    }
                    else
                    {
                        xpos = iconTextSpacing;
                    }
                    bool drawIconAsSelected = SelectionEnabled && item == SelectedItemIndex;
                    string markup           = DataProvider.HasMarkup(item) ? (DataProvider.GetMarkup(item) ?? "&lt;null&gt;") : GLib.Markup.EscapeText(DataProvider.GetText(item) ?? "<null>");
                    string description      = DataProvider.GetDescription(item, drawIconAsSelected);

                    if (string.IsNullOrEmpty(description))
                    {
                        layout.SetMarkup(markup);
                    }
                    else
                    {
                        layout.SetMarkup(markup + " " + description);
                    }

                    string text = DataProvider.GetText(item);

                    if (!string.IsNullOrEmpty(text))
                    {
                        int [] matchIndices = DataProvider.GetHighlightedTextIndices(item);
                        if (matchIndices != null)
                        {
                            Pango.AttrList attrList = layout.Attributes ?? new Pango.AttrList();
                            for (int newSelection = 0; newSelection < matchIndices.Length; newSelection++)
                            {
                                int idx  = matchIndices [newSelection];
                                var bold = new AttrWeight(Weight.Bold);

                                bold.StartIndex = (uint)idx;
                                bold.EndIndex   = (uint)(idx + 1);
                                attrList.Insert(bold);

                                if (item != SelectedItemIndex)
                                {
                                    var highlightColor = (item == SelectedItemIndex) ? Styles.CodeCompletion.SelectionHighlightColor : Styles.CodeCompletion.HighlightColor;
                                    var fg             = new AttrForeground((ushort)(highlightColor.Red * ushort.MaxValue), (ushort)(highlightColor.Green * ushort.MaxValue), (ushort)(highlightColor.Blue * ushort.MaxValue));
                                    fg.StartIndex      = (uint)idx;
                                    fg.EndIndex        = (uint)(idx + 1);
                                    attrList.Insert(fg);
                                }
                            }
                            layout.Attributes = attrList;
                        }
                    }

                    Xwt.Drawing.Image icon = DataProvider.GetIcon(item);
                    int iconHeight, iconWidth;
                    if (icon != null)
                    {
                        if (drawIconAsSelected)
                        {
                            icon = icon.WithStyles("sel");
                        }
                        iconWidth  = (int)icon.Width;
                        iconHeight = (int)icon.Height;
                    }
                    else if (!Gtk.Icon.SizeLookup(IconSize.Menu, out iconWidth, out iconHeight))
                    {
                        iconHeight = iconWidth = 24;
                    }

                    int wi, he, typos, iypos;
                    layout.GetPixelSize(out wi, out he);


                    typos = he < rowHeight ? ypos + (int)Math.Ceiling((rowHeight - he) / 2.0) : ypos;
                    if (scalef <= 1.0)
                    {
                        typos -= 1;                 // 1px up on non HiDPI
                    }
                    iypos = iconHeight < rowHeight ? ypos + (rowHeight - iconHeight) / 2 : ypos;
                    if (item == SelectedItemIndex)
                    {
                        var barStyle = SelectionEnabled ? Styles.CodeCompletion.SelectionBackgroundColor : Styles.CodeCompletion.SelectionBackgroundInactiveColor;
                        context.SetSourceColor(barStyle.ToCairoColor());

                        if (SelectionEnabled)
                        {
                            context.Rectangle(0, ypos, Allocation.Width, rowHeight);
                            context.Fill();
                        }
                        else
                        {
                            context.LineWidth++;
                            context.Rectangle(0.5, ypos + 0.5, Allocation.Width - 1, rowHeight - 1);
                            context.Stroke();
                            context.LineWidth--;
                        }
                    }

                    if (icon != null)
                    {
                        context.DrawImage(this, icon, xpos, iypos);
                        xpos += iconTextSpacing;
                    }
                    context.SetSourceColor((drawIconAsSelected ? Styles.CodeCompletion.SelectionTextColor : Styles.CodeCompletion.TextColor).ToCairoColor());
                    var textXPos = xpos + iconWidth + 2;
                    context.MoveTo(textXPos, typos);
                    layout.Width     = (int)((Allocation.Width - textXPos) * Pango.Scale.PangoScale);
                    layout.Ellipsize = EllipsizeMode.End;
                    Pango.CairoHelper.ShowLayout(context, layout);
                    int textW, textH;
                    layout.GetPixelSize(out textW, out textH);
                    layout.Width     = -1;
                    layout.Ellipsize = EllipsizeMode.None;

                    layout.SetMarkup("");
                    if (layout.Attributes != null)
                    {
                        layout.Attributes.Dispose();
                        layout.Attributes = null;
                    }

                    string rightText = DataProvider.GetRightSideDescription(item, drawIconAsSelected);
                    if (!string.IsNullOrEmpty(rightText))
                    {
                        layout.SetMarkup(rightText);

                        int w, h;
                        layout.GetPixelSize(out w, out h);
                        const int leftpadding  = 8;
                        const int rightpadding = 3;
                        w    += rightpadding;
                        w     = Math.Min(w, Allocation.Width - textXPos - textW - leftpadding);
                        wi   += w;
                        typos = h < rowHeight ? ypos + (rowHeight - h) / 2 : ypos;
                        if (scalef <= 1.0)
                        {
                            typos -= 1;                             // 1px up on non HiDPI
                        }
                        context.MoveTo(Allocation.Width - w, typos);
                        layout.Width     = (int)(w * Pango.Scale.PangoScale);
                        layout.Ellipsize = EllipsizeMode.End;

                        Pango.CairoHelper.ShowLayout(context, layout);
                        layout.Width     = -1;
                        layout.Ellipsize = EllipsizeMode.None;
                    }

                    if (Math.Min(maxListWidth, wi + xpos + iconWidth + 2) > listWidth)
                    {
                        WidthRequest = listWidth = Math.Min(maxListWidth, wi + xpos + iconWidth + 2 + iconTextSpacing);
                        win.ResetSizes();
                    }
                    else
                    {
                        //workaround for the vscrollbar display - the calculated width needs to be the width ofthe render region.
                        if (Allocation.Width < listWidth)
                        {
                            if (listWidth - Allocation.Width < 30)
                            {
                                WidthRequest = listWidth + listWidth - Allocation.Width;
                                win.ResetSizes();
                            }
                        }
                    }

                    return(true);
                });

                return(false);
            }
        }
Example #12
0
        public bool Run(AlertDialogData data)
        {
            using (var alert = new NSAlert()) {
                alert.Window.Title = data.Title ?? BrandingService.ApplicationName;
                IdeTheme.ApplyTheme(alert.Window);

                bool stockIcon;
                if (data.Message.Icon == MonoDevelop.Ide.Gui.Stock.Error || data.Message.Icon == Gtk.Stock.DialogError)
                {
                    alert.AlertStyle = NSAlertStyle.Critical;
                    stockIcon        = true;
                }
                else if (data.Message.Icon == MonoDevelop.Ide.Gui.Stock.Warning || data.Message.Icon == Gtk.Stock.DialogWarning)
                {
                    alert.AlertStyle = NSAlertStyle.Critical;
                    stockIcon        = true;
                }
                else
                {
                    alert.AlertStyle = NSAlertStyle.Informational;
                    stockIcon        = data.Message.Icon == MonoDevelop.Ide.Gui.Stock.Information;
                }

                if (!stockIcon && !string.IsNullOrEmpty(data.Message.Icon))
                {
                    var img = ImageService.GetIcon(data.Message.Icon, Gtk.IconSize.Dialog);
                    // HACK: VK The icon is not rendered in dark style correctly
                    //       Use light variant and reder it here
                    //       as long as NSAppearance.NameVibrantDark is broken
                    if (IdeTheme.UserInterfaceSkin == Skin.Dark)
                    {
                        alert.Icon = img.WithStyles("-dark").ToBitmap(GtkWorkarounds.GetScaleFactor()).ToNSImage();
                    }
                    else
                    {
                        alert.Icon = img.ToNSImage();
                    }
                }
                else
                {
                    //for some reason the NSAlert doesn't pick up the app icon by default
                    alert.Icon = NSApplication.SharedApplication.ApplicationIconImage;
                }

                alert.MessageText     = data.Message.Text;
                alert.InformativeText = data.Message.SecondaryText ?? "";

                var buttons = data.Buttons.Reverse().ToList();

                for (int i = 0; i < buttons.Count - 1; i++)
                {
                    if (i == data.Message.DefaultButton)
                    {
                        var next = buttons[i];
                        for (int j = buttons.Count - 1; j >= i; j--)
                        {
                            var tmp = buttons[j];
                            buttons[j] = next;
                            next       = tmp;
                        }
                        break;
                    }
                }

                var wrappers = new List <AlertButtonWrapper> (buttons.Count);
                foreach (var button in buttons)
                {
                    var label = button.Label;
                    if (button.IsStockButton)
                    {
                        label = Gtk.Stock.Lookup(label).Label;
                    }
                    label = label.Replace("_", "");

                    //this message seems to be a standard Mac message since alert handles it specially
                    if (button == AlertButton.CloseWithoutSave)
                    {
                        label = GettextCatalog.GetString("Don't Save");
                    }

                    var nsbutton      = alert.AddButton(label);
                    var wrapperButton = new AlertButtonWrapper(nsbutton, data.Message, button, alert);
                    wrappers.Add(wrapperButton);
                    nsbutton.Target = wrapperButton;
                    nsbutton.Action = new ObjCRuntime.Selector("buttonActivatedAction");
                }


                NSButton[] optionButtons = null;
                if (data.Options.Count > 0)
                {
                    var box = new MDBox(LayoutDirection.Vertical, 2, 2);
                    optionButtons = new NSButton[data.Options.Count];

                    for (int i = data.Options.Count - 1; i >= 0; i--)
                    {
                        var option = data.Options[i];
                        var button = new NSButton {
                            Title = option.Text,
                            Tag   = i,
                            State = option.Value? NSCellStateValue.On : NSCellStateValue.Off,
                        };
                        button.SetButtonType(NSButtonType.Switch);
                        optionButtons[i] = button;
                        box.Add(new MDAlignment(button, true)
                        {
                            XAlign = LayoutAlign.Begin
                        });
                    }

                    box.Layout();
                    alert.AccessoryView = box.View;
                }

                NSButton applyToAllCheck = null;
                if (data.Message.AllowApplyToAll)
                {
                    alert.ShowsSuppressionButton = true;
                    applyToAllCheck       = alert.SuppressionButton;
                    applyToAllCheck.Title = GettextCatalog.GetString("Apply to all");
                }

                // Hack up a slightly wider than normal alert dialog. I don't know how to do this in a nicer way
                // as the min size constraints are apparently ignored.
                var frame = alert.Window.Frame;
                alert.Window.SetFrame(new CGRect(frame.X, frame.Y, NMath.Max(frame.Width, 600), frame.Height), true);
                alert.Layout();

                bool completed = false;
                if (data.Message.CancellationToken.CanBeCanceled)
                {
                    data.Message.CancellationToken.Register(delegate {
                        alert.InvokeOnMainThread(() => {
                            if (!completed)
                            {
                                NSApplication.SharedApplication.AbortModal();
                            }
                        });
                    });
                }

                if (!data.Message.CancellationToken.IsCancellationRequested)
                {
                    var result = (int)alert.RunModal() - (long)(int)NSAlertButtonReturn.First;

                    completed = true;
                    if (result >= 0 && result < buttons.Count)
                    {
                        data.ResultButton = buttons [(int)result];
                    }
                    else
                    {
                        data.ResultButton = null;
                    }
                }

                if (data.ResultButton == null || data.Message.CancellationToken.IsCancellationRequested)
                {
                    data.SetResultToCancelled();
                }

                if (optionButtons != null)
                {
                    foreach (var button in optionButtons)
                    {
                        var option = data.Options[(int)button.Tag];
                        data.Message.SetOptionValue(option.Id, button.State != 0);
                    }
                }

                if (applyToAllCheck != null && applyToAllCheck.State != 0)
                {
                    data.ApplyToAll = true;
                }



                GtkQuartz.FocusWindow(data.TransientFor ?? MessageService.RootWindow);
            }

            return(true);
        }
Example #13
0
        public bool Run(AlertDialogData data)
        {
            using (var alert = new NSAlert()) {
                alert.Window.Title = data.Title ?? BrandingService.ApplicationName;
                IdeTheme.ApplyTheme(alert.Window);

                bool stockIcon;
                if (data.Message.Icon == MonoDevelop.Ide.Gui.Stock.Error || data.Message.Icon == Gtk.Stock.DialogError)
                {
                    alert.AlertStyle = NSAlertStyle.Critical;
                    stockIcon        = true;
                }
                else if (data.Message.Icon == MonoDevelop.Ide.Gui.Stock.Warning || data.Message.Icon == Gtk.Stock.DialogWarning)
                {
                    alert.AlertStyle = NSAlertStyle.Critical;
                    stockIcon        = true;
                }
                else
                {
                    alert.AlertStyle = NSAlertStyle.Informational;
                    stockIcon        = data.Message.Icon == MonoDevelop.Ide.Gui.Stock.Information;
                }

                if (!stockIcon && !string.IsNullOrEmpty(data.Message.Icon))
                {
                    var img = ImageService.GetIcon(data.Message.Icon, Gtk.IconSize.Dialog);
                    // HACK: The icon is not rendered in dark mode (VibrantDark or DarkAqua) correctly.
                    //       Use light variant and reder it here.
                    // TODO: Recheck rendering issues with DarkAqua on final Mojave
                    if (IdeTheme.UserInterfaceTheme == Theme.Dark)
                    {
                        alert.Icon = img.WithStyles("-dark").ToBitmap(GtkWorkarounds.GetScaleFactor()).ToNSImage();
                    }
                    else
                    {
                        alert.Icon = img.ToNSImage();
                    }
                }
                else
                {
                    //for some reason the NSAlert doesn't pick up the app icon by default
                    alert.Icon = NSApplication.SharedApplication.ApplicationIconImage;
                }

                alert.MessageText = data.Message.Text;

                int accessoryViewItemsCount = data.Options.Count;

                string secondaryText = data.Message.SecondaryText ?? string.Empty;
                if (TryGetMessageView(secondaryText, out NSView messageView))
                {
                    accessoryViewItemsCount++;
                }
                else
                {
                    alert.InformativeText = secondaryText;
                }

                var accessoryViews      = accessoryViewItemsCount > 0 ? new NSView [accessoryViewItemsCount] : null;
                int accessoryViewsIndex = 0;

                if (messageView != null)
                {
                    accessoryViews [accessoryViewsIndex++] = messageView;
                }

                var buttons = data.Buttons.Reverse().ToList();

                for (int i = 0; i < buttons.Count - 1; i++)
                {
                    if (i == data.Message.DefaultButton)
                    {
                        var next = buttons[i];
                        for (int j = buttons.Count - 1; j >= i; j--)
                        {
                            var tmp = buttons[j];
                            buttons[j] = next;
                            next       = tmp;
                        }
                        break;
                    }
                }

                var wrappers = new List <AlertButtonWrapper> (buttons.Count);
                foreach (var button in buttons)
                {
                    var label = button.Label;
                    if (button.IsStockButton)
                    {
                        label = Gtk.Stock.Lookup(label).Label;
                    }
                    label = label.Replace("_", "");

                    //this message seems to be a standard Mac message since alert handles it specially
                    if (button == AlertButton.CloseWithoutSave)
                    {
                        label = GettextCatalog.GetString("Don't Save");
                    }

                    var nsbutton      = alert.AddButton(label);
                    var wrapperButton = new AlertButtonWrapper(nsbutton, data.Message, button, alert);
                    wrappers.Add(wrapperButton);
                    nsbutton.Target = wrapperButton;
                    nsbutton.Action = new ObjCRuntime.Selector("buttonActivatedAction");
                }

                NSButton [] optionButtons = null;
                if (data.Options.Count > 0)
                {
                    optionButtons = new NSButton [data.Options.Count];

                    for (int i = data.Options.Count - 1; i >= 0; i--)
                    {
                        var option = data.Options[i];
                        var button = new NSButton {
                            Title = option.Text,
                            Tag   = i,
                            State = option.Value? NSCellStateValue.On : NSCellStateValue.Off,
                        };
                        button.SetButtonType(NSButtonType.Switch);
                        button.SizeToFit();
                        optionButtons [i] = button;
                        accessoryViews [accessoryViewsIndex++] = button;
                    }
                }

                var accessoryView = ArrangeAccessoryViews(accessoryViews);
                if (accessoryView != null)
                {
                    if (accessoryViews?[0] == messageView)
                    {
                        accessoryView.SetCustomSpacing(accessoryView.Spacing * 2, messageView);
                        var size = accessoryView.Frame.Size;
                        size.Height += accessoryView.Spacing;
                        accessoryView.SetFrameSize(size);
                    }
                    alert.AccessoryView = accessoryView;
                }

                NSButton applyToAllCheck = null;
                if (data.Message.AllowApplyToAll)
                {
                    alert.ShowsSuppressionButton = true;
                    applyToAllCheck       = alert.SuppressionButton;
                    applyToAllCheck.Title = GettextCatalog.GetString("Apply to all");
                }

                // Hack up a slightly wider than normal alert dialog. I don't know how to do this in a nicer way
                // as the min size constraints are apparently ignored.
                var frame = alert.Window.Frame;
                alert.Window.SetFrame(new CGRect(frame.X, frame.Y, NMath.Max(frame.Width, 600), frame.Height), true);
                alert.Layout();

                bool completed = false;
                if (data.Message.CancellationToken.CanBeCanceled)
                {
                    data.Message.CancellationToken.Register(delegate {
                        alert.InvokeOnMainThread(() => {
                            if (!completed)
                            {
                                if (alert.Window.IsSheet && alert.Window.SheetParent != null)
                                {
                                    alert.Window.SheetParent.EndSheet(alert.Window);
                                }
                                else
                                {
                                    NSApplication.SharedApplication.AbortModal();
                                }
                            }
                        });
                    });
                }

                int response = -1000;

                var parent = data.TransientFor;
                if (parent == null && IdeApp.Workbench?.RootWindow?.Visible == true)
                {
                    parent = IdeApp.Workbench?.RootWindow;
                }
                NSWindow nativeParent;
                try {
                    nativeParent = parent;
                } catch (NotSupportedException) {
                    nativeParent = null;
                }
                if (!data.Message.CancellationToken.IsCancellationRequested)
                {
                    // sheeting is broken on High Sierra with dark NSAppearance
                    var sheet = IdeTheme.UserInterfaceTheme != Theme.Dark || MacSystemInformation.OsVersion != MacSystemInformation.HighSierra;

                    // We have an issue with accessibility when using sheets, so disable it here
                    sheet &= !IdeServices.DesktopService.AccessibilityInUse;

                    if (!sheet || nativeParent == null)
                    {
                        // Force the alert window to be focused for accessibility
                        NSApplication.SharedApplication.AccessibilityFocusedWindow = alert.Window;
                        alert.Window.AccessibilityFocused = true;

                        if (nativeParent != null)
                        {
                            nativeParent.AccessibilityFocused = false;
                        }

                        alert.Window.ReleasedWhenClosed = true;
                        response = (int)alert.RunModal();

                        // Focus the old window
                        NSApplication.SharedApplication.AccessibilityFocusedWindow = nativeParent;
                    }
                    else
                    {
                        alert.BeginSheet(nativeParent, (modalResponse) => {
                            response = (int)modalResponse;
                            NSApplication.SharedApplication.StopModal();
                        });

                        NSApplication.SharedApplication.RunModalForWindow(alert.Window);
                    }
                }

                var result = response - (long)(int)NSAlertButtonReturn.First;

                completed = true;

                if (result >= 0 && result < buttons.Count)
                {
                    data.ResultButton = buttons [(int)result];
                }
                else
                {
                    data.ResultButton = null;
                }

                if (data.ResultButton == null || data.Message.CancellationToken.IsCancellationRequested)
                {
                    data.SetResultToCancelled();
                }

                if (optionButtons != null)
                {
                    foreach (var button in optionButtons)
                    {
                        var option = data.Options[(int)button.Tag];
                        data.Message.SetOptionValue(option.Id, button.State != 0);
                    }
                }

                if (applyToAllCheck != null && applyToAllCheck.State != 0)
                {
                    data.ApplyToAll = true;
                }

                if (nativeParent != null)
                {
                    nativeParent.MakeKeyAndOrderFront(nativeParent);
                }
                else
                {
                    IdeServices.DesktopService.FocusWindow(parent);
                }
            }

            return(true);
        }
Example #14
0
            bool RunHandler()
            {
tokenExit:
                if (token.IsCancellationRequested || mode.TextEditor.GetTextEditorData() == null)
                {
                    cr.Dispose();
                    // if the surface was newly created dispose it otherwise it'll leak.
                    if (surface != mode.swapIndicatorSurface)
                    {
                        surface.Dispose();
                    }
                    return(false);
                }
                bool nextStep = false;

                switch (drawingStep)
                {
                case 0:
                    for (int i = 0; i < 10 && !nextStep; i++)
                    {
                        if (token.IsCancellationRequested)
                        {
                            goto tokenExit;
                        }
                        if (mode.TextEditor.HighlightSearchPattern)
                        {
                            mode.GetSearchResultIndicator(state, searchResults, ref nextStep);
                        }
                        else
                        {
                            if (!Debugger.DebuggingService.IsDebugging)
                            {
                                mode.GetQuickTasks(state, allUsages, allTasks, ref nextStep);
                            }
                            else
                            {
                                nextStep = true;
                            }
                        }
                    }
                    if (nextStep)
                    {
                        drawingStep++;
                        nextStep = false;
                        if (!ForceUpdate && state.Equals(mode.currentDrawingState))
                        {
                            cr.Dispose();
                            // if the surface was newly created dispose it otherwise it'll leak.
                            if (surface != mode.swapIndicatorSurface)
                            {
                                surface.Dispose();
                            }
                            IndicatorDrawingState.Dispose(state);
                            return(false);
                        }
                    }
                    return(true);

                case 1:
                    var displayScale = Core.Platform.IsMac ? GtkWorkarounds.GetScaleFactor(mode) : 1.0;
                    mode.DrawBackground(cr, allocation);
                    drawingStep++;

                    state.taskIterator  = 0;
                    state.usageIterator = 0;
                    curIndex            = 0;
                    return(true);

                case 2:
                    for (int i = 0; i < 10 && !nextStep; i++)
                    {
                        if (token.IsCancellationRequested)
                        {
                            goto tokenExit;
                        }
                        if (mode.TextEditor.HighlightSearchPattern)
                        {
                            if (curIndex < state.SearchResultIndicators.Count)
                            {
                                mode.DrawSearchResults(cr, state, curIndex++);
                            }
                            else
                            {
                                nextStep = true;
                            }
                        }
                        else
                        {
                            if (!Debugger.DebuggingService.IsDebugging)
                            {
                                mode.DrawQuickTasks(cr, state, curIndex++, ref nextStep);
                            }
                            else
                            {
                                nextStep = true;
                            }
                        }
                    }
                    if (nextStep)
                    {
                        drawingStep++;
                    }
                    return(true);

                case 3:
                    if (mode.TextEditor.HighlightSearchPattern)
                    {
                        mode.DrawSearchIndicator(cr);
                    }
                    else
                    {
                        if (!Debugger.DebuggingService.IsDebugging)
                        {
                            mode.DrawIndicator(cr, state.Severity);
                        }
                    }
                    drawingStep++;
                    return(true);

                default:
                    mode.DrawBreakpoints(cr);
                    cr.Dispose();
                    var tmp = mode.indicatorSurface;
                    mode.indicatorSurface     = surface;
                    mode.swapIndicatorSurface = tmp;
                    IndicatorDrawingState.Dispose(mode.currentDrawingState);
                    mode.currentDrawingState = state;
                    mode.QueueDraw();

                    return(false);
                }
            }
            bool RunHandler()
            {
tokenExit:
                if (token.IsCancellationRequested || mode.TextEditor.GetTextEditorData() == null)
                {
                    cr.Dispose();
                    // if the surface was newly created dispose it otherwise it'll leak.
                    if (surface != mode.swapIndicatorSurface)
                    {
                        surface.Dispose();
                    }
                    return(false);
                }
                var lineCache = new List <HashSet <int> > ();

                lineCache.Add(new HashSet <int> ());
                lineCache.Add(new HashSet <int> ());
                bool nextStep = false;

                switch (drawingStep)
                {
                case 0:
                    var displayScale = Core.Platform.IsMac ? GtkWorkarounds.GetScaleFactor(mode) : 1.0;
                    mode.DrawBackground(cr, allocation);
                    drawingStep++;
                    return(true);

                case 1:
                    for (int i = 0; i < 10 && !nextStep; i++)
                    {
                        if (token.IsCancellationRequested)
                        {
                            goto tokenExit;
                        }
                        if (mode.TextEditor.HighlightSearchPattern)
                        {
                            mode.DrawSearchResults(cr, searchResults, ref nextStep);
                        }
                        else
                        {
                            if (!Debugger.DebuggingService.IsDebugging)
                            {
                                mode.DrawQuickTasks(cr, allUsages, allTasks, ref nextStep, ref severity, lineCache);
                            }
                            else
                            {
                                nextStep = true;
                            }
                        }
                    }
                    if (nextStep)
                    {
                        drawingStep++;
                    }
                    return(true);

                case 2:
                    if (mode.TextEditor.HighlightSearchPattern)
                    {
                        mode.DrawSearchIndicator(cr);
                    }
                    else
                    {
                        if (!Debugger.DebuggingService.IsDebugging)
                        {
                            mode.DrawIndicator(cr, severity);
                        }
                    }
                    drawingStep++;
                    return(true);

                default:
                    cr.Dispose();
                    var tmp = mode.indicatorSurface;
                    mode.indicatorSurface     = surface;
                    mode.swapIndicatorSurface = tmp;
                    mode.QueueDraw();

                    return(false);
                }
            }
Example #16
0
        protected override bool OnExposeEvent(Gdk.EventExpose args)
        {
            bool needsRefresh = false;

            using (var context = Gdk.CairoHelper.Create(args.Window)) {
                var scalef = GtkWorkarounds.GetScaleFactor(this);
                context.LineWidth = 1;
                var alloc  = Allocation;
                int width  = alloc.Width;
                int height = alloc.Height;
                context.Rectangle(args.Area.X, args.Area.Y, args.Area.Width, args.Area.Height);
                var backgroundColor = Styles.CodeCompletion.BackgroundColor.ToCairoColor();
                var textColor       = Styles.CodeCompletion.TextColor.ToCairoColor();
                var categoryColor   = Styles.CodeCompletion.CategoryColor.ToCairoColor();
                context.SetSourceColor(backgroundColor);
                context.Fill();
                int xpos = iconTextSpacing;
                int yPos = (int)-vadj.Value;
                //when there are no matches, display a message to indicate that the completion list is still handling input
                if (filteredItems.Count == 0)
                {
                    context.Rectangle(0, yPos, width, height - yPos);
                    context.SetSourceColor(backgroundColor);
                    context.Stroke();
                    //TODO: David, line below is simplified noMatchLayout.SetText (DataProvider.ItemCount == 0 ? NoSuggestionsMsg : NoMatchesMsg);
                    noMatchLayout.SetText(NoSuggestionsMsg);
                    int lWidth, lHeight;
                    noMatchLayout.GetPixelSize(out lWidth, out lHeight);
                    context.SetSourceColor(textColor);
                    context.MoveTo((width - lWidth) / 2, yPos + (height - lHeight - yPos) / 2 - lHeight / 2);
                    Pango.CairoHelper.ShowLayout(context, noMatchLayout);
                    return(false);
                }

                Iterate(true, ref yPos, delegate(int index, int itemidx, int ypos) {
                    if (ypos >= height)
                    {
                        return(false);
                    }
                    if (ypos < -rowHeight)
                    {
                        return(true);
                    }
                    xpos                    = iconTextSpacing;
                    var selected            = index == SelectedItemIndex;
                    bool drawIconAsSelected = SelectionEnabled && selected;
                    var item                = filteredItems [index];
                    string markup           = GLib.Markup.EscapeText(item.DisplayText);
                    string description      = "";               //TODO: David DataProvider.GetDescription (item, drawIconAsSelected);

                    if (string.IsNullOrEmpty(description))
                    {
                        layout.SetMarkup(markup);
                    }
                    else
                    {
                        layout.SetMarkup(markup + " " + description);
                    }

                    string text = item.DisplayText;

                    //TODO: David, where do we get HighlightedSpans?
                    //if (!string.IsNullOrEmpty (text) && item.HighlightedSpans.Any ()) {
                    //	Pango.AttrList attrList = layout.Attributes ?? new Pango.AttrList ();
                    //	foreach (var span in item.HighlightedSpans) {
                    //		var bold = new AttrWeight (Weight.Bold);

                    //		bold.StartIndex = (uint)span.Start;
                    //		bold.EndIndex = (uint)span.End;
                    //		attrList.Insert (bold);

                    //		if (!selected) {
                    //			var highlightColor = (selected) ? Styles.CodeCompletion.SelectionHighlightColor : Styles.CodeCompletion.HighlightColor;
                    //			var fg = new AttrForeground ((ushort)(highlightColor.Red * ushort.MaxValue), (ushort)(highlightColor.Green * ushort.MaxValue), (ushort)(highlightColor.Blue * ushort.MaxValue));
                    //			fg.StartIndex = (uint)span.Start;
                    //			fg.EndIndex = (uint)span.End;
                    //			attrList.Insert (fg);
                    //		}
                    //	}
                    //	layout.Attributes = attrList;
                    //}

                    Xwt.Drawing.Image icon = ImageService.GetIcon(GetIcon(item));
                    int iconHeight, iconWidth;
                    if (icon != null)
                    {
                        if (drawIconAsSelected)
                        {
                            icon = icon.WithStyles("sel");
                        }
                        iconWidth  = (int)icon.Width;
                        iconHeight = (int)icon.Height;
                    }
                    else if (!Gtk.Icon.SizeLookup(IconSize.Menu, out iconWidth, out iconHeight))
                    {
                        iconHeight = iconWidth = 24;
                    }

                    int wi, he, typos, iypos;
                    layout.GetPixelSize(out wi, out he);


                    typos = he < rowHeight ? ypos + (int)Math.Ceiling((rowHeight - he) / 2.0) : ypos;
                    if (scalef <= 1.0)
                    {
                        typos -= 1;                         // 1px up on non HiDPI
                    }
                    iypos = iconHeight < rowHeight ? ypos + (rowHeight - iconHeight) / 2 : ypos;
                    if (selected)
                    {
                        var barStyle = SelectionEnabled ? Styles.CodeCompletion.SelectionBackgroundColor : Styles.CodeCompletion.SelectionBackgroundInactiveColor;
                        context.SetSourceColor(barStyle.ToCairoColor());

                        if (SelectionEnabled)
                        {
                            context.Rectangle(0, ypos, Allocation.Width, rowHeight);
                            context.Fill();
                        }
                        else
                        {
                            context.LineWidth++;
                            context.Rectangle(0.5, ypos + 0.5, Allocation.Width - 1, rowHeight - 1);
                            context.Stroke();
                            context.LineWidth--;
                        }
                    }

                    if (icon != null)
                    {
                        context.DrawImage(this, icon, xpos, iypos);
                        xpos += iconTextSpacing;
                    }
                    context.SetSourceColor((drawIconAsSelected ? Styles.CodeCompletion.SelectionTextColor : Styles.CodeCompletion.TextColor).ToCairoColor());
                    var textXPos = xpos + iconWidth + 2;
                    context.MoveTo(textXPos, typos);
                    layout.Width     = (int)((Allocation.Width - textXPos) * Pango.Scale.PangoScale);
                    layout.Ellipsize = EllipsizeMode.End;
                    Pango.CairoHelper.ShowLayout(context, layout);
                    int textW, textH;
                    layout.GetPixelSize(out textW, out textH);
                    layout.Width     = -1;
                    layout.Ellipsize = EllipsizeMode.None;

                    layout.SetMarkup("");
                    if (layout.Attributes != null)
                    {
                        layout.Attributes.Dispose();
                        layout.Attributes = null;
                    }

                    string rightText = "";                    //TODO: David DataProvider.GetRightSideDescription (index, drawIconAsSelected);
                    if (!string.IsNullOrEmpty(rightText))
                    {
                        layout.SetMarkup(rightText);

                        int w, h;
                        layout.GetPixelSize(out w, out h);
                        const int leftpadding  = 8;
                        const int rightpadding = 3;
                        w    += rightpadding;
                        w     = Math.Min(w, Allocation.Width - textXPos - textW - leftpadding);
                        wi   += w;
                        typos = h < rowHeight ? ypos + (rowHeight - h) / 2 : ypos;
                        if (scalef <= 1.0)
                        {
                            typos -= 1;                             // 1px up on non HiDPI
                        }
                        context.MoveTo(Allocation.Width - w, typos);
                        layout.Width     = (int)(w * Pango.Scale.PangoScale);
                        layout.Ellipsize = EllipsizeMode.End;

                        Pango.CairoHelper.ShowLayout(context, layout);
                        layout.Width     = -1;
                        layout.Ellipsize = EllipsizeMode.None;
                    }

                    if (Math.Min(maxListWidth, wi + xpos + iconWidth + 2) > listWidth)
                    {
                        box.WidthRequest = listWidth = Math.Min(maxListWidth, wi + xpos + iconWidth + 2 + iconTextSpacing);
                        needsRefresh     = true;
                    }
                    else
                    {
                        //workaround for the vscrollbar display - the calculated width needs to be the width ofthe render region.
                        if (Allocation.Width < listWidth)
                        {
                            if (listWidth - Allocation.Width < 30)
                            {
                                box.WidthRequest = listWidth + listWidth - Allocation.Width;
                                needsRefresh     = true;
                            }
                        }
                    }

                    return(true);
                });

                if (needsRefresh)
                {
                    QueueSpaceReservationStackRefresh();
                }

                return(false);
            }
        }