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); }
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)))); }
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); }
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); }
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; } }
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) ?? "<null>") : 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); } }
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); }
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); }
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); } }
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); } }