From 60bf34b6cc11853602ef5a3f11cedf55d4a6d9de Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Fri, 17 Apr 2026 19:05:02 +0200 Subject: [PATCH 1/2] [tests] Simplify MonoTouch.Dialog. * Remove code we don't use. * Enable nullability and fix any issues. --- .../MonoTouch.Dialog/DialogViewController.cs | 93 +- tests/common/MonoTouch.Dialog/Elements.cs | 892 ++---------------- .../Elements/ActivityElement.cs | 67 -- .../Elements/MessageElement.cs | 192 ---- .../Elements/OwnerDrawnElement.cs | 117 --- .../OldElements/LoadMoreElement.cs | 162 ---- .../MonoTouch.Dialog/Utilities/Controls.cs | 18 +- .../MonoTouch.Dialog/Utilities/GlassButton.cs | 131 --- .../MonoTouch.Dialog/Utilities/Graphics.cs | 64 -- .../MonoTouch.Dialog/Utilities/LRUCache.cs | 140 --- tests/common/MonoTouch.Dialog/shared.csproj | 2 + 11 files changed, 150 insertions(+), 1728 deletions(-) delete mode 100644 tests/common/MonoTouch.Dialog/Elements/ActivityElement.cs delete mode 100644 tests/common/MonoTouch.Dialog/Elements/MessageElement.cs delete mode 100644 tests/common/MonoTouch.Dialog/Elements/OwnerDrawnElement.cs delete mode 100644 tests/common/MonoTouch.Dialog/OldElements/LoadMoreElement.cs delete mode 100644 tests/common/MonoTouch.Dialog/Utilities/GlassButton.cs delete mode 100644 tests/common/MonoTouch.Dialog/Utilities/Graphics.cs delete mode 100644 tests/common/MonoTouch.Dialog/Utilities/LRUCache.cs diff --git a/tests/common/MonoTouch.Dialog/DialogViewController.cs b/tests/common/MonoTouch.Dialog/DialogViewController.cs index b876ac9bff3a..798e6c9ee3e0 100644 --- a/tests/common/MonoTouch.Dialog/DialogViewController.cs +++ b/tests/common/MonoTouch.Dialog/DialogViewController.cs @@ -21,11 +21,11 @@ namespace MonoTouch.Dialog { /// public class DialogViewController : UITableViewController { public UITableViewStyle Style = UITableViewStyle.Grouped; - public event Action OnSelection; + public event Action? OnSelection; #if !__TVOS__ - UISearchBar searchBar; + UISearchBar? searchBar; #endif - UITableView tableView; + UITableView? tableView; RootElement root; bool pushing; bool dirty; @@ -50,7 +50,7 @@ public RootElement Root { } } - EventHandler refreshRequested; + EventHandler? refreshRequested; /// /// If you assign a handler to this event before the view is shown, the /// DialogViewController will have support for pull-to-refresh UI. @@ -87,7 +87,7 @@ public bool EnableSearch { // the user manually pulls it down. public bool AutoHideSearch { get; set; } - public string SearchPlaceholder { get; set; } + public string? SearchPlaceholder { get; set; } /// /// Invoke this method to trigger a data refresh. @@ -126,7 +126,7 @@ public void ReloadComplete () reloading = false; #if !__TVOS__ - RefreshControl.EndRefreshing (); + RefreshControl?.EndRefreshing (); #endif } @@ -150,8 +150,8 @@ public override void DidRotate (UIInterfaceOrientation fromInterfaceOrientation) } #endif - Section [] originalSections; - Element [] [] originalElements; + Section []? originalSections; + Element [] []? originalElements; /// /// Allows caller to programatically activate the search bar and start the search process @@ -162,7 +162,7 @@ public void StartSearch () return; #if !__TVOS__ - searchBar.BecomeFirstResponder (); + searchBar?.BecomeFirstResponder (); #endif originalSections = Root.Sections.ToArray (); originalElements = new Element [originalSections.Length] []; @@ -182,33 +182,24 @@ public virtual void FinishSearch () originalSections = null; originalElements = null; #if !__TVOS__ - searchBar.ResignFirstResponder (); + searchBar?.ResignFirstResponder (); #endif ReloadData (); } - public delegate void SearchTextEventHandler (object sender, SearchChangedEventArgs args); - public event SearchTextEventHandler SearchTextChanged; - - public virtual void OnSearchTextChanged (string text) - { - if (SearchTextChanged is not null) - SearchTextChanged (this, new SearchChangedEventArgs (text)); - } - public void PerformFilter (string text) { - if (originalSections is null) + var sections = originalSections; + var elementsBySection = originalElements; + if (sections is null || elementsBySection is null) return; - OnSearchTextChanged (text); - var newSections = new List
(); - for (int sidx = 0; sidx < originalSections.Length; sidx++) { - Section newSection = null; - var section = originalSections [sidx]; - Element [] elements = originalElements [sidx]; + for (int sidx = 0; sidx < sections.Length; sidx++) { + Section? newSection = null; + var section = sections [sidx]; + Element [] elements = elementsBySection [sidx]; for (int eidx = 0; eidx < elements.Length; eidx++) { if (elements [eidx].Matches (text)) { @@ -229,10 +220,6 @@ public void PerformFilter (string text) ReloadData (); } - public virtual void SearchButtonClicked (string text) - { - } - class SearchDelegate : UISearchBarDelegate { DialogViewController container; @@ -266,7 +253,8 @@ public override void TextChanged (UISearchBar searchBar, string searchText) public override void CancelButtonClicked (UISearchBar searchBar) { searchBar.ShowsCancelButton = false; - container.searchBar.Text = ""; + if (container.searchBar is not null) + container.searchBar.Text = ""; container.FinishSearch (); searchBar.ResignFirstResponder (); } @@ -274,14 +262,13 @@ public override void CancelButtonClicked (UISearchBar searchBar) public override void SearchButtonClicked (UISearchBar searchBar) { - container.SearchButtonClicked (searchBar.Text); } } public class Source : UITableViewSource { const float yboundary = 65; WeakReference container; - protected DialogViewController Container => container.TryGetTarget (out var result) ? result : null; + protected DialogViewController? Container => container.TryGetTarget (out var result) ? result : null; protected RootElement Root; public Source (DialogViewController container) @@ -311,12 +298,12 @@ public override nint NumberOfSections (UITableView tableView) return Root.Sections.Count; } - public override string TitleForHeader (UITableView tableView, nint section) + public override string? TitleForHeader (UITableView tableView, nint section) { return Root.Sections [(int) section].Caption; } - public override string TitleForFooter (UITableView tableView, nint section) + public override string? TitleForFooter (UITableView tableView, nint section) { return Root.Sections [(int) section].Footer; } @@ -342,21 +329,26 @@ public override void WillDisplay (UITableView tableView, UITableViewCell cell, N public override void RowDeselected (UITableView tableView, NSIndexPath indexPath) { - Container.Deselected (indexPath); + var container = Container; + if (container is not null) + container.Deselected (indexPath); } public override void RowSelected (UITableView tableView, NSIndexPath indexPath) { - var onSelection = Container.OnSelection; + var container = Container; + if (container is null) + return; + var onSelection = container.OnSelection; if (onSelection is not null) onSelection (indexPath); - Container.Selected (indexPath); + container.Selected (indexPath); } public override UIView GetViewForHeader (UITableView tableView, nint sectionIdx) { var section = Root.Sections [(int) sectionIdx]; - return section.HeaderView; + return section.HeaderView!; } public override nfloat GetHeightForHeader (UITableView tableView, nint sectionIdx) @@ -370,7 +362,7 @@ public override nfloat GetHeightForHeader (UITableView tableView, nint sectionId public override UIView GetViewForFooter (UITableView tableView, nint sectionIdx) { var section = Root.Sections [(int) sectionIdx]; - return section.FooterView; + return section.FooterView!; } public override nfloat GetHeightForFooter (UITableView tableView, nint sectionIdx) @@ -466,13 +458,14 @@ void SetupSearch () // Can't create a UISearchBar in tvOS, you can only use one from a UISearchController, // which require bigger changes, so just skip this for now. #else - if (enableSearch) { - searchBar = new UISearchBar (new CGRect (0, 0, tableView.Bounds.Width, 44)) { + var tv = tableView; + if (enableSearch && tv is not null) { + searchBar = new UISearchBar (new CGRect (0, 0, tv.Bounds.Width, 44)) { Delegate = new SearchDelegate (this) }; if (SearchPlaceholder is not null) searchBar.Placeholder = this.SearchPlaceholder; - tableView.TableHeaderView = searchBar; + tv.TableHeaderView = searchBar; } else { // Does not work with current Monotouch, will work with 3.0 // tableView.TableHeaderView = null; @@ -482,6 +475,8 @@ void SetupSearch () public virtual void Deselected (NSIndexPath indexPath) { + if (tableView is null) + return; var section = root.Sections [(int) indexPath.Section]; var element = section.Elements [(int) indexPath.Row]; @@ -490,6 +485,8 @@ public virtual void Deselected (NSIndexPath indexPath) public virtual void Selected (NSIndexPath indexPath) { + if (tableView is null) + return; var section = root.Sections [(int) indexPath.Section]; var element = section.Elements [(int) indexPath.Row]; @@ -531,7 +528,7 @@ void ConfigureTableView () #endif } - public event EventHandler ViewAppearing; + public event EventHandler? ViewAppearing; public override void ViewWillAppear (bool animated) { @@ -553,7 +550,7 @@ public override void ViewWillAppear (bool animated) if (root.Caption is not null) NavigationItem.Title = root.Caption; if (dirty) { - tableView.ReloadData (); + tableView?.ReloadData (); dirty = false; } @@ -579,11 +576,11 @@ public virtual Source CreateSizingSource (bool unevenRows) return unevenRows ? new SizingSource (this) : new Source (this); } - Source TableSource; + Source? TableSource; void UpdateSource () { - if (root is null) + if (root is null || tableView is null) return; TableSource = CreateSizingSource (root.UnevenRows); @@ -606,7 +603,7 @@ public void ReloadData () dirty = false; } - public event EventHandler ViewDisappearing; + public event EventHandler? ViewDisappearing; [Obsolete ("Use the ViewDisappearing event instead")] public event EventHandler ViewDissapearing { diff --git a/tests/common/MonoTouch.Dialog/Elements.cs b/tests/common/MonoTouch.Dialog/Elements.cs index e6dad909b5f3..e7d613660307 100644 --- a/tests/common/MonoTouch.Dialog/Elements.cs +++ b/tests/common/MonoTouch.Dialog/Elements.cs @@ -24,8 +24,6 @@ using Foundation; using CoreAnimation; using ObjCRuntime; -using MonoTouch.Dialog.Utilities; - using NSAction = global::System.Action; namespace MonoTouch.Dialog { @@ -41,12 +39,12 @@ public partial class Element : IDisposable { /// other object this points to a Section and it is null /// for the root RootElement. /// - public Element Parent; + public Element? Parent; /// /// The caption to display for this given element /// - public string Caption; + public string? Caption; /// /// Initializes the element with the given caption. @@ -54,7 +52,7 @@ public partial class Element : IDisposable { /// /// The caption. /// - public Element (string caption) + public Element (string? caption) { this.Caption = caption; } @@ -152,7 +150,7 @@ public virtual void Selected (DialogViewController dvc, UITableView tableView, N /// /// If the cell is attached will return the immediate RootElement /// - public RootElement GetImmediateRootElement () + public RootElement? GetImmediateRootElement () { var section = Parent as Section; if (section is null) @@ -165,7 +163,7 @@ public RootElement GetImmediateRootElement () /// /// Returns the UITableView associated with this element, or null if this cell is not currently attached to a UITableView /// - public UITableView GetContainerTableView () + public UITableView? GetContainerTableView () { var root = GetImmediateRootElement (); if (root is null) @@ -176,7 +174,7 @@ public UITableView GetContainerTableView () /// /// Returns the currently active UITableViewCell for this element, or null if the element is not currently visible /// - public UITableViewCell GetActiveCell () + public UITableViewCell? GetActiveCell () { var tv = GetContainerTableView (); if (tv is null) @@ -192,7 +190,7 @@ public UITableViewCell GetActiveCell () /// it does not work for a toplevel RootElement or a Section of if the Element has /// not been attached yet. /// - public NSIndexPath IndexPath { + public NSIndexPath? IndexPath { get { var section = Parent as Section; if (section is null) @@ -242,7 +240,7 @@ public virtual bool Value { ValueChanged (this, EventArgs.Empty); } } - public event EventHandler ValueChanged; + public event EventHandler? ValueChanged; public BoolElement (string caption, bool value) : base (caption) { @@ -261,7 +259,7 @@ public override string Summary () public partial class BooleanElement : BoolElement { static NSString bkey = new NSString ("BooleanElement"); #if !__TVOS__ - UISwitch sw; + UISwitch? sw; #endif // !__TVOS__ public BooleanElement (string caption, bool value) : base (caption, value) @@ -318,7 +316,8 @@ public override void Selected (DialogViewController dvc, UITableView tableView, { Value = !Value; var cell = tableView.CellAt (path); - ConfigCell (cell); + if (cell is not null) + ConfigCell (cell); base.Selected (dvc, tableView, path); } #endif // !__TVOS__ @@ -351,234 +350,15 @@ public override bool Value { } } - /// - /// This class is used to render a string + a state in the form - /// of an image. - /// - /// - /// It is abstract to avoid making this element - /// keep two pointers for the state images, saving 8 bytes per - /// slot. The more derived class "BooleanImageElement" shows - /// one way to implement this by keeping two pointers, a better - /// implementation would return pointers to images that were - /// preloaded and are static. - /// - /// A subclass only needs to implement the GetImage method. - /// - public abstract partial class BaseBooleanImageElement : BoolElement { - static NSString key = new NSString ("BooleanImageElement"); - - public class TextWithImageCellView : UITableViewCell { - const int fontSize = 17; - static UIFont font = UIFont.BoldSystemFontOfSize (fontSize); - BaseBooleanImageElement parent; - UILabel label; - UIButton button; - const int ImageSpace = 32; - const int Padding = 8; - - public TextWithImageCellView (BaseBooleanImageElement parent_) : base (UITableViewCellStyle.Value1, parent_.CellKey) - { - parent = parent_; - label = new UILabel () { - TextAlignment = UITextAlignment.Left, - Text = parent.Caption, - Font = font, - BackgroundColor = UIColor.Clear - }; - button = UIButton.FromType (UIButtonType.Custom); - button.TouchDown += delegate - { - parent.Value = !parent.Value; - UpdateImage (); - if (parent.Tapped is not null) - parent.Tapped (); - }; - ContentView.Add (label); - ContentView.Add (button); - UpdateImage (); - } - - void UpdateImage () - { - button.SetImage (parent.GetImage (), UIControlState.Normal); - } - - public override void LayoutSubviews () - { - base.LayoutSubviews (); - var full = ContentView.Bounds; - var frame = full; - frame.Height = 22; - frame.X = Padding; - frame.Y = (full.Height - frame.Height) / 2; - frame.Width -= ImageSpace + Padding; - label.Frame = frame; - - button.Frame = new CGRect (full.Width - ImageSpace, -3, ImageSpace, 48); - } - - public void UpdateFrom (BaseBooleanImageElement newParent) - { - parent = newParent; - UpdateImage (); - label.Text = parent.Caption; - SetNeedsDisplay (); - } - } - - public BaseBooleanImageElement (string caption, bool value) - : base (caption, value) - { - } - - public event NSAction Tapped; - - protected abstract UIImage GetImage (); - - protected override NSString CellKey { - get { - return key; - } - } - public override UITableViewCell GetCell (UITableView tv) - { - var cell = tv.DequeueReusableCell (CellKey) as TextWithImageCellView; - if (cell is null) - cell = new TextWithImageCellView (this); - else - cell.UpdateFrom (this); - return cell; - } - } - - public partial class BooleanImageElement : BaseBooleanImageElement { - UIImage onImage, offImage; - - public BooleanImageElement (string caption, bool value, UIImage onImage, UIImage offImage) : base (caption, value) - { - this.onImage = onImage; - this.offImage = offImage; - } - - protected override UIImage GetImage () - { - if (Value) - return onImage; - else - return offImage; - } - - protected override void Dispose (bool disposing) - { - base.Dispose (disposing); - onImage = offImage = null; - } - } - - /// - /// Used to display a slider on the screen. - /// - public partial class FloatElement : Element { - public bool ShowCaption; - public float Value; - public float MinValue, MaxValue; - static NSString skey = new NSString ("FloatElement"); - //UIImage Left, Right; -#if !__TVOS__ - // There is no UISlider in tvOS, so make this read-only for now. - UISlider slider; -#endif // !__TVOS__ - - public FloatElement (float value) : this (null, null, value) - { - } - - public FloatElement (UIImage left, UIImage right, float value) : base (null) - { - //Left = left; - //Right = right; - MinValue = 0; - MaxValue = 1; - Value = value; - } - - protected override NSString CellKey { - get { - return skey; - } - } - public override UITableViewCell GetCell (UITableView tv) - { - var cell = tv.DequeueReusableCell (CellKey); - if (cell is null) { - cell = new UITableViewCell (UITableViewCellStyle.Default, CellKey); - cell.SelectionStyle = UITableViewCellSelectionStyle.None; - } else - RemoveTag (cell, 1); - -#if __TVOS__ - if (Caption is not null && ShowCaption) - cell.TextLabel.Text = Caption; - - cell.DetailTextLabel.Text = string.Format ("[{0}...{2}]: {1}]", MinValue, Value, MaxValue); -#else - CGSize captionSize = new CGSize (0, 0); - if (Caption is not null && ShowCaption) { - cell.TextLabel.Text = Caption; - captionSize = Caption.StringSize (UIFont.FromName (cell.TextLabel.Font.Name, UIFont.LabelFontSize)); - captionSize.Width += 10; // Spacing - } - if (slider is null) { - slider = new UISlider (new CGRect (10f + captionSize.Width, UIDevice.CurrentDevice.CheckSystemVersion (7, 0) ? 18f : 12f, cell.ContentView.Bounds.Width - 20 - captionSize.Width, 7f)) { - BackgroundColor = UIColor.Clear, - MinValue = this.MinValue, - MaxValue = this.MaxValue, - Continuous = true, - Value = this.Value, - Tag = 1, - AutoresizingMask = UIViewAutoresizing.FlexibleWidth - }; - slider.ValueChanged += delegate - { - Value = slider.Value; - }; - } else { - slider.Value = Value; - } - - cell.ContentView.AddSubview (slider); -#endif // __TVOS__ - return cell; - } - - public override string Summary () - { - return Value.ToString (); - } - - protected override void Dispose (bool disposing) - { - if (disposing) { -#if !__TVOS__ - if (slider is not null) { - slider.Dispose (); - slider = null; - } -#endif // !__TVOS__ - } - } - } - /// /// Used to display a cell that will launch a web browser when selected. /// public partial class HtmlElement : Element { - NSUrl nsUrl; + NSUrl? nsUrl; static NSString hkey = new NSString ("HtmlElement"); #if !__TVOS__ && !__MACCATALYST__ // There is no UIWebView in tvOS, so we can't launch anything. - UIWebView web; + UIWebView? web; #endif // !__TVOS__ && !__MACCATALYST__ public HtmlElement (string caption, string url) : base (caption) @@ -598,7 +378,7 @@ protected override NSString CellKey { } public string Url { get { - return nsUrl.ToString (); + return nsUrl?.ToString () ?? ""; } set { nsUrl = new NSUrl (value); @@ -690,11 +470,15 @@ public override void Selected (DialogViewController dvc, UITableView tableView, }; vc.NavigationItem.Title = Caption; - vc.View.AutosizesSubviews = true; - vc.View.AddSubview (web); + var view = vc.View; + if (view is not null) { + view.AutosizesSubviews = true; + view.AddSubview (web); + } dvc.ActivateController (vc); - web.LoadRequest (NSUrlRequest.FromUrl (nsUrl)); + if (nsUrl is not null) + web.LoadRequest (NSUrlRequest.FromUrl (nsUrl)); } #endif // !__TVOS__ && !__MACCATALYST__ } @@ -707,21 +491,21 @@ public partial class StringElement : Element { static NSString skey = new NSString ("StringElement"); static NSString skeyvalue = new NSString ("StringElementValue"); public UITextAlignment Alignment = UITextAlignment.Left; - public string Value; + public string? Value; - public StringElement (string caption) : base (caption) { } + public StringElement (string? caption) : base (caption) { } - public StringElement (string caption, string value) : base (caption) + public StringElement (string? caption, string? value) : base (caption) { this.Value = value; } - public StringElement (string caption, NSAction tapped) : base (caption) + public StringElement (string? caption, NSAction tapped) : base (caption) { Tapped += tapped; } - public event NSAction Tapped; + public event NSAction? Tapped; public override UITableViewCell GetCell (UITableView tv) { @@ -744,7 +528,7 @@ public override UITableViewCell GetCell (UITableView tv) public override string Summary () { - return Caption; + return Caption ?? ""; } public override void Selected (DialogViewController dvc, UITableView tableView, NSIndexPath indexPath) @@ -780,20 +564,20 @@ public StyledStringElement (string caption, string value, UITableViewCellStyle s } protected UITableViewCellStyle style; - public event NSAction AccessoryTapped; - public UIFont Font; - public UIFont SubtitleFont; - public UIColor TextColor; + public event NSAction? AccessoryTapped; + public UIFont? Font; + public UIFont? SubtitleFont; + public UIColor? TextColor; public UILineBreakMode LineBreakMode = UILineBreakMode.WordWrap; public int Lines = 0; public UITableViewCellAccessory Accessory = UITableViewCellAccessory.None; // To keep the size down for a StyleStringElement, we put all the image information // on a separate structure, and create this on demand. - ExtraInfo extraInfo; + ExtraInfo? extraInfo; class ExtraInfo { - public UIColor BackgroundColor, DetailColor; + public UIColor? BackgroundColor, DetailColor; } ExtraInfo OnImageInfo () @@ -803,7 +587,7 @@ ExtraInfo OnImageInfo () return extraInfo; } - public UIColor BackgroundColor { + public UIColor? BackgroundColor { get { return extraInfo is null ? null : extraInfo.BackgroundColor; } @@ -812,7 +596,7 @@ public UIColor BackgroundColor { } } - public UIColor DetailColor { + public UIColor? DetailColor { get { return extraInfo is null ? null : extraInfo.DetailColor; } @@ -890,7 +674,7 @@ void IColorizeBackground.WillDisplay (UITableView tableView, UITableViewCell cel internal void AccessoryTap () { - NSAction tapped = AccessoryTapped; + var tapped = AccessoryTapped; if (tapped is not null) tapped (); } @@ -983,8 +767,8 @@ public virtual nfloat GetHeight (UITableView tableView, NSIndexPath indexPath) if (this.Accessory != UITableViewCellAccessory.None) maxSize.Width -= 20; - string c = Caption; - string v = Value; + string? c = Caption; + string? v = Value; // ensure the (multi-line) Value will be rendered inside the cell when no Caption is present if (String.IsNullOrEmpty (c)) c = " "; @@ -1053,98 +837,14 @@ public virtual nfloat GetHeight (UITableView tableView, NSIndexPath indexPath) float margin = UIDevice.CurrentDevice.UserInterfaceIdiom == UIUserInterfaceIdiom.Phone ? 40f : 110f; CGSize size = new CGSize (tableView.Bounds.Width - margin, float.MaxValue); UIFont font = UIFont.BoldSystemFontOfSize (17); - string c = Caption; + string? c = Caption; // ensure the (single-line) Value will be rendered inside the cell if (String.IsNullOrEmpty (c) && !String.IsNullOrEmpty (Value)) c = " "; - return c.StringSize (font, size, UILineBreakMode.WordWrap).Height + 10; - } - } - - public partial class RadioElement : StringElement { - public string Group; - internal int RadioIdx; - - public RadioElement (string caption, string group) : base (caption) - { - Group = group; - } - - public RadioElement (string caption) : base (caption) - { - } - - public override UITableViewCell GetCell (UITableView tv) - { - var cell = base.GetCell (tv); - var root = (RootElement) Parent.Parent; - - if (!(root.group is RadioGroup)) - throw new Exception ("The RootElement's Group is null or is not a RadioGroup"); - - bool selected = RadioIdx == ((RadioGroup) (root.group)).Selected; - cell.Accessory = selected ? UITableViewCellAccessory.Checkmark : UITableViewCellAccessory.None; - - return cell; - } - - public override void Selected (DialogViewController dvc, UITableView tableView, NSIndexPath indexPath) - { - RootElement root = (RootElement) Parent.Parent; - if (RadioIdx != root.RadioSelected) { - UITableViewCell cell; - var selectedIndex = root.PathForRadio (root.RadioSelected); - if (selectedIndex is not null) { - cell = tableView.CellAt (selectedIndex); - if (cell is not null) - cell.Accessory = UITableViewCellAccessory.None; - } - cell = tableView.CellAt (indexPath); - if (cell is not null) - cell.Accessory = UITableViewCellAccessory.Checkmark; - root.RadioSelected = RadioIdx; - } - - base.Selected (dvc, tableView, indexPath); + return (c ?? "").StringSize (font, size, UILineBreakMode.WordWrap).Height + 10; } } - public partial class CheckboxElement : StringElement { - public new bool Value; - public string Group; - - public CheckboxElement (string caption) : base (caption) { } - public CheckboxElement (string caption, bool value) : base (caption) - { - Value = value; - } - - public CheckboxElement (string caption, bool value, string group) : this (caption, value) - { - Group = group; - } - - UITableViewCell ConfigCell (UITableViewCell cell) - { - cell.Accessory = Value ? UITableViewCellAccessory.Checkmark : UITableViewCellAccessory.None; - return cell; - } - - public override UITableViewCell GetCell (UITableView tv) - { - return ConfigCell (base.GetCell (tv)); - } - - public override void Selected (DialogViewController dvc, UITableView tableView, NSIndexPath path) - { - Value = !Value; - var cell = tableView.CellAt (path); - ConfigCell (cell); - base.Selected (dvc, tableView, path); - } - - } - /// /// An element that can be used to enter text. /// @@ -1157,7 +857,7 @@ public partial class EntryElement : Element { /// /// The value of the EntryElement /// - public string Value { + public string? Value { get { if (entry is null) return val; @@ -1176,7 +876,7 @@ public string Value { entry.Text = value; } } - protected string val; + protected string? val; /// /// The key used for reusable UITableViewCells. @@ -1291,14 +991,14 @@ public UITextAlignment TextAlignment { UITextAutocorrectionType autocorrectionType = UITextAutocorrectionType.Default; UITextFieldViewMode clearButtonMode = UITextFieldViewMode.Never; bool isPassword, becomeResponder; - UITextField entry; - string placeholder; + UITextField? entry; + string? placeholder; static UIFont font = UIFont.BoldSystemFontOfSize (17); - public event EventHandler Changed; - public event Func ShouldReturn; - public EventHandler EntryStarted { get; set; } - public EventHandler EntryEnded { get; set; } + public event EventHandler? Changed; + public event Func? ShouldReturn; + public EventHandler? EntryStarted { get; set; } + public EventHandler? EntryEnded { get; set; } /// /// Constructs an EntryElement with the given caption, placeholder and initial value. /// @@ -1311,7 +1011,7 @@ public UITextAlignment TextAlignment { /// /// Initial value. /// - public EntryElement (string caption, string placeholder, string value) : base (caption) + public EntryElement (string caption, string? placeholder, string? value) : base (caption) { Value = value; this.placeholder = placeholder; @@ -1332,7 +1032,7 @@ public EntryElement (string caption, string placeholder, string value) : base (c /// /// True if this should be used to enter a password. /// - public EntryElement (string caption, string placeholder, string value, bool isPassword) : base (caption) + public EntryElement (string caption, string? placeholder, string? value, bool isPassword) : base (caption) { Value = value; this.isPassword = isPassword; @@ -1341,7 +1041,7 @@ public EntryElement (string caption, string placeholder, string value, bool isPa public override string Summary () { - return Value; + return Value ?? ""; } // @@ -1353,7 +1053,15 @@ CGSize ComputeEntryPosition (UITableView tv, UITableViewCell cell) nfloat maxHeight = font.LineHeight; // Determine if we should calculate accross all sections or just the current section. - var sections = AlignEntryWithAllSections ? (Parent.Parent as RootElement).Sections : (new [] { Parent as Section }).AsEnumerable (); + IEnumerable
sections; + if (AlignEntryWithAllSections) { + var root = Parent?.Parent as RootElement; + sections = root is not null ? root.Sections : Enumerable.Empty
(); + } else if (Parent is Section section) { + sections = new [] { section }; + } else { + sections = Enumerable.Empty
(); + } foreach (Section s in sections) { @@ -1397,7 +1105,7 @@ protected override NSString CellKey { } } - UITableViewCell cell; + UITableViewCell? cell; public override UITableViewCell GetCell (UITableView tv) { if (cell is null) { @@ -1439,7 +1147,7 @@ public override UITableViewCell GetCell (UITableView tv) { FetchValue (); if (EntryEnded is not null) { - EntryEnded (this, null); + EntryEnded (this, EventArgs.Empty); } }; entry.ShouldReturn += delegate @@ -1448,8 +1156,8 @@ public override UITableViewCell GetCell (UITableView tv) if (ShouldReturn is not null) return ShouldReturn (); - RootElement root = GetImmediateRootElement (); - EntryElement focus = null; + RootElement? root = GetImmediateRootElement (); + EntryElement? focus = null; if (root is null) return true; @@ -1469,34 +1177,37 @@ public override UITableViewCell GetCell (UITableView tv) } if (focus != this) - focus.BecomeFirstResponder (true); + focus?.BecomeFirstResponder (true); else - focus.ResignFirstResponder (true); + focus?.ResignFirstResponder (true); return true; }; entry.Started += delegate { - EntryElement self = null; + EntryElement? self = null; if (EntryStarted is not null) { - EntryStarted (this, null); + EntryStarted (this, EventArgs.Empty); } - if (!returnKeyType.HasValue) { + if (!returnKeyType.HasValue && Parent is Section parentSection) { var returnType = UIReturnKeyType.Default; - foreach (var e in (Parent as Section).Elements) { + foreach (var e in parentSection.Elements) { if (e == this) self = this; else if (self is not null && e is EntryElement) returnType = UIReturnKeyType.Next; } entry.ReturnKeyType = returnType; - } else + } else if (returnKeyType.HasValue) { entry.ReturnKeyType = returnKeyType.Value; + } - tv.ScrollToRow (IndexPath, UITableViewScrollPosition.Middle, true); + var path = IndexPath; + if (path is not null) + tv.ScrollToRow (path, UITableViewScrollPosition.Middle, true); }; cell.ContentView.AddSubview (entry); } @@ -1565,7 +1276,9 @@ public virtual void BecomeFirstResponder (bool animated) var tv = GetContainerTableView (); if (tv is null) return; - tv.ScrollToRow (IndexPath, UITableViewScrollPosition.Middle, animated); + var path = IndexPath; + if (path is not null) + tv.ScrollToRow (path, UITableViewScrollPosition.Middle, animated); if (entry is not null) { entry.BecomeFirstResponder (); becomeResponder = false; @@ -1578,310 +1291,14 @@ public virtual void ResignFirstResponder (bool animated) var tv = GetContainerTableView (); if (tv is null) return; - tv.ScrollToRow (IndexPath, UITableViewScrollPosition.Middle, animated); + var path = IndexPath; + if (path is not null) + tv.ScrollToRow (path, UITableViewScrollPosition.Middle, animated); if (entry is not null) entry.ResignFirstResponder (); } } - public partial class DateTimeElement : StringElement { - public DateTime DateValue; - // There's no UIDatePicker for tvOS, so this is a read-only element for now -#if !__TVOS__ - public UIDatePicker datePicker; -#endif - public int MinuteInterval = 1; -#pragma warning disable 67 // The event 'X' is never used - public event Action DateSelected; -#pragma warning restore 67 - public UIColor BackgroundColor = (UIDevice.CurrentDevice.CheckSystemVersion (7, 0)) ? UIColor.White : UIColor.Black; - - protected internal NSDateFormatter fmt = new NSDateFormatter () { - DateStyle = NSDateFormatterStyle.Short - }; - - public DateTimeElement (string caption, DateTime date) : base (caption) - { - DateValue = date; - Value = FormatDate (date); - } - - public override UITableViewCell GetCell (UITableView tv) - { - Value = FormatDate (DateValue); - var cell = base.GetCell (tv); - cell.Accessory = UITableViewCellAccessory.DisclosureIndicator; - cell.SelectionStyle = UITableViewCellSelectionStyle.Blue; - return cell; - } - - protected override void Dispose (bool disposing) - { - base.Dispose (disposing); - if (disposing) { - if (fmt is not null) { - fmt.Dispose (); - fmt = null; - } -#if !__TVOS__ - if (datePicker is not null) { - datePicker.Dispose (); - datePicker = null; - } -#endif // !__TVOS__ - } - } - - protected DateTime GetDateWithKind (DateTime dt) - { - if (dt.Kind == DateTimeKind.Unspecified) - return DateTime.SpecifyKind (dt, DateTimeKind.Local); - - return dt; - } - - public virtual string FormatDate (DateTime dt) - { - dt = GetDateWithKind (dt); - return fmt.ToString ((NSDate) dt) + " " + dt.ToLocalTime ().ToShortTimeString (); - } - -#if !__TVOS__ - public virtual UIDatePicker CreatePicker () - { - var picker = new UIDatePicker (CGRect.Empty) { - AutoresizingMask = UIViewAutoresizing.FlexibleMargins, - Mode = UIDatePickerMode.DateAndTime, - Date = (NSDate) GetDateWithKind (DateValue), - MinuteInterval = MinuteInterval - }; - return picker; - } - - class MyViewController : UIViewController { - DateTimeElement container; - - public MyViewController (DateTimeElement container) - { - this.container = container; - } - - public override void ViewWillDisappear (bool animated) - { - base.ViewWillDisappear (animated); - container.DateValue = (DateTime) container.datePicker.Date; - if (container.DateSelected is not null) - container.DateSelected (container); - } - - public override void DidRotate (UIInterfaceOrientation fromInterfaceOrientation) - { - base.DidRotate (fromInterfaceOrientation); - container.datePicker.Center = this.View.Center; - } - - public bool Autorotate { get; set; } - - public override bool ShouldAutorotateToInterfaceOrientation (UIInterfaceOrientation toInterfaceOrientation) - { - return Autorotate; - } - } - - public override void Selected (DialogViewController dvc, UITableView tableView, NSIndexPath path) - { - var vc = new MyViewController (this) { - Autorotate = dvc.Autorotate - }; - datePicker = CreatePicker (); - - vc.View.BackgroundColor = BackgroundColor; - vc.View.AddSubview (datePicker); - dvc.ActivateController (vc); - - datePicker.Center = vc.View.Center; - } -#endif // !__TVOS__ - } - - public partial class DateElement : DateTimeElement { - public DateElement (string caption, DateTime date) : base (caption, date) - { - fmt.DateStyle = NSDateFormatterStyle.Medium; - } - - public override string FormatDate (DateTime dt) - { - return fmt.ToString ((NSDate) GetDateWithKind (dt)); - } - -#if !__TVOS__ - public override UIDatePicker CreatePicker () - { - var picker = base.CreatePicker (); - picker.Mode = UIDatePickerMode.Date; - return picker; - } -#endif // !__TVOS__ - } - - public partial class TimeElement : DateTimeElement { - public TimeElement (string caption, DateTime date) : base (caption, date) - { - } - - public override string FormatDate (DateTime dt) - { - return GetDateWithKind (dt).ToLocalTime ().ToShortTimeString (); - } - -#if !__TVOS__ - public override UIDatePicker CreatePicker () - { - var picker = base.CreatePicker (); - picker.Mode = UIDatePickerMode.Time; - picker.MinuteInterval = MinuteInterval; - return picker; - } -#endif // !__TVOS__ - } - - /// - /// This element can be used to insert an arbitrary UIView - /// - /// - /// There is no cell reuse here as we have a 1:1 mapping - /// in this case from the UIViewElement to the cell that - /// holds our view. - /// - public partial class UIViewElement : Element, IElementSizing { - static int count; - public UIView ContainerView; - NSString key; - protected UIView View; - public CellFlags Flags; - UIEdgeInsets insets; - - public UIEdgeInsets Insets { - get { - return insets; - } - set { - var viewFrame = View.Frame; - var dx = value.Left - insets.Left; - var dy = value.Top - insets.Top; - var ow = insets.Left + insets.Right; - var oh = insets.Top + insets.Bottom; - var w = value.Left + value.Right; - var h = value.Top + value.Bottom; - - ContainerView.Frame = new CGRect (0, 0, ContainerView.Frame.Width + w - ow, ContainerView.Frame.Height + h - oh); - viewFrame.X += dx; - viewFrame.Y += dy; - View.Frame = viewFrame; - - insets = value; - - // Height changed, notify UITableView - if (dy != 0 || h != oh) - GetContainerTableView ().ReloadData (); - - } - } - - [Flags] - public enum CellFlags { - Transparent = 1, - DisableSelection = 2 - } - - - /// - /// Constructor - /// - /// - /// The caption, only used for RootElements that might want to summarize results - /// - /// - /// The view to display - /// - /// - /// If this is set, then the view is responsible for painting the entire area, - /// otherwise the default cell paint code will be used. - /// - public UIViewElement (string caption, UIView view, bool transparent, UIEdgeInsets insets) : base (caption) - { - this.insets = insets; - var oframe = view.Frame; - var frame = oframe; - frame.Width += insets.Left + insets.Right; - frame.Height += insets.Top + insets.Bottom; - - ContainerView = new UIView (frame); - if ((Flags & CellFlags.Transparent) != 0) - ContainerView.BackgroundColor = UIColor.Clear; - - if (insets.Left != 0 || insets.Top != 0) - view.Frame = new CGRect (insets.Left + frame.X, insets.Top + frame.Y, frame.Width, frame.Height); - - ContainerView.AddSubview (view); - this.View = view; - this.Flags = transparent ? CellFlags.Transparent : 0; - key = new NSString ("UIViewElement" + count++); - } - - public UIViewElement (string caption, UIView view, bool transparent) : this (caption, view, transparent, UIEdgeInsets.Zero) - { - } - - protected override NSString CellKey { - get { - return key; - } - } - public override UITableViewCell GetCell (UITableView tv) - { - var cell = tv.DequeueReusableCell (CellKey); - if (cell is null) { - cell = new UITableViewCell (UITableViewCellStyle.Default, CellKey); - if ((Flags & CellFlags.Transparent) != 0) { - cell.BackgroundColor = UIColor.Clear; - - // - // This trick is necessary to keep the background clear, otherwise - // it gets painted as black - // - cell.BackgroundView = new UIView (CGRect.Empty) { - BackgroundColor = UIColor.Clear - }; - } - if ((Flags & CellFlags.DisableSelection) != 0) - cell.SelectionStyle = UITableViewCellSelectionStyle.None; - - if (Caption is not null) - cell.TextLabel.Text = Caption; - cell.ContentView.AddSubview (ContainerView); - } - return cell; - } - - public nfloat GetHeight (UITableView tableView, NSIndexPath indexPath) - { - return ContainerView.Bounds.Height + 1; - } - - protected override void Dispose (bool disposing) - { - base.Dispose (disposing); - if (disposing) { - if (View is not null) { - View.Dispose (); - View = null; - } - } - } - } - /// /// Sections contain individual Element instances that are rendered by MonoTouch.Dialog /// @@ -1898,7 +1315,7 @@ protected override void Dispose (bool disposing) /// this uses the same storage, so you can only show one or the other. /// public class Section : Element, IEnumerable { - object header, footer; + object? header, footer; public List Elements = new List (); // X corresponds to the alignment, Y to the height of the password @@ -1915,7 +1332,7 @@ public Section () : base (null) { } /// /// The header to display /// - public Section (string caption) : base (caption) + public Section (string? caption) : base (caption) { } @@ -1928,7 +1345,7 @@ public Section (string caption) : base (caption) /// /// The footer to display. /// - public Section (string caption, string footer) : base (caption) + public Section (string? caption, string? footer) : base (caption) { Footer = footer; } @@ -1947,7 +1364,7 @@ public Section (UIView header, UIView footer) : base (null) /// /// The section header, as a string /// - public string Header { + public string? Header { get { return header as string; } @@ -1959,7 +1376,7 @@ public string Header { /// /// The section footer, as a string. /// - public string Footer { + public string? Footer { get { return footer as string; } @@ -1972,7 +1389,7 @@ public string Footer { /// /// The section's header view. /// - public UIView HeaderView { + public UIView? HeaderView { get { return header as UIView; } @@ -1984,7 +1401,7 @@ public UIView HeaderView { /// /// The section's footer view. /// - public UIView FooterView { + public UIView? FooterView { get { return footer as UIView; } @@ -2048,29 +1465,6 @@ public int Add (IEnumerable elements) return AddAll (elements); } - /// - /// Use to add a UIView to a section, it makes the section opaque, to - /// get a transparent one, you must manually call UIViewElement - public void Add (UIView view) - { - if (view is null) - return; - Add (new UIViewElement (null, view, false)); - } - - /// - /// Adds the UIViews to the section. - /// - /// - /// An enumarable list that can be produced by something like: - /// from x in ... select (UIView) new UIFoo (); - /// - public void Add (IEnumerable views) - { - foreach (var v in views) - Add (v); - } - /// /// Inserts a series of elements into the Section using the specified animation /// @@ -2094,7 +1488,7 @@ public void Insert (int idx, UITableViewRowAnimation anim, params Element [] new e.Parent = this; } var root = Parent as RootElement; - if (Parent is not null && root.TableView is not null) { + if (root is not null && root.TableView is not null) { if (anim == UITableViewRowAnimation.None) root.TableView.ReloadData (); else @@ -2271,7 +1665,6 @@ protected override void Dispose (bool disposing) if (disposing) { Parent = null; Clear (); - Elements = null; } base.Dispose (disposing); } @@ -2290,32 +1683,12 @@ public override UITableViewCell GetCell (UITableView tv) /// render a summary (Checkbox count or selected radio group). /// public class Group { - public string Key; - public Group (string key) + public string? Key; + public Group (string? key) { Key = key; } } - /// - /// Captures the information about mutually exclusive elements in a RootElement - /// - public class RadioGroup : Group { - int selected; - public virtual int Selected { - get { return selected; } - set { selected = value; } - } - - public RadioGroup (string key, int selected) : base (key) - { - this.selected = selected; - } - - public RadioGroup (int selected) : base (null) - { - this.selected = selected; - } - } /// /// RootElements are responsible for showing a full configuration page. @@ -2346,10 +1719,10 @@ public partial class RootElement : Element, IEnumerable, IEnumerable
{ static NSString rkey1 = new NSString ("RootElement1"); static NSString rkey2 = new NSString ("RootElement2"); int summarySection, summaryElement; - internal Group group; + internal Group? group; public bool UnevenRows; - public Func createOnSelected; - public UITableView TableView; + public Func? createOnSelected; + public UITableView? TableView; // This is used to indicate that we need the DVC to dispatch calls to // WillDisplayCell so we can prepare the color of the cell before @@ -2418,31 +1791,6 @@ public RootElement (string caption, Group group) : base (caption) internal List
Sections = new List
(); - internal NSIndexPath PathForRadio (int idx) - { - RadioGroup radio = group as RadioGroup; - if (radio is null) - return null; - - uint current = 0, section = 0; - foreach (Section s in Sections) { - uint row = 0; - - foreach (Element e in s.Elements) { - if (!(e is RadioElement)) - continue; - - if (current == idx) { - return NSIndexPath.Create (section, row); - } - row++; - current++; - } - section++; - } - return null; - } - public int Count { get { return Sections.Count; @@ -2468,12 +1816,8 @@ internal int IndexOf (Section target) public void Prepare () { - int current = 0; foreach (Section s in Sections) { foreach (Element e in s.Elements) { - var re = e as RadioElement; - if (re is not null) - re.RadioIdx = current++; if (UnevenRows == false && e is IElementSizing) UnevenRows = true; if (NeedColorUpdate == false && e is IColorizeBackground) @@ -2646,7 +1990,6 @@ protected override void Dispose (bool disposing) TableView = null; Clear (); - Sections = null; } } @@ -2668,23 +2011,6 @@ IEnumerator
IEnumerable
.GetEnumerator () yield return s; } - /// - /// The currently selected Radio item in the whole Root. - /// - public int RadioSelected { - get { - var radio = group as RadioGroup; - if (radio is not null) - return radio.Selected; - return -1; - } - set { - var radio = group as RadioGroup; - if (radio is not null) - radio.Selected = value; - } - } - public override UITableViewCell GetCell (UITableView tv) { NSString key = summarySection == -1 ? rkey1 : rkey2; @@ -2697,34 +2023,11 @@ public override UITableViewCell GetCell (UITableView tv) } cell.TextLabel.Text = Caption; - var radio = group as RadioGroup; - if (radio is not null) { - int selected = radio.Selected; - int current = 0; - - foreach (var s in Sections) { - foreach (var e in s.Elements) { - if (!(e is RadioElement)) - continue; - - if (current == selected) { - cell.DetailTextLabel.Text = e.Summary (); - goto le; - } - current++; - } - } - } else if (group is not null) { + if (group is not null) { int count = 0; foreach (var s in Sections) { foreach (var e in s.Elements) { - var ce = e as CheckboxElement; - if (ce is not null) { - if (ce.Value) - count++; - continue; - } var be = e as BoolElement; if (be is not null) { if (be.Value) @@ -2739,7 +2042,6 @@ public override UITableViewCell GetCell (UITableView tv) if (summaryElement < s.Elements.Count && cell.DetailTextLabel is not null) cell.DetailTextLabel.Text = s.Elements [summaryElement].Summary (); } - le: cell.Accessory = UITableViewCellAccessory.DisclosureIndicator; return cell; @@ -2784,6 +2086,8 @@ public void Reload (Section section, UITableViewRowAnimation animation) int idx = 0; foreach (var sect in Sections) { if (sect == section) { + if (TableView is null) + return; TableView.ReloadSections (new NSIndexSet ((uint) idx), animation); return; } @@ -2802,7 +2106,7 @@ public void Reload (Element element, UITableViewRowAnimation animation) if (root is null) throw new ArgumentException ("Element is not attached to this root"); var path = element.IndexPath; - if (path is null) + if (path is null || TableView is null) return; TableView.ReloadRows (new NSIndexPath [] { path }, animation); } diff --git a/tests/common/MonoTouch.Dialog/Elements/ActivityElement.cs b/tests/common/MonoTouch.Dialog/Elements/ActivityElement.cs deleted file mode 100644 index f9cfd0133a16..000000000000 --- a/tests/common/MonoTouch.Dialog/Elements/ActivityElement.cs +++ /dev/null @@ -1,67 +0,0 @@ -using System; -using System.Drawing; - -using UIKit; -using CoreGraphics; -using Foundation; - -namespace MonoTouch.Dialog { - public class ActivityElement : Element { - public ActivityElement () : base ("") - { - } - - UIActivityIndicatorView indicator; - - public bool Animating { - get { - return indicator.IsAnimating; - } - set { - if (value) - indicator.StartAnimating (); - else - indicator.StopAnimating (); - } - } - - static NSString ikey = new NSString ("ActivityElement"); - - protected override NSString CellKey { - get { - return ikey; - } - } - - public override UITableViewCell GetCell (UITableView tv) - { - var cell = tv.DequeueReusableCell (CellKey); - if (cell is null) { - cell = new UITableViewCell (UITableViewCellStyle.Default, CellKey); - } - - indicator = new UIActivityIndicatorView (UIActivityIndicatorViewStyle.Gray); - var sbounds = tv.Frame; - var vbounds = indicator.Bounds; - - indicator.Frame = new CGRect ((sbounds.Width - vbounds.Width) / 2, 12, vbounds.Width, vbounds.Height); - indicator.StartAnimating (); - - cell.Add (indicator); - - return cell; - } - - protected override void Dispose (bool disposing) - { - if (disposing) { - if (indicator is not null) { - indicator.Dispose (); - indicator = null; - } - } - base.Dispose (disposing); - } - } -} - diff --git a/tests/common/MonoTouch.Dialog/Elements/MessageElement.cs b/tests/common/MonoTouch.Dialog/Elements/MessageElement.cs deleted file mode 100644 index c17e9f242818..000000000000 --- a/tests/common/MonoTouch.Dialog/Elements/MessageElement.cs +++ /dev/null @@ -1,192 +0,0 @@ -using System; -using System.Drawing; - -using UIKit; -using Foundation; -using CoreGraphics; -using ObjCRuntime; - -namespace MonoTouch.Dialog { - - public partial class MessageSummaryView : UIView { - static UIFont SenderFont = UIFont.BoldSystemFontOfSize (19); - static UIFont SubjectFont = UIFont.SystemFontOfSize (14); - static UIFont TextFont = UIFont.SystemFontOfSize (13); - static UIFont CountFont = UIFont.BoldSystemFontOfSize (13); - public string Sender { get; private set; } - public string Body { get; private set; } - public string Subject { get; private set; } - public DateTime Date { get; private set; } - public bool NewFlag { get; private set; } - public int MessageCount { get; private set; } - - static CGGradient gradient; - - static MessageSummaryView () - { - using (var colorspace = CGColorSpace.CreateDeviceRGB ()) { - gradient = new CGGradient (colorspace, new nfloat [] { /* first */ .52f, .69f, .96f, 1, /* second */ .12f, .31f, .67f, 1 }, null); //new float [] { 0, 1 }); - } - } - - public MessageSummaryView () - { - BackgroundColor = UIColor.White; - } - - public void Update (string sender, string body, string subject, DateTime date, bool newFlag, int messageCount) - { - Sender = sender; - Body = body; - Subject = subject; - Date = date; - NewFlag = newFlag; - MessageCount = messageCount; - SetNeedsDisplay (); - } - - public override void Draw (CGRect rect) - { - const int padright = 21; - var ctx = UIGraphics.GetCurrentContext (); - nfloat boxWidth; - CGSize ssize; - - if (MessageCount > 0) { - var ms = MessageCount.ToString (); - ssize = ms.StringSize (CountFont); - boxWidth = (nfloat) Math.Min (22 + ssize.Width, 18); - var crect = new CGRect (Bounds.Width - 20 - boxWidth, 32, boxWidth, 16); - - UIColor.Gray.SetFill (); - GraphicsUtil.FillRoundedRect (ctx, crect, 3); - UIColor.White.SetColor (); - crect.X += 5; - ms.DrawString (crect, CountFont); - - boxWidth += padright; - } else - boxWidth = 0; - - UIColor.FromRGB (36, 112, 216).SetColor (); - var diff = DateTime.Now - Date; - var now = DateTime.Now; - string label; - if (now.Day == Date.Day && now.Month == Date.Month && now.Year == Date.Year) - label = Date.ToShortTimeString (); - else if (diff <= TimeSpan.FromHours (24)) - label = "Yesterday".GetText (); - else if (diff < TimeSpan.FromDays (6)) - label = Date.ToString ("dddd"); - else - label = Date.ToShortDateString (); - ssize = label.StringSize (SubjectFont); - nfloat dateSize = ssize.Width + padright + 5; - label.DrawString (new CGRect (Bounds.Width - dateSize, 6, dateSize, 14), SubjectFont, UILineBreakMode.Clip, UITextAlignment.Left); - - const int offset = 33; - nfloat bw = Bounds.Width - offset; - - UIColor.Black.SetColor (); - Sender.DrawString (new CGPoint (offset, 2), (float) (bw - dateSize), SenderFont, UILineBreakMode.TailTruncation); - Subject.DrawString (new CGPoint (offset, 23), (float) (bw - offset - boxWidth), SubjectFont, UILineBreakMode.TailTruncation); - - //UIColor.Black.SetFill (); - //ctx.FillRect (new CGRect (offset, 40, bw-boxWidth, 34)); - UIColor.Gray.SetColor (); - Body.DrawString (new CGRect (offset, 40, bw - boxWidth, 34), TextFont, UILineBreakMode.TailTruncation, UITextAlignment.Left); - - if (NewFlag) { - ctx.SaveState (); - ctx.AddEllipseInRect (new CGRect (10, 32, 12, 12)); - ctx.Clip (); - ctx.DrawLinearGradient (gradient, new CGPoint (10, 32), new CGPoint (22, 44), CGGradientDrawingOptions.DrawsAfterEndLocation); - ctx.RestoreState (); - } - -#if WANT_SHADOWS - ctx.SaveState (); - UIColor.FromRGB (78, 122, 198).SetStroke (); - ctx.SetShadow (new CGSize (1, 1), 3); - ctx.StrokeEllipseInRect (new CGRect (10, 32, 12, 12)); - ctx.RestoreState (); -#endif - } - } - - public class MessageElement : Element, IElementSizing { - static NSString mKey = new NSString ("MessageElement"); - - public string Sender, Body, Subject; - public DateTime Date; - public bool NewFlag; - public int MessageCount; - - class MessageCell : UITableViewCell { - MessageSummaryView view; - - public MessageCell () : base (UITableViewCellStyle.Default, mKey) - { - view = new MessageSummaryView (); - ContentView.Add (view); - Accessory = UITableViewCellAccessory.DisclosureIndicator; - } - - public void Update (MessageElement me) - { - view.Update (me.Sender, me.Body, me.Subject, me.Date, me.NewFlag, me.MessageCount); - } - - public override void LayoutSubviews () - { - base.LayoutSubviews (); - view.Frame = ContentView.Bounds; - view.SetNeedsDisplay (); - } - } - - public MessageElement () : base ("") - { - } - - public MessageElement (Action tapped) : base ("") - { - Tapped += tapped; - } - - public override UITableViewCell GetCell (UITableView tv) - { - var cell = tv.DequeueReusableCell (mKey) as MessageCell; - if (cell is null) - cell = new MessageCell (); - cell.Update (this); - return cell; - } - - public nfloat GetHeight (UITableView tableView, NSIndexPath indexPath) - { - return 78; - } - - public event Action Tapped; - - public override void Selected (DialogViewController dvc, UITableView tableView, NSIndexPath path) - { - if (Tapped is not null) - Tapped (dvc, tableView, path); - } - - public override bool Matches (string text) - { - if (Sender is not null && Sender.IndexOf (text, StringComparison.CurrentCultureIgnoreCase) != -1) - return true; - if (Body is not null && Body.IndexOf (text, StringComparison.CurrentCultureIgnoreCase) != -1) - return true; - if (Subject is not null && Subject.IndexOf (text, StringComparison.CurrentCultureIgnoreCase) != -1) - return true; - - return false; - } - } -} - diff --git a/tests/common/MonoTouch.Dialog/Elements/OwnerDrawnElement.cs b/tests/common/MonoTouch.Dialog/Elements/OwnerDrawnElement.cs deleted file mode 100644 index fdbdb37726ac..000000000000 --- a/tests/common/MonoTouch.Dialog/Elements/OwnerDrawnElement.cs +++ /dev/null @@ -1,117 +0,0 @@ -using System; -using System.Drawing; - -using UIKit; -using CoreFoundation; -using CoreGraphics; -using Foundation; -using ObjCRuntime; - -namespace MonoTouch.Dialog { - public abstract partial class OwnerDrawnElement : Element, IElementSizing { - public string CellReuseIdentifier { - get; set; - } - - public UITableViewCellStyle Style { - get; set; - } - - public OwnerDrawnElement (UITableViewCellStyle style, string cellIdentifier) : base (null) - { - this.CellReuseIdentifier = cellIdentifier; - this.Style = style; - } - - public nfloat GetHeight (UITableView tableView, NSIndexPath indexPath) - { - return Height (tableView.Bounds); - } - - public override UITableViewCell GetCell (UITableView tv) - { - OwnerDrawnCell cell = tv.DequeueReusableCell (this.CellReuseIdentifier) as OwnerDrawnCell; - - if (cell is null) { - cell = new OwnerDrawnCell (this, this.Style, this.CellReuseIdentifier); - } else { - cell.Element = this; - } - - cell.Update (); - return cell; - } - - public abstract void Draw (CGRect bounds, CGContext context, UIView view); - - public abstract nfloat Height (CGRect bounds); - - class OwnerDrawnCell : UITableViewCell { - OwnerDrawnCellView view; - - public OwnerDrawnCell (OwnerDrawnElement element, UITableViewCellStyle style, string cellReuseIdentifier) : base (style, cellReuseIdentifier) - { - Element = element; - } - - public OwnerDrawnElement Element { - get { - return view.Element; - } - set { - if (view is null) { - view = new OwnerDrawnCellView (value); - ContentView.Add (view); - } else { - view.Element = value; - } - } - } - - - - public void Update () - { - SetNeedsDisplay (); - view.SetNeedsDisplay (); - } - - public override void LayoutSubviews () - { - base.LayoutSubviews (); - - view.Frame = ContentView.Bounds; - } - } - - class OwnerDrawnCellView : UIView { - OwnerDrawnElement element; - - public OwnerDrawnCellView (OwnerDrawnElement element) - { - this.element = element; - } - - - public OwnerDrawnElement Element { - get { return element; } - set { - element = value; - } - } - - public void Update () - { - SetNeedsDisplay (); - - } - - public override void Draw (CGRect rect) - { - CGContext context = UIGraphics.GetCurrentContext (); - element.Draw (rect, context, this); - } - } - } -} - diff --git a/tests/common/MonoTouch.Dialog/OldElements/LoadMoreElement.cs b/tests/common/MonoTouch.Dialog/OldElements/LoadMoreElement.cs deleted file mode 100644 index 59730f5cb7ec..000000000000 --- a/tests/common/MonoTouch.Dialog/OldElements/LoadMoreElement.cs +++ /dev/null @@ -1,162 +0,0 @@ -// -// This cell does not perform cell recycling, do not use as -// sample code for new elements. -// -using System; -using System.Drawing; -using System.Threading; - -using CoreFoundation; -using Foundation; -using UIKit; -using CoreGraphics; -using ObjCRuntime; - -namespace MonoTouch.Dialog { - public partial class LoadMoreElement : Element, IElementSizing { - static NSString key = new NSString ("LoadMoreElement"); - public string NormalCaption { get; set; } - public string LoadingCaption { get; set; } - public UIColor TextColor { get; set; } - public UIColor BackgroundColor { get; set; } - public event Action Tapped = null; - public UIFont Font; - public float? Height; - UITextAlignment alignment = UITextAlignment.Center; - bool animating; - - public LoadMoreElement () : base ("") - { - } - - public LoadMoreElement (string normalCaption, string loadingCaption, Action tapped) : this (normalCaption, loadingCaption, tapped, UIFont.BoldSystemFontOfSize (16), UIColor.Black) - { - } - - public LoadMoreElement (string normalCaption, string loadingCaption, Action tapped, UIFont font, UIColor textColor) : base ("") - { - NormalCaption = normalCaption; - LoadingCaption = loadingCaption; - Tapped += tapped; - Font = font; - TextColor = textColor; - } - - public override UITableViewCell GetCell (UITableView tv) - { - var cell = tv.DequeueReusableCell (key); - UIActivityIndicatorView activityIndicator; - UILabel caption; - - if (cell is null) { - cell = new UITableViewCell (UITableViewCellStyle.Default, key); - - activityIndicator = new UIActivityIndicatorView () { - ActivityIndicatorViewStyle = UIActivityIndicatorViewStyle.Gray, - Tag = 1 - }; - caption = new UILabel () { - AdjustsFontSizeToFitWidth = false, - AutoresizingMask = UIViewAutoresizing.FlexibleWidth, - Tag = 2 - }; - cell.ContentView.AddSubview (caption); - cell.ContentView.AddSubview (activityIndicator); - } else { - activityIndicator = cell.ContentView.ViewWithTag (1) as UIActivityIndicatorView; - caption = cell.ContentView.ViewWithTag (2) as UILabel; - } - if (Animating) { - caption.Text = LoadingCaption; - activityIndicator.Hidden = false; - activityIndicator.StartAnimating (); - } else { - caption.Text = NormalCaption; - activityIndicator.Hidden = true; - activityIndicator.StopAnimating (); - } - if (BackgroundColor is not null) { - cell.ContentView.BackgroundColor = BackgroundColor ?? UIColor.Clear; - } else { - cell.ContentView.BackgroundColor = null; - } - caption.BackgroundColor = UIColor.Clear; - caption.TextColor = TextColor ?? UIColor.Black; - caption.Font = Font ?? UIFont.BoldSystemFontOfSize (16); - caption.TextAlignment = Alignment; - Layout (cell, activityIndicator, caption); - return cell; - } - - public bool Animating { - get { - return animating; - } - set { - if (animating == value) - return; - animating = value; - var cell = GetActiveCell (); - if (cell is null) - return; - var activityIndicator = cell.ContentView.ViewWithTag (1) as UIActivityIndicatorView; - var caption = cell.ContentView.ViewWithTag (2) as UILabel; - if (value) { - caption.Text = LoadingCaption; - activityIndicator.Hidden = false; - activityIndicator.StartAnimating (); - } else { - activityIndicator.StopAnimating (); - activityIndicator.Hidden = true; - caption.Text = NormalCaption; - } - Layout (cell, activityIndicator, caption); - } - } - - public override void Selected (DialogViewController dvc, UITableView tableView, NSIndexPath path) - { - tableView.DeselectRow (path, true); - - if (Animating) - return; - - if (Tapped is not null) { - Animating = true; - Tapped (this); - } - } - - CGSize GetTextSize (string text) - { - return new NSString (text).StringSize (Font, (float) UIScreen.MainScreen.Bounds.Width, UILineBreakMode.TailTruncation); - } - - const int pad = 10; - const int isize = 20; - - public nfloat GetHeight (UITableView tableView, NSIndexPath indexPath) - { - return Height ?? GetTextSize (Animating ? LoadingCaption : NormalCaption).Height + 2 * pad; - } - - void Layout (UITableViewCell cell, UIActivityIndicatorView activityIndicator, UILabel caption) - { - var sbounds = cell.ContentView.Bounds; - - var size = GetTextSize (Animating ? LoadingCaption : NormalCaption); - - if (!activityIndicator.Hidden) - activityIndicator.Frame = new CGRect ((sbounds.Width - size.Width) / 2 - isize * 2, pad, isize, isize); - - caption.Frame = new CGRect (10, pad, sbounds.Width - 20, size.Height); - } - - public UITextAlignment Alignment { - get { return alignment; } - set { alignment = value; } - } - public UITableViewCellAccessory Accessory { get; set; } - } -} - diff --git a/tests/common/MonoTouch.Dialog/Utilities/Controls.cs b/tests/common/MonoTouch.Dialog/Utilities/Controls.cs index 452af0ce9045..4d514a190aef 100644 --- a/tests/common/MonoTouch.Dialog/Utilities/Controls.cs +++ b/tests/common/MonoTouch.Dialog/Utilities/Controls.cs @@ -9,8 +9,6 @@ using Foundation; using CoreAnimation; -using MonoTouch.Dialog.Utilities; - namespace MonoTouch.Dialog { public enum RefreshViewStatus { ReleaseToReload, @@ -21,7 +19,7 @@ public enum RefreshViewStatus { // This cute method will be added to UIImage.FromResource, but for old installs // make a copy here internal static class Util { - public static UIImage FromResource (Assembly assembly, string name) + public static UIImage? FromResource (Assembly assembly, string name) { if (name is null) throw new ArgumentNullException ("name"); @@ -31,20 +29,14 @@ public static UIImage FromResource (Assembly assembly, string name) return null; try { - using (var data = NSData.FromStream (stream)) + using (var data = NSData.FromStream (stream)) { + if (data is null) + return null; return UIImage.LoadFromData (data); + } } finally { stream.Dispose (); } } - - } - - public class SearchChangedEventArgs : EventArgs { - public SearchChangedEventArgs (string text) - { - Text = text; - } - public string Text { get; set; } } } diff --git a/tests/common/MonoTouch.Dialog/Utilities/GlassButton.cs b/tests/common/MonoTouch.Dialog/Utilities/GlassButton.cs deleted file mode 100644 index 47a280ef2de6..000000000000 --- a/tests/common/MonoTouch.Dialog/Utilities/GlassButton.cs +++ /dev/null @@ -1,131 +0,0 @@ -using System; -using System.Drawing; - -using UIKit; -using CoreGraphics; -using Foundation; -using CoreAnimation; -using ObjCRuntime; - -namespace MonoTouch.Dialog { - - /// - /// GlassButton is a glossy/glass button. User code can use either - /// targets or can subscribe to the Tapped event. Colors are customized - /// by asssigning to the NormalColor, HighlightedColor and DisabledColor - /// properties - /// - public class GlassButton : UIButton { - bool pressed; - - public UIColor NormalColor, HighlightedColor, DisabledColor; - - /// - /// Invoked when the user touches - /// - public event Action Tapped; - - /// - /// Creates a new instance of the GlassButton using the specified dimensions - /// - public GlassButton (CGRect frame) : base (frame) - { - NormalColor = new UIColor (0.55f, 0.04f, 0.02f, 1); - HighlightedColor = UIColor.Black; - DisabledColor = UIColor.Gray; - } - - /// - /// Whether the button is rendered enabled or not. - /// - public override bool Enabled { - get { - return base.Enabled; - } - set { - base.Enabled = value; - SetNeedsDisplay (); - } - } - - public override bool BeginTracking (UITouch uitouch, UIEvent uievent) - { - SetNeedsDisplay (); - pressed = true; - return base.BeginTracking (uitouch, uievent); - } - - public override void EndTracking (UITouch uitouch, UIEvent uievent) - { - if (pressed && Enabled) { - if (Tapped is not null) - Tapped (this); - } - pressed = false; - SetNeedsDisplay (); - base.EndTracking (uitouch, uievent); - } - - public override bool ContinueTracking (UITouch uitouch, UIEvent uievent) - { - var touch = uievent.AllTouches.AnyObject as UITouch; - if (Bounds.Contains (touch.LocationInView (this))) - pressed = true; - else - pressed = false; - return base.ContinueTracking (uitouch, uievent); - } - - public override void Draw (CGRect rect) - { - var context = UIGraphics.GetCurrentContext (); - var bounds = Bounds; - - UIColor background = Enabled ? pressed ? HighlightedColor : NormalColor : DisabledColor; - float alpha = 1; - - CGPath container; - container = GraphicsUtil.MakeRoundedRectPath (bounds, 14); - context.AddPath (container); - context.Clip (); - - using (var cs = CGColorSpace.CreateDeviceRGB ()) { - var topCenter = new CGPoint (bounds.GetMidX (), 0); - var midCenter = new CGPoint (bounds.GetMidX (), bounds.GetMidY ()); - var bottomCenter = new CGPoint (bounds.GetMidX (), bounds.GetMaxY ()); - - using (var gradient = new CGGradient (cs, new nfloat [] { 0.23f, 0.23f, 0.23f, alpha, 0.47f, 0.47f, 0.47f, alpha }, new nfloat [] { 0, 1 })) { - context.DrawLinearGradient (gradient, topCenter, bottomCenter, 0); - } - - container = GraphicsUtil.MakeRoundedRectPath (bounds.Inset (1, 1), 13); - context.AddPath (container); - context.Clip (); - using (var gradient = new CGGradient (cs, new nfloat [] { 0.05f, 0.05f, 0.05f, alpha, 0.15f, 0.15f, 0.15f, alpha }, new nfloat [] { 0, 1 })) { - context.DrawLinearGradient (gradient, topCenter, bottomCenter, 0); - } - - var nb = bounds.Inset (4, 4); - container = GraphicsUtil.MakeRoundedRectPath (nb, 10); - context.AddPath (container); - context.Clip (); - - background.SetFill (); - context.FillRect (nb); - - using (var gradient = new CGGradient (cs, new nfloat [] { 1, 1, 1, .35f, 1, 1, 1, 0.06f }, new nfloat [] { 0, 1 })) { - context.DrawLinearGradient (gradient, topCenter, midCenter, 0); - } - context.SetLineWidth (2); - context.AddPath (container); - context.ReplacePathWithStrokedPath (); - context.Clip (); - - using (var gradient = new CGGradient (cs, new nfloat [] { 1, 1, 1, 0.5f, 0.5f, 0.5f, 0.5f, 0.5f }, new nfloat [] { 0, 1 })) { - context.DrawLinearGradient (gradient, topCenter, bottomCenter, 0); - } - } - } - } -} - diff --git a/tests/common/MonoTouch.Dialog/Utilities/Graphics.cs b/tests/common/MonoTouch.Dialog/Utilities/Graphics.cs deleted file mode 100644 index a2d81835ac0b..000000000000 --- a/tests/common/MonoTouch.Dialog/Utilities/Graphics.cs +++ /dev/null @@ -1,64 +0,0 @@ -using System; - -using CoreGraphics; -using ObjCRuntime; - -namespace MonoTouch.Dialog { - public static class GraphicsUtil { - - /// - /// Creates a path for a rectangle with rounded corners - /// - /// - /// The rectangle bounds - /// - /// - /// The size of the rounded corners - /// - /// - /// A that can be used to stroke the rounded rectangle - /// - public static CGPath MakeRoundedRectPath (CGRect rect, nfloat radius) - { - nfloat minx = rect.Left; - nfloat midx = rect.Left + (rect.Width) / 2; - nfloat maxx = rect.Right; - nfloat miny = rect.Top; - nfloat midy = rect.Y + rect.Size.Height / 2; - nfloat maxy = rect.Bottom; - - var path = new CGPath (); - path.MoveToPoint (minx, midy); - path.AddArcToPoint (minx, miny, midx, miny, radius); - path.AddArcToPoint (maxx, miny, maxx, midy, radius); - path.AddArcToPoint (maxx, maxy, midx, maxy, radius); - path.AddArcToPoint (minx, maxy, minx, midy, radius); - path.CloseSubpath (); - - return path; - } - - public static void FillRoundedRect (CGContext ctx, CGRect rect, nfloat radius) - { - var p = GraphicsUtil.MakeRoundedRectPath (rect, radius); - ctx.AddPath (p); - ctx.FillPath (); - } - - public static CGPath MakeRoundedPath (float size, float radius) - { - float hsize = size / 2; - - var path = new CGPath (); - path.MoveToPoint (size, hsize); - path.AddArcToPoint (size, size, hsize, size, radius); - path.AddArcToPoint (0, size, 0, hsize, radius); - path.AddArcToPoint (0, 0, hsize, 0, radius); - path.AddArcToPoint (size, 0, size, hsize, radius); - path.CloseSubpath (); - - return path; - } - } -} - diff --git a/tests/common/MonoTouch.Dialog/Utilities/LRUCache.cs b/tests/common/MonoTouch.Dialog/Utilities/LRUCache.cs deleted file mode 100644 index cdfcf360a04e..000000000000 --- a/tests/common/MonoTouch.Dialog/Utilities/LRUCache.cs +++ /dev/null @@ -1,140 +0,0 @@ -// -// A simple LRU cache used for tracking the images -// -// Authors: -// Miguel de Icaza (miguel@gnome.org) -// -// Copyright 2010 Miguel de Icaza -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -// THE SOFTWARE. -// -using System; -using System.Collections.Generic; - -namespace MonoTouch.Dialog.Utilities { - - public class LRUCache where TValue : class, IDisposable { - Dictionary> dict; - Dictionary, TKey> revdict; - LinkedList list; - int entryLimit, sizeLimit, currentSize; - Func slotSizeFunc; - - public LRUCache (int entryLimit) : this (entryLimit, 0, null) - { - } - - public LRUCache (int entryLimit, int sizeLimit, Func slotSizer) - { - list = new LinkedList (); - dict = new Dictionary> (); - revdict = new Dictionary, TKey> (); - - if (sizeLimit != 0 && slotSizer is null) - throw new ArgumentNullException ("If sizeLimit is set, the slotSizer must be provided"); - - this.entryLimit = entryLimit; - this.sizeLimit = sizeLimit; - this.slotSizeFunc = slotSizer; - } - - void Evict () - { - var last = list.Last; - var key = revdict [last]; - - if (sizeLimit > 0) { - int size = slotSizeFunc (last.Value); - currentSize -= size; - } - - dict.Remove (key); - revdict.Remove (last); - list.RemoveLast (); - last.Value.Dispose (); - } - - public void Purge () - { - foreach (var element in list) - element.Dispose (); - - dict.Clear (); - revdict.Clear (); - list.Clear (); - currentSize = 0; - } - - public TValue this [TKey key] { - get { - LinkedListNode node; - - if (dict.TryGetValue (key, out node)) { - list.Remove (node); - list.AddFirst (node); - - return node.Value; - } - return null; - } - - set { - LinkedListNode node; - int size = sizeLimit > 0 ? slotSizeFunc (value) : 0; - - if (dict.TryGetValue (key, out node)) { - if (sizeLimit > 0 && node.Value is not null) { - int repSize = slotSizeFunc (node.Value); - currentSize -= repSize; - currentSize += size; - } - - // If we already have a key, move it to the front - list.Remove (node); - list.AddFirst (node); - - // Remove the old value - if (node.Value is not null) - node.Value.Dispose (); - node.Value = value; - while (sizeLimit > 0 && currentSize > sizeLimit && list.Count > 1) - Evict (); - return; - } - if (sizeLimit > 0) { - while (sizeLimit > 0 && currentSize + size > sizeLimit && list.Count > 0) - Evict (); - } - if (dict.Count >= entryLimit) - Evict (); - // Adding new node - node = new LinkedListNode (value); - list.AddFirst (node); - dict [key] = node; - revdict [node] = key; - currentSize += size; - } - } - - public override string ToString () - { - return "LRUCache dict={0} revdict={1} list={2}"; - } - } -} diff --git a/tests/common/MonoTouch.Dialog/shared.csproj b/tests/common/MonoTouch.Dialog/shared.csproj index 57d76949c7d6..dbb2c9e2083c 100644 --- a/tests/common/MonoTouch.Dialog/shared.csproj +++ b/tests/common/MonoTouch.Dialog/shared.csproj @@ -12,6 +12,8 @@ $(NoWarn);CA1422 + enable + Nullable From e7ada3205f5d6c3fbc372c221c7e16d65171a260 Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Wed, 22 Apr 2026 21:50:53 +0200 Subject: [PATCH 2/2] Fix MonoTouch.Dialog nullability Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- tests/common/MonoTouch.Dialog/Elements.cs | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/tests/common/MonoTouch.Dialog/Elements.cs b/tests/common/MonoTouch.Dialog/Elements.cs index e7d613660307..15c5a9fd959d 100644 --- a/tests/common/MonoTouch.Dialog/Elements.cs +++ b/tests/common/MonoTouch.Dialog/Elements.cs @@ -552,6 +552,16 @@ public override bool Matches (string text) public partial class StyledStringElement : StringElement, IColorizeBackground { static NSString [] skey = { new NSString (".1"), new NSString (".2"), new NSString (".3"), new NSString (".4") }; + internal static UIFont GetBoldFont (nfloat size) + { + return UIFont.BoldSystemFontOfSize (size) ?? throw new InvalidOperationException ("Unable to create a bold system font."); + } + + internal static UIFont GetSystemFont (nfloat size) + { + return UIFont.SystemFontOfSize (size) ?? throw new InvalidOperationException ("Unable to create a system font."); + } + public StyledStringElement (string caption) : base (caption) { } public StyledStringElement (string caption, NSAction tapped) : base (caption, tapped) { } public StyledStringElement (string caption, string value) : base (caption, value) @@ -629,7 +639,7 @@ protected void PrepareCell (UITableViewCell cell) tl.Text = Caption; tl.TextAlignment = Alignment; tl.TextColor = TextColor ?? UIColor.Black; - tl.Font = Font ?? UIFont.BoldSystemFontOfSize (17); + tl.Font = Font ?? GetBoldFont (17); tl.LineBreakMode = LineBreakMode; tl.Lines = Lines; @@ -647,7 +657,7 @@ protected void PrepareCell (UITableViewCell cell) if (cell.DetailTextLabel is not null) { cell.DetailTextLabel.Lines = Lines; cell.DetailTextLabel.LineBreakMode = LineBreakMode; - cell.DetailTextLabel.Font = SubtitleFont ?? UIFont.SystemFontOfSize (14); + cell.DetailTextLabel.Font = SubtitleFont ?? GetSystemFont (14); cell.DetailTextLabel.TextColor = (extraInfo is null || extraInfo.DetailColor is null) ? UIColor.Gray : extraInfo.DetailColor; } } @@ -773,11 +783,11 @@ public virtual nfloat GetHeight (UITableView tableView, NSIndexPath indexPath) if (String.IsNullOrEmpty (c)) c = " "; - var captionFont = Font ?? UIFont.BoldSystemFontOfSize (17); + var captionFont = Font ?? StyledStringElement.GetBoldFont (17); var height = c.StringSize (captionFont, maxSize, LineBreakMode).Height; if (!String.IsNullOrEmpty (v)) { - var subtitleFont = SubtitleFont ?? UIFont.SystemFontOfSize (14); + var subtitleFont = SubtitleFont ?? StyledStringElement.GetSystemFont (14); if (this.style == UITableViewCellStyle.Subtitle) { height += v.StringSize (subtitleFont, maxSize, LineBreakMode).Height; } else { @@ -836,7 +846,7 @@ public virtual nfloat GetHeight (UITableView tableView, NSIndexPath indexPath) { float margin = UIDevice.CurrentDevice.UserInterfaceIdiom == UIUserInterfaceIdiom.Phone ? 40f : 110f; CGSize size = new CGSize (tableView.Bounds.Width - margin, float.MaxValue); - UIFont font = UIFont.BoldSystemFontOfSize (17); + var font = StyledStringElement.GetBoldFont (17); string? c = Caption; // ensure the (single-line) Value will be rendered inside the cell if (String.IsNullOrEmpty (c) && !String.IsNullOrEmpty (Value)) @@ -993,7 +1003,7 @@ public UITextAlignment TextAlignment { bool isPassword, becomeResponder; UITextField? entry; string? placeholder; - static UIFont font = UIFont.BoldSystemFontOfSize (17); + static UIFont font = StyledStringElement.GetBoldFont (17); public event EventHandler? Changed; public event Func? ShouldReturn;