|
1 | 1 | using System;
|
| 2 | +using System.Collections.Generic; |
| 3 | +using System.Linq; |
| 4 | +using System.Threading.Tasks; |
2 | 5 | using AppKit;
|
| 6 | +using Plugin.Badge.Abstractions; |
| 7 | +using Xamarin.Forms; |
3 | 8 | using Xamarin.Forms.Platform.MacOS;
|
4 | 9 |
|
5 | 10 | namespace Plugin.Badge.Mac
|
6 | 11 | {
|
7 | 12 | public class BadgedTabbedPageRenderer : TabbedPageRenderer
|
8 | 13 | {
|
9 |
| - public BadgedTabbedPageRenderer() |
10 |
| - { |
11 |
| - } |
| 14 | + protected readonly Dictionary<Element, BadgeView> BadgeViews = new Dictionary<Element, BadgeView>(); |
| 15 | + private NSSegmentedControl _segmentedControl; |
12 | 16 |
|
13 | 17 | protected override void OnElementChanged(VisualElementChangedEventArgs e)
|
14 | 18 | {
|
15 |
| - |
16 | 19 | base.OnElementChanged(e);
|
| 20 | + } |
| 21 | + |
| 22 | + public override void ViewWillAppear() |
| 23 | + { |
| 24 | + base.ViewWillAppear(); |
| 25 | + |
| 26 | + |
| 27 | + Cleanup(Tabbed); |
| 28 | + |
17 | 29 |
|
18 |
| - foreach(var item in this.TabViewItems){ |
19 |
| - item.ToolTip = "bla"; |
| 30 | + Tabbed.ChildAdded += OnTabAdded; |
| 31 | + Tabbed.ChildRemoved += OnTabRemoved; |
| 32 | + |
| 33 | + _segmentedControl = this.View.Subviews.FirstOrDefault(s => s is NSSegmentedControl) as NSSegmentedControl; |
| 34 | + if (_segmentedControl == null) |
| 35 | + { |
| 36 | + Console.WriteLine("[TabBadge] No SegmentedControl found. Not adding tabs."); |
20 | 37 | }
|
21 | 38 |
|
22 | 39 |
|
| 40 | + _segmentedControl.SegmentStyle = NSSegmentStyle.TexturedSquare; |
23 | 41 |
|
| 42 | + var tabWidth = this.View.Frame.Width / _segmentedControl.SegmentCount; |
24 | 43 |
|
| 44 | + for (var i = 0; i < Tabbed.Children.Count; i++) |
| 45 | + { |
| 46 | + AddTabBadge(i); |
| 47 | + } |
25 | 48 | }
|
26 | 49 |
|
27 |
| - public override void ViewWillAppear() |
| 50 | + protected virtual void AddTabBadge(int tabIndex) |
28 | 51 | {
|
29 |
| - base.ViewWillAppear(); |
| 52 | + var segment = _segmentedControl.Subviews[tabIndex]; |
| 53 | + |
| 54 | + var element = Tabbed.Children[tabIndex]; |
| 55 | + element.PropertyChanged += OnTabbedPagePropertyChanged; |
| 56 | + |
| 57 | + var badge = new BadgeView(segment, false) |
| 58 | + { |
| 59 | + Color = TabBadge.GetBadgeColor(element), |
| 60 | + TextColor = TabBadge.GetBadgeTextColor(element), |
| 61 | + Text = TabBadge.GetBadgeText(element) |
| 62 | + }; |
| 63 | + |
| 64 | + BadgeViews.Add(element, badge); |
| 65 | + } |
30 | 66 |
|
| 67 | + protected virtual void OnTabbedPagePropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e) |
| 68 | + { |
| 69 | + var element = sender as Element; |
| 70 | + if (element == null) |
| 71 | + return; |
31 | 72 |
|
32 |
| - //foreach (var item in this.TabViewItems) |
33 |
| - //{ |
34 |
| - // item.ToolTip = "blabla"; |
35 |
| - // item.View.Layer.BackgroundColor = new CoreGraphics.CGColor(0.1f, 0.5f, 0.7f); |
36 |
| - |
37 |
| - // Console.WriteLine(item.View.GetType().Name); |
38 |
| - // foreach(var view in item.View.Subviews){ |
39 |
| - // Console.WriteLine(view.GetType().Name); |
40 |
| - // } |
41 |
| - //} |
| 73 | + if (!BadgeViews.TryGetValue(element, out BadgeView badgeView)) |
| 74 | + { |
| 75 | + return; |
| 76 | + } |
42 | 77 |
|
43 |
| - foreach (var view in this.View.Subviews) |
44 |
| - { |
45 |
| - Console.WriteLine(view.GetType().Name); |
46 |
| - if(view is NSSegmentedControl){ |
47 |
| - var segmentedControl = view as NSSegmentedControl; |
48 |
| - segmentedControl.SegmentStyle = NSSegmentStyle.TexturedSquare; |
| 78 | + if (e.PropertyName == TabBadge.BadgeTextProperty.PropertyName) |
| 79 | + { |
| 80 | + badgeView.Text = TabBadge.GetBadgeText(element); |
| 81 | + return; |
| 82 | + } |
49 | 83 |
|
50 |
| - foreach (var segment in segmentedControl.Subviews) |
51 |
| - { |
52 |
| - |
53 |
| - var badge = new NSView(new CoreGraphics.CGRect(0, 0, 20, 20)); |
54 |
| - badge.WantsLayer = true; |
55 |
| - badge.Layer.BackgroundColor = new CoreGraphics.CGColor(1f, 0f, 0f); |
56 |
| - //badge.AddConstraints(new []{}); |
| 84 | + if (e.PropertyName == TabBadge.BadgeColorProperty.PropertyName) |
| 85 | + { |
| 86 | + badgeView.Color = TabBadge.GetBadgeColor(element); |
| 87 | + return; |
| 88 | + } |
57 | 89 |
|
58 |
| - segment.AddSubview(badge); |
59 |
| - var constraint = NSLayoutConstraint.Create(badge, NSLayoutAttribute.Right, NSLayoutRelation.Equal); |
60 |
| - badge.AddConstraint(constraint); |
| 90 | + if (e.PropertyName == TabBadge.BadgeTextColorProperty.PropertyName) |
| 91 | + { |
| 92 | + badgeView.TextColor = TabBadge.GetBadgeTextColor(element); |
| 93 | + return; |
| 94 | + } |
| 95 | + |
| 96 | + if (e.PropertyName == TabBadge.BadgeFontProperty.PropertyName) |
| 97 | + { |
| 98 | + badgeView.Font = TabBadge.GetBadgeFont(element); |
| 99 | + return; |
| 100 | + } |
| 101 | + } |
| 102 | + |
| 103 | + private void OnTabRemoved(object sender, ElementEventArgs e) |
| 104 | + { |
| 105 | + e.Element.PropertyChanged -= OnTabbedPagePropertyChanged; |
| 106 | + BadgeViews.Remove(e.Element); |
| 107 | + } |
| 108 | + |
| 109 | + private async void OnTabAdded(object sender, ElementEventArgs e) |
| 110 | + { |
| 111 | + //workaround for XF, tabbar is not updated at this point and we have no way of knowing for sure when it will be updated. so we have to wait ... |
| 112 | + await Task.Delay(10); |
61 | 113 |
|
| 114 | + var page = e.Element as Page; |
| 115 | + if (page == null) |
| 116 | + return; |
62 | 117 |
|
63 |
| - Console.WriteLine(segment.GetType().Name); |
64 |
| - } |
65 |
| - } |
66 |
| - } |
| 118 | + var tabIndex = Tabbed.Children.IndexOf(page); |
| 119 | + AddTabBadge(tabIndex); |
| 120 | + } |
| 121 | + |
| 122 | + protected override void Dispose(bool disposing) |
| 123 | + { |
| 124 | + Cleanup(Tabbed); |
| 125 | + |
| 126 | + base.Dispose(disposing); |
| 127 | + } |
67 | 128 |
|
| 129 | + private void Cleanup(TabbedPage page) |
| 130 | + { |
| 131 | + if (page == null) |
| 132 | + { |
| 133 | + return; |
| 134 | + } |
| 135 | + |
| 136 | + foreach (var tab in page.Children) |
| 137 | + { |
| 138 | + tab.PropertyChanged -= OnTabbedPagePropertyChanged; |
| 139 | + } |
68 | 140 |
|
| 141 | + page.ChildRemoved -= OnTabRemoved; |
| 142 | + page.ChildAdded -= OnTabAdded; |
69 | 143 |
|
| 144 | + BadgeViews.Clear(); |
70 | 145 | }
|
71 | 146 | }
|
72 | 147 | }
|
0 commit comments