diff options
14 files changed, 173 insertions, 91 deletions
diff --git a/Xamarin.Forms.Platform.Tizen/Cells/ViewCellRenderer.cs b/Xamarin.Forms.Platform.Tizen/Cells/ViewCellRenderer.cs index 69065c8a..63287786 100644 --- a/Xamarin.Forms.Platform.Tizen/Cells/ViewCellRenderer.cs +++ b/Xamarin.Forms.Platform.Tizen/Cells/ViewCellRenderer.cs @@ -5,6 +5,7 @@ namespace Xamarin.Forms.Platform.Tizen { public class ViewCellRenderer : CellRenderer { + readonly Dictionary<EvasObject, ViewCell> _cacheCandidate = new Dictionary<EvasObject, ViewCell>(); public ViewCellRenderer() : base("full") { MainContentPart = "elm.swallow.content"; @@ -12,21 +13,42 @@ namespace Xamarin.Forms.Platform.Tizen protected string MainContentPart { get; set; } + protected override EvasObject OnReusableContent(Cell cell, string part, EvasObject old) + { + if (_cacheCandidate.ContainsKey(old)) + { + var viewCell = _cacheCandidate[old]; + var widget = (old as Widget); + if (widget != null) + widget.IsEnabled = true; + viewCell.BindingContext = cell.BindingContext; + return old; + } + return null; + } + protected override EvasObject OnGetContent(Cell cell, string part) { if (part == MainContentPart) { - var viewCell = cell as ViewCell; - if (viewCell != null) - { - var renderer = Platform.GetOrCreateRenderer(viewCell.View); - int height = (int)viewCell.RenderHeight; - height = height <= 0 ? FindCellContentHeight(viewCell) : height; + var viewCell = (ViewCell)cell; - renderer.NativeView.MinimumHeight = height; - return renderer.NativeView; + var listView = viewCell?.RealParent as ListView; + + // It is a condition for reusable the cell + if (listView != null && + listView.HasUnevenRows == false && + !(listView.ItemTemplate is DataTemplateSelector)) + { + return CreateReusableContent(viewCell); } - return null; + + var renderer = Platform.GetOrCreateRenderer(viewCell.View); + int height = (int)viewCell.RenderHeight; + height = height > 0 ? height : FindCellContentHeight(viewCell); + + renderer.NativeView.MinimumHeight = height; + return renderer.NativeView; } return null; } @@ -39,5 +61,26 @@ namespace Xamarin.Forms.Platform.Tizen } return base.OnCellPropertyChanged(cell, property, realizedView); } + + EvasObject CreateReusableContent(ViewCell viewCell) + { + var listView = viewCell.RealParent as ListView; + ViewCell duplicatedCell = (ViewCell)listView.ItemTemplate.CreateContent(); + duplicatedCell.BindingContext = viewCell.BindingContext; + duplicatedCell.Parent = listView; + + var renderer = Platform.GetOrCreateRenderer(duplicatedCell.View); + int height = (int)duplicatedCell.RenderHeight; + height = height > 0 ? height : FindCellContentHeight(duplicatedCell); + renderer.NativeView.MinimumHeight = height; + + _cacheCandidate[renderer.NativeView] = duplicatedCell; + renderer.NativeView.Deleted += (sender, e) => + { + _cacheCandidate.Remove((EvasObject)sender); + }; + + return renderer.NativeView; + } } } diff --git a/Xamarin.Forms.Platform.Tizen/Extensions/ColorExtensions.cs b/Xamarin.Forms.Platform.Tizen/Extensions/ColorExtensions.cs index 553c2cba..ae348274 100644 --- a/Xamarin.Forms.Platform.Tizen/Extensions/ColorExtensions.cs +++ b/Xamarin.Forms.Platform.Tizen/Extensions/ColorExtensions.cs @@ -13,7 +13,7 @@ namespace Xamarin.Forms.Platform.Tizen { if (c.IsDefault) { - Log.Warn("Trying to convert the default color, this may result in black color."); + // Trying to convert the default color, this may result in black color. return EColor.Default; } else diff --git a/Xamarin.Forms.Platform.Tizen/Forms.cs b/Xamarin.Forms.Platform.Tizen/Forms.cs index 6aa0e62b..453bab82 100644 --- a/Xamarin.Forms.Platform.Tizen/Forms.cs +++ b/Xamarin.Forms.Platform.Tizen/Forms.cs @@ -1,12 +1,22 @@ using System; +using System.Collections.Generic; +using System.Linq; +using System.Linq.Expressions; using System.Reflection; -using Tizen.Applications; using ElmSharp; +using Tizen.Applications; +using TSystemInfo = Tizen.System.SystemInfo; namespace Xamarin.Forms.Platform.Tizen { public static class Forms { + static Lazy<int> s_dpi = new Lazy<int>(() => + { + int dpi = 0; + TSystemInfo.TryGetValue<int>("http://tizen.org/feature/screen.dpi", out dpi); + return dpi; + }); class TizenDeviceInfo : DeviceInfo { readonly Size pixelScreenSize; @@ -41,10 +51,15 @@ namespace Xamarin.Forms.Platform.Tizen public TizenDeviceInfo(FormsApplication formsApplication) { - // TODO: obtain screen data from device - pixelScreenSize = new Size(); - scaledScreenSize = new Size(); - scalingFactor = 0.0; + int width = 0; + int height = 0; + + TSystemInfo.TryGetValue("http://tizen.org/feature/screen.width", out width); + TSystemInfo.TryGetValue("http://tizen.org/feature/screen.height", out height); + + scalingFactor = 1.0; // scaling is disabled, we're using pixels as Xamarin's geometry units + pixelScreenSize = new Size(width, height); + scaledScreenSize = new Size(width / scalingFactor, height / scalingFactor); } } @@ -155,7 +170,7 @@ namespace Xamarin.Forms.Platform.Tizen // FIXME: We should consider TV and Common (Desktop) profiles also. Device.Idiom = TargetIdiom.Phone; - + ExpressionSearch.Default = new TizenExpressionSearch(); IsInitialized = true; } @@ -169,5 +184,37 @@ namespace Xamarin.Forms.Platform.Tizen // TODO: implement me return Color.Black; } + + internal static int ConvertToPixel(double dp) + { + return (int)Math.Round(dp * s_dpi.Value / 160.0); + } + } + + class TizenExpressionSearch : ExpressionVisitor, IExpressionSearch + { + List<object> _results; + Type _targetType; + + public List<T> FindObjects<T>(Expression expression) where T : class + { + _results = new List<object>(); + _targetType = typeof(T); + Visit(expression); + return _results.Select(o => o as T).ToList(); + } + + protected override Expression VisitMember(MemberExpression node) + { + if (node.Expression is ConstantExpression && node.Member is FieldInfo) + { + var container = ((ConstantExpression)node.Expression).Value; + var value = ((FieldInfo)node.Member).GetValue(container); + + if (_targetType.IsInstanceOfType(value)) + _results.Add(value); + } + return base.VisitMember(node); + } } } diff --git a/Xamarin.Forms.Platform.Tizen/Native/ListView.cs b/Xamarin.Forms.Platform.Tizen/Native/ListView.cs index e932a28e..f5047b3d 100644 --- a/Xamarin.Forms.Platform.Tizen/Native/ListView.cs +++ b/Xamarin.Forms.Platform.Tizen/Native/ListView.cs @@ -501,6 +501,7 @@ namespace Xamarin.Forms.Platform.Tizen.Native } groupItemContext.Item.SelectionMode = GenListSelectionMode.None; + groupItemContext.Item.IsEnabled = groupCell.IsEnabled; groupItemContext.IsGroupItem = true; groupItemContext.ListOfSubItems = groupList; @@ -543,6 +544,7 @@ namespace Xamarin.Forms.Platform.Tizen.Native } itemContext.Item.SelectionMode = GenListSelectionMode.Always; + itemContext.Item.IsEnabled = cell.IsEnabled; cell.PropertyChanged += OnCellPropertyChanged; (cell as ICellController).ForceUpdateSizeRequested += OnForceUpdateSizeRequested; diff --git a/Xamarin.Forms.Platform.Tizen/Native/Span.cs b/Xamarin.Forms.Platform.Tizen/Native/Span.cs index 7ac4134f..0e3f0000 100644 --- a/Xamarin.Forms.Platform.Tizen/Native/Span.cs +++ b/Xamarin.Forms.Platform.Tizen/Native/Span.cs @@ -175,7 +175,7 @@ namespace Xamarin.Forms.Platform.Tizen.Native if (FontSize != -1) { - _formattingString.AppendFormat("font_size={0} ", FontSize); + _formattingString.AppendFormat("font_size={0} ", Forms.ConvertToPixel(FontSize)); } if ((FontAttributes & FontAttributes.Bold) != 0) diff --git a/Xamarin.Forms.Platform.Tizen/Native/TableView.cs b/Xamarin.Forms.Platform.Tizen/Native/TableView.cs index 73388a84..2a77299f 100644 --- a/Xamarin.Forms.Platform.Tizen/Native/TableView.cs +++ b/Xamarin.Forms.Platform.Tizen/Native/TableView.cs @@ -25,7 +25,8 @@ namespace Xamarin.Forms.Platform.Tizen.Native Clear(); foreach (TableSection ts in root) { - AddSectionTitle(ts.Title); + if(!string.IsNullOrEmpty(ts.Title)) + AddSectionTitle(ts.Title); AddSource(ts); } } diff --git a/Xamarin.Forms.Platform.Tizen/Platform.cs b/Xamarin.Forms.Platform.Tizen/Platform.cs index ab073007..c7a89b06 100644 --- a/Xamarin.Forms.Platform.Tizen/Platform.cs +++ b/Xamarin.Forms.Platform.Tizen/Platform.cs @@ -6,7 +6,7 @@ using ElmSharp; namespace Xamarin.Forms.Platform.Tizen { - internal class Platform : BindableObject, IPlatform, INavigation, IDisposable + public class Platform : BindableObject, IPlatform, INavigation, IDisposable { internal static readonly BindableProperty RendererProperty = BindableProperty.CreateAttached("Renderer", typeof(IVisualElementRenderer), typeof(Platform), default(IVisualElementRenderer), propertyChanged: (bindable, oldvalue, newvalue) => diff --git a/Xamarin.Forms.Platform.Tizen/Renderers/NavigationPageRenderer.cs b/Xamarin.Forms.Platform.Tizen/Renderers/NavigationPageRenderer.cs index e760489d..c8f8606a 100644 --- a/Xamarin.Forms.Platform.Tizen/Renderers/NavigationPageRenderer.cs +++ b/Xamarin.Forms.Platform.Tizen/Renderers/NavigationPageRenderer.cs @@ -22,6 +22,11 @@ namespace Xamarin.Forms.Platform.Tizen readonly List<Widget> _naviItemContentPartList = new List<Widget>(); ToolbarTracker _toolbarTracker = null; + Page CurrentPage => Element.CurrentPage; + Page PreviousPage => Element.Navigation.NavigationStack.Count > 1 ? Element.Navigation.NavigationStack[Element.Navigation.NavigationStack.Count - 2] : null; + NaviItem CurrentNaviItem => _naviFrame.NavigationStack.Count > 0 ? _naviFrame.NavigationStack.Last() : null; + NaviItem PreviousNaviItem => _naviFrame.NavigationStack.Count > 1 ? _naviFrame.NavigationStack[_naviFrame.NavigationStack.Count - 2] : null; + public NavigationPageRenderer() { } @@ -99,6 +104,11 @@ namespace Xamarin.Forms.Platform.Tizen _previousPage = Element.CurrentPage; (_previousPage as IPageController)?.SendAppearing(); } + else if (e.PropertyName == NavigationPage.BarTextColorProperty.PropertyName) + UpdateTitle(CurrentPage); + // Tizen does not support 'Tint', but only 'BarBackgroundColor' + else if (e.PropertyName == NavigationPage.BarBackgroundColorProperty.PropertyName) + UpdateBarBackgroundColor(CurrentNaviItem); } void PageCollectionChangedHandler(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) @@ -124,10 +134,7 @@ namespace Xamarin.Forms.Platform.Tizen else if (e.PropertyName == NavigationPage.HasBackButtonProperty.PropertyName || e.PropertyName == NavigationPage.BackButtonTitleProperty.PropertyName) UpdateHasBackButton(sender as Page); - else if (e.PropertyName == Page.TitleProperty.PropertyName || - e.PropertyName == NavigationPage.BarBackgroundColorProperty.PropertyName || - e.PropertyName == NavigationPage.BarTextColorProperty.PropertyName || - e.PropertyName == NavigationPage.TintProperty.PropertyName) + else if (e.PropertyName == Page.TitleProperty.PropertyName) UpdateTitle(sender as Page); } @@ -136,6 +143,7 @@ namespace Xamarin.Forms.Platform.Tizen NaviItem item = GetNaviItemForPage(page); item.TitleBarVisible = (bool)page.GetValue(NavigationPage.HasNavigationBarProperty); UpdateToolbarItem(page, item); + UpdateBarBackgroundColor(item); } void UpdateToolbarItem(Page page, NaviItem item = null) @@ -171,9 +179,11 @@ namespace Xamarin.Forms.Platform.Tizen item.SetPartContent(_partBackButton, button); } - void UpdateTitle(Page page) + void UpdateTitle(Page page, NaviItem item = null) { - NaviItem item = GetNaviItemForPage(page); + if (item == null) + item = GetNaviItemForPage(page); + item.SetPartText(_partTitle, SpanTitle(page.Title)); } @@ -185,21 +195,23 @@ namespace Xamarin.Forms.Platform.Tizen HorizontalTextAlignment = Native.TextAlignment.Center, ForegroundColor = Element.BarTextColor.ToNative() }; - - //TODO: changes only background of title not all bar - if (Element.BarBackgroundColor != Color.Default) - { - span.BackgroundColor = Element.BarBackgroundColor.ToNative(); - } - else if (Element.Tint != Color.Default) - { - //TODO: This is only for backward compatibility - //- remove when Tint is no longer in Xamarin API - span.BackgroundColor = Element.Tint.ToNative(); - } return span.GetMarkupText(); } + void UpdateBarBackgroundColor(NaviItem item) + { + item.TitleBarBackgroundColor = Element.BarBackgroundColor.ToNative(); + } + + void UpdateNavigationBar(Page page, NaviItem item = null) + { + if (item == null) + item = GetNaviItemForPage(page); + + UpdateTitle(page, item); + UpdateBarBackgroundColor(item); + } + EButton CreateNavigationButton(string text) { EButton button = new EButton(Forms.Context.MainWindow); @@ -289,6 +301,8 @@ namespace Xamarin.Forms.Platform.Tizen { if ((Element as IPageController).InternalChildren.Count == _naviFrame.NavigationStack.Count) { + UpdateNavigationBar(PreviousPage, PreviousNaviItem); + if (nre.Animated) { _naviFrame.Pop(); @@ -301,7 +315,7 @@ namespace Xamarin.Forms.Platform.Tizen CompleteCurrentNavigationTask(); } else - _naviFrame.NavigationStack.Last().Delete(); + CurrentNaviItem?.Delete(); } } @@ -318,6 +332,7 @@ namespace Xamarin.Forms.Platform.Tizen if (topItem != rootItem) { + UpdateNavigationBar(Element.Navigation.NavigationStack.Last(), rootItem); if (nre.Animated) { _naviFrame.Pop(); @@ -369,7 +384,6 @@ namespace Xamarin.Forms.Platform.Tizen tcs.SetResult(true); UpdateHasNavigationBar(nre.Page); - return false; }); } diff --git a/Xamarin.Forms.Platform.Tizen/Renderers/PickerRenderer.cs b/Xamarin.Forms.Platform.Tizen/Renderers/PickerRenderer.cs index 9abd5070..4508ccf1 100644 --- a/Xamarin.Forms.Platform.Tizen/Renderers/PickerRenderer.cs +++ b/Xamarin.Forms.Platform.Tizen/Renderers/PickerRenderer.cs @@ -27,7 +27,6 @@ namespace Xamarin.Forms.Platform.Tizen if (e.OldElement != null) { Control.Clicked -= OnClick; - ((ObservableList<String>)e.OldElement.Items).CollectionChanged -= RowsCollectionChanged; } if (e.NewElement != null) @@ -35,7 +34,6 @@ namespace Xamarin.Forms.Platform.Tizen UpdateSelectedIndex(); Control.Clicked += OnClick; - ((ObservableList<String>)e.NewElement.Items).CollectionChanged += RowsCollectionChanged; } base.OnElementChanged(e); @@ -57,11 +55,6 @@ namespace Xamarin.Forms.Platform.Tizen "" : Element.Items[Element.SelectedIndex]); } - void RowsCollectionChanged(object sender, EventArgs e) - { - UpdateSelectedIndex(); - } - void OnClick(object sender, EventArgs e) { int i = 0; diff --git a/Xamarin.Forms.Platform.Tizen/Renderers/ScrollViewRenderer.cs b/Xamarin.Forms.Platform.Tizen/Renderers/ScrollViewRenderer.cs index a566f24a..11195386 100755 --- a/Xamarin.Forms.Platform.Tizen/Renderers/ScrollViewRenderer.cs +++ b/Xamarin.Forms.Platform.Tizen/Renderers/ScrollViewRenderer.cs @@ -123,7 +123,16 @@ namespace Xamarin.Forms.Platform.Tizen void ScrollRequestHandler(object sender, ScrollToRequestedEventArgs e) { - Rect region = new Rect(ToNativeDimension(e.ScrollX), ToNativeDimension(e.ScrollY), ToNativeDimension(Element.Width), ToNativeDimension(Element.Height)); + var x = e.ScrollX; + var y = e.ScrollY; + if (e.Mode == ScrollToMode.Element) + { + Point itemPosition = (Element as IScrollViewController).GetScrollPositionForElement(e.Element as VisualElement, e.Position); + x = itemPosition.X; + y = itemPosition.Y; + } + + Rect region = new Rect(ToNativeDimension(x), ToNativeDimension(y), ToNativeDimension(Element.Width), ToNativeDimension(Element.Height)); Control.ScrollTo(region, e.ShouldAnimate); } } diff --git a/Xamarin.Forms.Platform.Tizen/Renderers/TabbedPageRenderer.cs b/Xamarin.Forms.Platform.Tizen/Renderers/TabbedPageRenderer.cs index db97b339..2afacfbd 100644 --- a/Xamarin.Forms.Platform.Tizen/Renderers/TabbedPageRenderer.cs +++ b/Xamarin.Forms.Platform.Tizen/Renderers/TabbedPageRenderer.cs @@ -124,19 +124,9 @@ namespace Xamarin.Forms.Platform.Tizen } else { - //elm_toobar style and size hint must be changed at least once before adding the toolbar item having icon. if (!hasIcon) { - int windowHeight = Forms.Context.MainWindow.Geometry.Height; - //This value is from efl-theme-tizen-mobile theme. (NAVIFRAME_TABBAR_HEIGHT_WITH_TITLE_INC 80) - double requiredToolbarHeight = 80.0; - double toolBarWeight = requiredToolbarHeight/windowHeight; _tpage.Style="tabbar"; - _tpage.TransverseExpansion = true; - _tpage.SetAlignment(-1,-1); - _tpage.SetWeight(1, toolBarWeight); - _box.SetAlignment(-1,-1); - _box.SetWeight(1, 1- toolBarWeight); hasIcon = true; } toolbarItem = _tpage.Append(child.Title, ResourcePath.GetPath(child.Icon)); diff --git a/Xamarin.Forms.Platform.Tizen/TizenPlatformServices.cs b/Xamarin.Forms.Platform.Tizen/TizenPlatformServices.cs index 7d442318..db7ee1de 100644 --- a/Xamarin.Forms.Platform.Tizen/TizenPlatformServices.cs +++ b/Xamarin.Forms.Platform.Tizen/TizenPlatformServices.cs @@ -82,14 +82,14 @@ namespace Xamarin.Forms.Platform.Tizen switch (size) { case NamedSize.Micro: - return 16; + return 10; case NamedSize.Small: - return 20; + return 12; case NamedSize.Default: case NamedSize.Medium: - return 24; + return 14; case NamedSize.Large: - return 30; + return 18; default: throw new ArgumentOutOfRangeException(); } diff --git a/Xamarin.Forms.Platform.Tizen/Xamarin.Forms.Platform.Tizen.project.json b/Xamarin.Forms.Platform.Tizen/Xamarin.Forms.Platform.Tizen.project.json index 02b62b96..1e97eea4 100644 --- a/Xamarin.Forms.Platform.Tizen/Xamarin.Forms.Platform.Tizen.project.json +++ b/Xamarin.Forms.Platform.Tizen/Xamarin.Forms.Platform.Tizen.project.json @@ -3,7 +3,8 @@ "ElmSharp": "1.1.0-*", "NETStandard.Library": "1.6.0", "System.Runtime.Serialization.Xml": "4.1.1", - "Tizen.Applications": "1.0.2" + "Tizen.Applications": "1.0.2", + "Tizen.System": "1.0.5" }, "frameworks": { "netstandard1.6": { diff --git a/packaging/xamarin-forms-tizen.spec b/packaging/xamarin-forms-tizen.spec index 074629b1..ca3fca42 100644 --- a/packaging/xamarin-forms-tizen.spec +++ b/packaging/xamarin-forms-tizen.spec @@ -1,16 +1,8 @@ -%{!?dotnet_assembly_path: %define dotnet_assembly_path /opt/usr/share/dotnet.tizen/framework} - -%if 0%{?tizen_build_devel_mode} -%define BUILDCONF Debug -%else -%define BUILDCONF Release -%endif - %define XF_VERSION 2.3.3.175 -#%define XF_PRETAG pre3 +## %define XF_PRETAG pre3 # Increase this XF_TIZEN_VERSION when any public APIs of Xamarin.Forms.Platform.Tizen are changed. -%define XF_TIZEN_VERSION b01 +%define XF_TIZEN_VERSION b02 Name: xamarin-forms-tizen Summary: Xamarin.Forms for Tizen platform @@ -38,35 +30,35 @@ BuildRequires: dotnet-build-tools # C# API Requires BuildRequires: csapi-tizen-nuget BuildRequires: csapi-application-nuget +BuildRequires: csapi-system-nuget BuildRequires: elm-sharp-nuget %description Allows one to use portable controls subsets that are mapped to native controls of Android, iOS, Windows Phone, and Tizen. +%dotnet_import_sub_packages + %prep %setup -q cp %{SOURCE1} . %build # Restore NuGet Dependencies -find . -name *.Tizen.project.json -print0 | xargs -n1 -0 nuget restore +%dotnet_restore Xamarin.Forms.Platform.Tizen +%dotnet_restore Xamarin.Forms.Maps.Tizen # Build -xbuild Xamarin.Forms.Tizen.sln \ - /p:Configuration=%{BUILDCONF} \ - /p:PackageSources=/nuget +%dotnet_build Xamarin.Forms.Tizen.sln /p:PackageSources=/nuget # Create NuGet Packages -nuget pack .nuspec/Xamarin.Forms.Platform.Tizen.nuspec \ - -BasePath ./.nuspec -Version %{NUPKG_VERSION} \ - -Properties "Configuration=%{BUILDCONF}" +%dotnet_pack .nuspec/Xamarin.Forms.Platform.Tizen.nuspec %{NUPKG_VERSION} "-BasePath ./.nuspec" %install function install_asm() { mkdir -p %{buildroot}%{dotnet_assembly_path} - install -p -m 644 $1/bin/%{BUILDCONF}/$1.dll %{buildroot}%{dotnet_assembly_path} + install -p -m 644 $1/bin/%{_dotnet_build_conf}/$1.dll %{buildroot}%{dotnet_assembly_path} } install_asm Xamarin.Forms.Core @@ -80,15 +72,5 @@ install -p -m 644 *.nupkg %{buildroot}/nuget %files %manifest %{name}.manifest %license LICENSE -%attr(644,root,root) %{dotnet_assembly_path}/*.dll - -%package nuget -Summary: NuGet package for %{name} -Group: Development/Libraries -Requires: %{name} = %{version}-%{release} - -%description nuget -NuGet package for %{name} +%attr(644,root,root) %{dotnet_assembly_files} -%files nuget -/nuget/*.nupkg |