// // DialogViewController.cs: drives MonoTouch.Dialog // // Author: // Miguel de Icaza // // Code to support pull-to-refresh based on Martin Bowling's TweetTableView // which is based in turn in EGOTableViewPullRefresh code which was created // by Devin Doty and is Copyrighted 2009 enormego and released under the // MIT X11 license // using System; using UIKit; using CoreGraphics; using System.Collections.Generic; using Foundation; using CodeHub.iOS.DialogElements; using System.Linq; namespace CodeHub.iOS.ViewControllers { /// /// The DialogViewController is the main entry point to use MonoTouch.Dialog, /// it provides a simplified API to the UITableViewController. /// public class DialogViewController : TableViewController { private readonly Lazy _rootElement; private UISearchBar _searchBar; bool pushing; public RootElement Root => _rootElement.Value; public bool EnableSearch { get; set; } public string SearchPlaceholder { get; set; } public override void DidRotate (UIInterfaceOrientation fromInterfaceOrientation) { base.DidRotate (fromInterfaceOrientation); ReloadData (); } Section [] originalSections; Element [][] originalElements; /// /// Allows caller to programatically activate the search bar and start the search process /// public void StartSearch () { if (originalSections != null) return; _searchBar.BecomeFirstResponder (); CreateOriginals(Root); } private void CreateOriginals(RootElement root) { originalSections = root.Sections.ToArray (); originalElements = new Element [originalSections.Length][]; for (int i = 0; i < originalSections.Length; i++) originalElements [i] = originalSections [i].Elements.ToArray (); } /// /// Allows the caller to programatically stop searching. /// public virtual void FinishSearch () { if (originalSections == null) return; _searchBar.Text = ""; Root.Reset(originalSections); originalSections = null; originalElements = null; _searchBar.ResignFirstResponder (); ReloadData (); } public void PerformFilter (string text) { if (originalSections == null) return; 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 eidx = 0; eidx < elements.Length; eidx++){ if (elements [eidx].Matches (text)){ if (newSection == null){ newSection = new Section (section.Header, section.Footer){ FooterView = section.FooterView, HeaderView = section.HeaderView }; newSections.Add (newSection); } newSection.Add (elements [eidx]); } } } Root.Reset(newSections); ReloadData (); } public virtual void SearchButtonClicked (string text) { _searchBar.ResignFirstResponder(); } protected class SearchDelegate : UISearchBarDelegate { readonly WeakReference container; public SearchDelegate (DialogViewController container) { this.container = new WeakReference(container); } public override void OnEditingStarted (UISearchBar searchBar) { searchBar.ShowsCancelButton = true; container.Get()?.StartSearch (); } public override void OnEditingStopped (UISearchBar searchBar) { searchBar.ShowsCancelButton = false; //container.FinishSearch (); } public override void TextChanged (UISearchBar searchBar, string searchText) { container.Get()?.PerformFilter (searchText ?? ""); } public override void CancelButtonClicked (UISearchBar searchBar) { var r = container.Get(); searchBar.ShowsCancelButton = false; if (r != null) { r._searchBar.Text = ""; r.FinishSearch(); } searchBar.ResignFirstResponder (); } public override void SearchButtonClicked (UISearchBar searchBar) { container.Get()?.SearchButtonClicked (searchBar.Text); } } protected virtual void DidScroll(CGPoint p) { } public class Source : UITableViewSource { private readonly WeakReference _container; public RootElement Root => _container.Get()?.Root; public DialogViewController Container { get { return _container.Get(); } } public Source (DialogViewController container) { _container = new WeakReference(container); } public override nint RowsInSection (UITableView tableview, nint section) { var s = Root?[(int)section]; var count = s?.Elements.Count; return count ?? 0; } public override nint NumberOfSections (UITableView tableView) { return Root?.Count ?? 0; } public override string TitleForHeader (UITableView tableView, nint section) { return Root?[(int)section]?.Header; } public override string TitleForFooter (UITableView tableView, nint section) { return Root?[(int)section]?.Footer; } public override UITableViewCell GetCell (UITableView tableView, NSIndexPath indexPath) { var section = Root?[indexPath.Section]; var element = section?[indexPath.Row]; return element?.GetCell (tableView); } public override void RowDeselected (UITableView tableView, NSIndexPath indexPath) { _container.Get()?.Deselected (indexPath); } public override void RowSelected (UITableView tableView, NSIndexPath indexPath) { _container.Get()?.Selected (indexPath); } public override UIView GetViewForHeader (UITableView tableView, nint sectionIdx) { var section = Root?[(int)sectionIdx]; return section?.HeaderView; } public override nfloat GetHeightForHeader (UITableView tableView, nint sectionIdx) { var section = Root?[(int)sectionIdx]; return section?.HeaderView?.Frame.Height ?? -1; } public override UIView GetViewForFooter (UITableView tableView, nint sectionIdx) { var section = Root?[(int)sectionIdx]; return section?.FooterView; } public override nfloat GetHeightForFooter (UITableView tableView, nint sectionIdx) { var section = Root?[(int)sectionIdx]; return section?.FooterView?.Frame.Height ?? -1; } public override void Scrolled (UIScrollView scrollView) { _container.Get()?.DidScroll(Root.TableView.ContentOffset); } public override nfloat GetHeightForRow (UITableView tableView, NSIndexPath indexPath) { var section = Root?[indexPath.Section]; var element = section?[indexPath.Row]; var sizable = element as IElementSizing; return sizable?.GetHeight(tableView, indexPath) ?? tableView.RowHeight; } } protected virtual IUISearchBarDelegate CreateSearchDelegate() { return new SearchDelegate(this); } void SetupSearch () { if (EnableSearch){ _searchBar = new UISearchBar (new CGRect (0, 0, TableView.Bounds.Width, 44)) { Delegate = CreateSearchDelegate() }; if (SearchPlaceholder != null) _searchBar.Placeholder = this.SearchPlaceholder; TableView.TableHeaderView = _searchBar; } else { // Does not work with current Monotouch, will work with 3.0 // tableView.TableHeaderView = null; } } public virtual void Deselected (NSIndexPath indexPath) { var section = Root[indexPath.Section]; var element = section[indexPath.Row]; element.Deselected (TableView, indexPath); } public virtual void Selected (NSIndexPath indexPath) { var section = Root[indexPath.Section]; var element = section[indexPath.Row]; element.Selected (TableView, indexPath); } public virtual Source CreateSizingSource() { return new Source (this); } public override void LoadView () { base.LoadView(); SetupSearch (); TableView.Source = CreateSizingSource(); } public override void ViewWillAppear (bool animated) { base.ViewWillAppear (animated); NavigationItem.HidesBackButton = !pushing; TableView.ReloadData (); } public bool Pushing { get { return pushing; } set { pushing = value; if (NavigationItem != null) NavigationItem.HidesBackButton = !pushing; } } public void ReloadData () { TableView.ReloadData(); } public DialogViewController (UITableViewStyle style, bool pushing = true) : base (style) { _rootElement = new Lazy(() => new RootElement(TableView)); EdgesForExtendedLayout = UIRectEdge.None; SearchPlaceholder = "Search"; NavigationItem.BackBarButtonItem = new UIBarButtonItem { Title = "" }; this.pushing = pushing; } } }