From bef3d44962b3d6ef9b811933940163e936bb6625 Mon Sep 17 00:00:00 2001 From: Curtis Wensley Date: Wed, 5 Feb 2025 10:16:08 -0800 Subject: [PATCH] Mac: Open/SaveFileDialog fixes --- src/Eto.Mac/Forms/MacFileDialog.cs | 115 +++++++----------- src/Eto.Mac/Forms/OpenFileDialogHandler.cs | 2 - src/Eto.Mac/Forms/OpenWithDialogHandler.cs | 11 +- src/Eto.Mac/Forms/SaveFileDialogHandler.cs | 16 ++- .../Sections/Dialogs/FileDialogSection.cs | 27 ++-- 5 files changed, 75 insertions(+), 96 deletions(-) diff --git a/src/Eto.Mac/Forms/MacFileDialog.cs b/src/Eto.Mac/Forms/MacFileDialog.cs index fabe9566f3..4f50aa9a44 100644 --- a/src/Eto.Mac/Forms/MacFileDialog.cs +++ b/src/Eto.Mac/Forms/MacFileDialog.cs @@ -33,56 +33,38 @@ public abstract class MacFileDialog : WidgetHandler macfilters; - readonly NSPopUpButton fileTypes; + readonly DropDown fileTypes; protected MacFileDialog() { - fileTypes = new NSPopUpButton(); + fileTypes = new DropDown(); + fileTypes.SelectedIndexChanged += (sender, e) => OnFileTypeChanged(); } void Create() { - if (Control.AccessoryView != null) - return; - - var fileTypeView = new NSView(); - fileTypeView.AutoresizingMask = NSViewResizingMask.HeightSizable | NSViewResizingMask.WidthSizable; - - const int padding = 15; - if (Widget.Filters.Count > 0) { - var label = new NSTextField(); - label.StringValue = "Format"; - label.DrawsBackground = false; - label.Bordered = false; - label.Bezeled = false; - label.Editable = false; - label.Selectable = false; - label.SizeToFit(); - fileTypeView.AddSubview(label); - - fileTypes.SizeToFit(); - fileTypes.Activated += (sender, e) => - { - SetCurrentItem(); - Control.ValidateVisibleColumns(); - Control.Update(); - }; - fileTypeView.AddSubview(fileTypes); - fileTypes.SetFrameOrigin(new CGPoint((nfloat)label.Frame.Width + 10, padding)); - - label.SetFrameOrigin(new CGPoint(0, (nfloat)(padding + (fileTypes.Frame.Height - label.Frame.Height) / 2))); - - fileTypeView.Frame = new CGRect(0, 0, (nfloat)(fileTypes.Frame.Width + label.Frame.Width + 10), (nfloat)(fileTypes.Frame.Height + padding * 2)); - - Control.AccessoryView = fileTypeView; - SetCurrentItem(); + if (Control.AccessoryView != null) + return; + + var layout = new TableLayout { Padding = 15, Spacing = new Size(2, 2) }; + layout.Rows.Add(new TableRow(null, fileTypes, null)); + + Control.AccessoryView = layout.ToNative(true); + SetAllowedFileTypes(); } else Control.AccessoryView = null; } + protected virtual void OnFileTypeChanged() + { + SetAllowedFileTypes(); + Control.ValidateVisibleColumns(); + Control.Update(); + } + string fileName; public virtual string FileName @@ -93,7 +75,7 @@ public virtual string FileName public Uri Directory { - get => new Uri(Control.DirectoryUrl.AbsoluteString); + get => (Uri)Control.DirectoryUrl; set => Control.DirectoryUrl = new NSUrl(value.AbsoluteUri); } @@ -111,44 +93,38 @@ public string GetDefaultExtension() return null; } - public List MacFilters - { - get { return macfilters; } - } + public List MacFilters => macfilters; - public void SetCurrentItem() + internal void SetAllowedFileTypes() { - macfilters = Widget.CurrentFilter.Extensions?.Select(r => r.TrimStart('*', '.')).ToList(); - - if (macfilters == null || macfilters.Count == 0 || macfilters.Contains("")) + var filters = Widget.CurrentFilter?.Extensions?.Select(r => r.TrimStart('*', '.')).ToList(); + if (filters != null && (filters.Count == 0 || filters.Contains(""))) { - macfilters = null; - // MacOS throws exception when setting to null (ugh) - Messaging.void_objc_msgSend_IntPtr(Control.Handle, Selector.GetHandle("setAllowedFileTypes:"), IntPtr.Zero); + filters = null; } - else - Control.AllowedFileTypes = macfilters.Distinct().ToArray(); + + if (macfilters == filters) + return; + macfilters = filters; + +#if MACOS_NET + Control.AllowedContentTypes = macfilters.Distinct().Select(UniformTypeIdentifiers.UTType.CreateFromExtension).ToArray() + ?? Array.Empty(); +#else + + Control.AllowedFileTypes = macfilters?.Distinct().ToArray(); +#endif } public int CurrentFilterIndex { - get - { - var title = fileTypes.TitleOfSelectedItem; - var item = Widget.Filters.FirstOrDefault(r => r.Name == title); - if (item == null) - return -1; - return Widget.Filters.IndexOf(item); - } - set - { - fileTypes.SelectItem(Widget.Filters[value].Name); - } + get => fileTypes.SelectedIndex; + set => fileTypes.SelectedIndex = value; } public bool CheckFileExists { - get { return false; } + get { return true; } set { } } @@ -172,24 +148,21 @@ public virtual DialogResult ShowDialog(Window parent) return ret == 1 ? DialogResult.Ok : DialogResult.Cancel; } - protected override void Dispose(bool disposing) - { - //base.Dispose (disposing); - } - public void InsertFilter(int index, FileFilter filter) { - fileTypes.InsertItem(filter.Name, index); + fileTypes.Items.Insert(index, new ListItem { Text = filter.Name } ); + if (fileTypes.SelectedIndex == -1) + fileTypes.SelectedIndex = index; } public void RemoveFilter(int index) { - fileTypes.RemoveItem(index); + fileTypes.Items.RemoveAt(index); } public void ClearFilters() { - fileTypes.RemoveAllItems(); + fileTypes.Items.Clear(); } } } diff --git a/src/Eto.Mac/Forms/OpenFileDialogHandler.cs b/src/Eto.Mac/Forms/OpenFileDialogHandler.cs index 413127094c..94288eb33c 100644 --- a/src/Eto.Mac/Forms/OpenFileDialogHandler.cs +++ b/src/Eto.Mac/Forms/OpenFileDialogHandler.cs @@ -8,8 +8,6 @@ protected override NSOpenPanel CreateControl() return NSOpenPanel.OpenPanel; } - protected override bool DisposeControl { get { return false; } } - public bool MultiSelect { get { return Control.AllowsMultipleSelection; } diff --git a/src/Eto.Mac/Forms/OpenWithDialogHandler.cs b/src/Eto.Mac/Forms/OpenWithDialogHandler.cs index ee4619ea45..3f4b0f99c1 100644 --- a/src/Eto.Mac/Forms/OpenWithDialogHandler.cs +++ b/src/Eto.Mac/Forms/OpenWithDialogHandler.cs @@ -6,11 +6,14 @@ public class OpenWithDialogHandler : WidgetHandler