From: TizenAPI-Bot Date: Fri, 4 Mar 2022 07:41:07 +0000 (+0000) Subject: Merge remote-tracking branch 'origin/master' into tizen X-Git-Tag: accepted/tizen/unified/20220307.232902~1 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=0a446d39faf1d22f9ea803672342b24f28ea71ec;hp=92067bb24d27ef51b91c1fdf4f935ebec0951b47;p=platform%2Fcore%2Fcsapi%2Ftizenfx.git Merge remote-tracking branch 'origin/master' into tizen --- diff --git a/packaging/csapi-tizenfx.spec b/packaging/csapi-tizenfx.spec index 9a25fcd..1433138 100644 --- a/packaging/csapi-tizenfx.spec +++ b/packaging/csapi-tizenfx.spec @@ -1,8 +1,8 @@ # Auto-generated from csapi-tizenfx.spec.in by makespec.sh %define TIZEN_NET_API_VERSION 10 -%define TIZEN_NET_RPM_VERSION 10.0.0.16997+nui22110 -%define TIZEN_NET_NUGET_VERSION 10.0.0.16997 +%define TIZEN_NET_RPM_VERSION 10.0.0.999+nui22111 +%define TIZEN_NET_NUGET_VERSION 10.0.0.99999 %define DOTNET_ASSEMBLY_PATH /usr/share/dotnet.tizen/framework %define DOTNET_ASSEMBLY_DUMMY_PATH %{DOTNET_ASSEMBLY_PATH}/ref diff --git a/packaging/version.txt b/packaging/version.txt index bcbcc39..f2d0a6a 100755 --- a/packaging/version.txt +++ b/packaging/version.txt @@ -6,4 +6,4 @@ RPM_VERSION=10.0.0.999 NUGET_VERSION=10.0.0.99999 # RPM Version Suffix -RPM_VERSION_SUFFIX=nui22110 +RPM_VERSION_SUFFIX=nui22111 diff --git a/src/Tizen.Applications.Common/Tizen.Applications/CoreApplication.cs b/src/Tizen.Applications.Common/Tizen.Applications/CoreApplication.cs index 364da7c..4cbb737 100644 --- a/src/Tizen.Applications.Common/Tizen.Applications/CoreApplication.cs +++ b/src/Tizen.Applications.Common/Tizen.Applications/CoreApplication.cs @@ -142,9 +142,16 @@ namespace Tizen.Applications /// 3 protected virtual void OnCreate() { - string locale = ULocale.GetDefaultLocale(); - ChangeCurrentUICultureInfo(locale); - ChangeCurrentCultureInfo(locale); + if (!GlobalizationMode.Invariant) + { + string locale = ULocale.GetDefaultLocale(); + ChangeCurrentUICultureInfo(locale); + ChangeCurrentCultureInfo(locale); + } + else + { + Log.Warn(LogTag, "Run in invariant mode"); + } Created?.Invoke(this, EventArgs.Empty); } @@ -213,7 +220,11 @@ namespace Tizen.Applications /// 3 protected virtual void OnLocaleChanged(LocaleChangedEventArgs e) { - ChangeCurrentUICultureInfo(e.Locale); + if (!GlobalizationMode.Invariant) + { + ChangeCurrentUICultureInfo(e.Locale); + } + LocaleChanged?.Invoke(this, e); } @@ -225,7 +236,11 @@ namespace Tizen.Applications /// 3 protected virtual void OnRegionFormatChanged(RegionFormatChangedEventArgs e) { - ChangeCurrentCultureInfo(e.Region); + if (!GlobalizationMode.Invariant) + { + ChangeCurrentCultureInfo(e.Region); + } + RegionFormatChanged?.Invoke(this, e); } @@ -397,6 +412,25 @@ namespace Tizen.Applications } } + internal static class GlobalizationMode + { + private static int _invariant = -1; + + internal static bool Invariant + { + get + { + if (_invariant == -1) + { + string value = Environment.GetEnvironmentVariable("DOTNET_SYSTEM_GLOBALIZATION_INVARIANT"); + _invariant = value != null ? (value.Equals("1") ? 1 : 0) : 0; + } + + return _invariant != 0; + } + } + } + internal class ULocale { private const int ULOC_FULLNAME_CAPACITY = 157; diff --git a/src/Tizen.Applications.Common/Tizen.Applications/CultureInfoHelper.cs b/src/Tizen.Applications.Common/Tizen.Applications/CultureInfoHelper.cs index 15ec3f8..3b92796 100755 --- a/src/Tizen.Applications.Common/Tizen.Applications/CultureInfoHelper.cs +++ b/src/Tizen.Applications.Common/Tizen.Applications/CultureInfoHelper.cs @@ -30,7 +30,6 @@ namespace Tizen.Applications private static readonly Dictionary _cultureNames = new Dictionary(); private static readonly object _lock = new object(); private const string _pathCultureInfoXml = "/usr/share/dotnet.tizen/framework/i18n/CultureInfo.xml"; - private static readonly CultureInfo _cultureInfo = new CultureInfo("en-US"); public static void Initialize() { @@ -86,7 +85,7 @@ namespace Tizen.Applications Initialize(); } - if (_cultureNames.TryGetValue(locale.ToLower(_cultureInfo), out string cultureName)) + if (_cultureNames.TryGetValue(locale.ToLowerInvariant(), out string cultureName)) { return cultureName; } diff --git a/src/Tizen.NUI.Components/Controls/Navigation/Navigator.cs b/src/Tizen.NUI.Components/Controls/Navigation/Navigator.cs index 94ca551..a60dc14 100755 --- a/src/Tizen.NUI.Components/Controls/Navigation/Navigator.cs +++ b/src/Tizen.NUI.Components/Controls/Navigation/Navigator.cs @@ -860,7 +860,7 @@ namespace Tizen.NUI.Components disappearedPage.UnregisterDefaultLabel(); //We can call disappearedPage.NotifyAccessibilityStatesChange //To reduce accessibility events, we are using currently highlighted view instead - View curHighlightedView = Accessibility.Accessibility.Instance.GetCurrentlyHighlightedView(); + View curHighlightedView = Accessibility.Accessibility.GetCurrentlyHighlightedView(); if (curHighlightedView != null) { curHighlightedView.NotifyAccessibilityStatesChange(new AccessibilityStates(AccessibilityState.Visible, AccessibilityState.Showing), AccessibilityStatesNotifyMode.Single); diff --git a/src/Tizen.NUI.Components/Controls/Picker.cs b/src/Tizen.NUI.Components/Controls/Picker.cs index 70eaf90..1bcf1a0 100755 --- a/src/Tizen.NUI.Components/Controls/Picker.cs +++ b/src/Tizen.NUI.Components/Controls/Picker.cs @@ -520,7 +520,11 @@ namespace Tizen.NUI.Components if (loopEnabled) startY = ((dummyItemsForLoop + startItemIdx) * itemHeight) + startScrollOffset; // + 2 for non loop picker center align - else startY = ((2 + startItemIdx) * itemHeight) + startScrollOffset; + else + { + startY = ((2 + startItemIdx) * itemHeight) + startScrollOffset; + currentValue = currentValue - minValue + 2; + } pickerScroller.ScrollTo(startY, false); } diff --git a/src/Tizen.NUI.Components/Controls/RecyclerView/CollectionView.cs b/src/Tizen.NUI.Components/Controls/RecyclerView/CollectionView.cs index e48b598..f8e8469 100755 --- a/src/Tizen.NUI.Components/Controls/RecyclerView/CollectionView.cs +++ b/src/Tizen.NUI.Components/Controls/RecyclerView/CollectionView.cs @@ -845,6 +845,15 @@ namespace Tizen.NUI.Components } } + /// + /// Initialize AT-SPI object. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + public override void OnInitialize() + { + base.OnInitialize(); + SetAccessibilityConstructor(Role.List); + } /// /// Scroll to specified item diff --git a/src/Tizen.NUI.Components/Controls/RecyclerView/Item/DefaultLinearItem.cs b/src/Tizen.NUI.Components/Controls/RecyclerView/Item/DefaultLinearItem.cs index 84e5aa9..1b7c77f 100755 --- a/src/Tizen.NUI.Components/Controls/RecyclerView/Item/DefaultLinearItem.cs +++ b/src/Tizen.NUI.Components/Controls/RecyclerView/Item/DefaultLinearItem.cs @@ -150,8 +150,6 @@ namespace Tizen.NUI.Components layoutChanged = true; Add(itemLabel); } - itemLabel.AppendAccessibilityRelation(this, AccessibilityRelationType.ControlledBy); - this.AppendAccessibilityRelation(itemLabel, AccessibilityRelationType.LabelledBy); } return itemLabel; } @@ -305,7 +303,8 @@ namespace Tizen.NUI.Components //need to consider horizontal/vertical! WidthSpecification = LayoutParamPolicies.MatchParent, HeightSpecification = 2, - ExcludeLayouting = true + ExcludeLayouting = true, + AccessibilityHidden = true }; layoutChanged = true; Add(itemSeperator); @@ -361,6 +360,15 @@ namespace Tizen.NUI.Components } /// + /// Get accessibility name. + /// + [EditorBrowsable(EditorBrowsableState.Never)] + protected override string AccessibilityGetName() + { + return Label.Text + ", " + SubLabel.Text; + } + + /// /// Creates Item's text part. /// /// The created Item's text part. @@ -370,7 +378,8 @@ namespace Tizen.NUI.Components return new TextLabel(style) { HorizontalAlignment = HorizontalAlignment.Begin, - VerticalAlignment = VerticalAlignment.Center + VerticalAlignment = VerticalAlignment.Center, + AccessibilityHidden = true }; } diff --git a/src/Tizen.NUI.Components/Controls/TimePicker.cs b/src/Tizen.NUI.Components/Controls/TimePicker.cs index 67f60d6..101961f 100755 --- a/src/Tizen.NUI.Components/Controls/TimePicker.cs +++ b/src/Tizen.NUI.Components/Controls/TimePicker.cs @@ -197,7 +197,8 @@ namespace Tizen.NUI.Components else { isAm = true; - hourPicker.CurrentValue = currentTime.Hour; + if (currentTime.Hour == 0) hourPicker.CurrentValue = 12; + else hourPicker.CurrentValue = currentTime.Hour; ampmPicker.CurrentValue = 1; } } @@ -288,14 +289,16 @@ namespace Tizen.NUI.Components ampmPicker.ValueChanged += OnAmpmValueChanged; currentTime = DateTime.Now; - Console.WriteLine(" Time " + currentTime.Hour + " " + currentTime.Minute); if (currentTime.Hour > 12) { ampmPicker.CurrentValue = 2; hourPicker.CurrentValue = currentTime.Hour - 12; } else + { + ampmPicker.CurrentValue = 1; hourPicker.CurrentValue = currentTime.Hour; + } minutePicker.CurrentValue = currentTime.Minute; @@ -362,12 +365,12 @@ namespace Tizen.NUI.Components { if (isAm) { - if (e.Value == 12) ChangeTime(12, 0, true); + if (e.Value == 12) ChangeTime(0, 0, true); else ChangeTime(e.Value, 0, true); } else { - if (e.Value == 12) ChangeTime(0, 0, true); + if (e.Value == 12) ChangeTime(12, 0, true); else ChangeTime(e.Value + 12, 0, true); } } @@ -392,20 +395,16 @@ namespace Tizen.NUI.Components if (e.Value == 1) { //AM - if (currentTime.Hour > 12 || currentTime.Hour == 0) - { - if (currentTime.Hour == 0) ChangeTime(12, 0, true); - else ChangeTime(currentTime.Hour - 12, 0, true); - } + if (currentTime.Hour == 12) ChangeTime(0, 0, true); + else ChangeTime(currentTime.Hour - 12, 0, true); + isAm = true; } else { //PM - if (currentTime.Hour > 0 && currentTime.Hour <= 12) - { - if (currentTime.Hour == 12) ChangeTime(0, 0, true); - else ChangeTime(currentTime.Hour + 12, 0, true); - } + if (currentTime.Hour == 0) ChangeTime(12, 0, true); + else ChangeTime(currentTime.Hour + 12, 0, true); + isAm = false; } diff --git a/src/Tizen.NUI/src/internal/Application/Application.cs b/src/Tizen.NUI/src/internal/Application/Application.cs index ac87ddc..73430e0 100755 --- a/src/Tizen.NUI/src/internal/Application/Application.cs +++ b/src/Tizen.NUI/src/internal/Application/Application.cs @@ -1,5 +1,5 @@ /* - * Copyright(c) 2021 Samsung Electronics Co., Ltd. + * Copyright(c) 2022 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -308,12 +308,9 @@ namespace Tizen.NUI public delegate void resChangeCb(object sender, ResourcesChangedEventArgs e); - internal event EventHandler XamlResourceChanged; - internal override void OnResourcesChanged(object sender, ResourcesChangedEventArgs e) { base.OnResourcesChanged(sender, e); - XamlResourceChanged?.Invoke(sender, e); } public ResourceDictionary XamlResources @@ -358,6 +355,9 @@ namespace Tizen.NUI internal override void OnParentResourcesChanged(IEnumerable> values) { + if (values == null) + return; + if (!((IResourcesProvider)this).IsResourcesCreated || XamlResources.Count == 0) { base.OnParentResourcesChanged(values); @@ -373,7 +373,8 @@ namespace Tizen.NUI if (innerKeys.Add(value.Key)) changedResources.Add(value); } - OnResourcesChanged(changedResources); + if (changedResources.Count != 0) + OnResourcesChanged(changedResources); } internal Application(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn) diff --git a/src/Tizen.NUI/src/internal/EXaml/Operation/GatherProperty.cs b/src/Tizen.NUI/src/internal/EXaml/Operation/GatherProperty.cs index 039e2e1..215e782 100755 --- a/src/Tizen.NUI/src/internal/EXaml/Operation/GatherProperty.cs +++ b/src/Tizen.NUI/src/internal/EXaml/Operation/GatherProperty.cs @@ -38,7 +38,23 @@ namespace Tizen.NUI.EXaml public void Do() { var type = globalDataList.GatheredTypes[typeIndex]; - globalDataList.GatheredProperties.Add(type.GetProperty(propertyName)); + PropertyInfo propertyInfo = null; + try + { + propertyInfo = type.GetProperty(propertyName); + } +#pragma warning disable CA1031 // Do not catch general exception types + catch (Exception) +#pragma warning restore CA1031 // Do not catch general exception types + { + propertyInfo = type.GetProperty(propertyName, BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance); + } + + if (null == propertyInfo) + { + throw new Exception($"Can't find property {propertyName} from type {type.FullName}"); + } + globalDataList.GatheredProperties.Add(propertyInfo); } private int typeIndex; diff --git a/src/Tizen.NUI/src/internal/Interop/Interop.Accessibility.cs b/src/Tizen.NUI/src/internal/Interop/Interop.Accessibility.cs index 9311088..e45066c 100755 --- a/src/Tizen.NUI/src/internal/Interop/Interop.Accessibility.cs +++ b/src/Tizen.NUI/src/internal/Interop/Interop.Accessibility.cs @@ -24,23 +24,19 @@ namespace Tizen.NUI { internal static partial class Accessibility { - [DllImport(NDalicPINVOKE.Lib, EntryPoint = "csharp_dali_accessibility_get_status")] - [return: MarshalAs(UnmanagedType.U1)] - public static extern bool GetStatus(HandleRef jarg1); - [DllImport(NDalicPINVOKE.Lib, EntryPoint = "csharp_dali_accessibility_say")] [return: MarshalAs(UnmanagedType.U1)] - public static extern bool Say(HandleRef jarg1, string jarg2, bool jarg3, IntPtr jarg4); + public static extern bool Say(string jarg1, bool jarg2, IntPtr jarg3); [DllImport(NDalicPINVOKE.Lib, EntryPoint = "csharp_dali_accessibility_pause_resume")] - public static extern void PauseResume(HandleRef jarg1, bool jarg2); + public static extern void PauseResume(bool jarg1); [DllImport(NDalicPINVOKE.Lib, EntryPoint = "csharp_dali_accessibility_stop_reading")] - public static extern void StopReading(HandleRef jarg1, bool jarg2); + public static extern void StopReading(bool jarg1); [DllImport(NDalicPINVOKE.Lib, EntryPoint = "csharp_dali_accessibility_suppress_screen_reader")] [return: MarshalAs(UnmanagedType.U1)] - public static extern bool SuppressScreenReader(HandleRef jarg1, bool jarg2); + public static extern bool SuppressScreenReader(bool jarg1); [DllImport(NDalicPINVOKE.Lib, EntryPoint = "csharp_dali_accessibility_BridgeEnableAutoInit")] public static extern void BridgeEnableAutoInit(); diff --git a/src/Tizen.NUI/src/internal/Interop/Interop.ControlDevel.cs b/src/Tizen.NUI/src/internal/Interop/Interop.ControlDevel.cs index 5ddeac6..29499c5 100755 --- a/src/Tizen.NUI/src/internal/Interop/Interop.ControlDevel.cs +++ b/src/Tizen.NUI/src/internal/Interop/Interop.ControlDevel.cs @@ -384,10 +384,15 @@ namespace Tizen.NUI public delegate bool AccessibilityDeselectChild(IntPtr self, int childIndex); [EditorBrowsable(EditorBrowsableState.Never)] public AccessibilityDeselectChild DeselectChild; // 35 + + [UnmanagedFunctionPointer(CallingConvention.Cdecl)] + public delegate uint AccessibilityGetInterfaces(IntPtr self); + [EditorBrowsable(EditorBrowsableState.Never)] + public AccessibilityGetInterfaces GetInterfaces; // 36 } [DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Toolkit_DevelControl_SetAccessibilityConstructor_NUI")] - public static extern void DaliToolkitDevelControlSetAccessibilityConstructor(HandleRef arg1_self, int arg2_role, int arg3_iface); + public static extern void DaliToolkitDevelControlSetAccessibilityConstructor(HandleRef arg1_self, int arg2_role); [DllImport(NDalicPINVOKE.Lib, EntryPoint = "CSharp_Dali_Accessibility_DuplicateString")] public static extern IntPtr DaliAccessibilityDuplicateString(string arg); diff --git a/src/Tizen.NUI/src/internal/Xaml/ApplyPropertiesVisitor.cs b/src/Tizen.NUI/src/internal/Xaml/ApplyPropertiesVisitor.cs index 0ca6d91..e1af6ff 100755 --- a/src/Tizen.NUI/src/internal/Xaml/ApplyPropertiesVisitor.cs +++ b/src/Tizen.NUI/src/internal/Xaml/ApplyPropertiesVisitor.cs @@ -1,5 +1,5 @@ /* - * Copyright(c) 2021 Samsung Electronics Co., Ltd. + * Copyright(c) 2022 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -53,13 +53,14 @@ namespace Tizen.NUI.Xaml public bool StopOnResourceDictionary { get; } public bool VisitNodeOnDataTemplate => true; public bool SkipChildren(INode node, INode parentNode) => false; - public bool IsResourceDictionary(ElementNode node) => typeof(ResourceDictionary).IsAssignableFrom(Context.Types[node]); + public bool IsResourceDictionary(ElementNode node) => Context.Types.TryGetValue(node, out var type) && typeof(ResourceDictionary).IsAssignableFrom(type); public void Visit(ValueNode node, INode parentNode) { var parentElement = parentNode as IElementNode; var value = Values[node]; - var source = Values[parentNode]; + if (!Values.TryGetValue(parentNode, out var source) && Context.ExceptionHandler != null) + return; XmlName propertyName; if (TryGetPropertyName(node, parentNode, out propertyName)) @@ -119,7 +120,8 @@ namespace Tizen.NUI.Xaml parentElement = parentNode as IElementNode; } - var value = Values[node]; + if (!Values.TryGetValue(node, out var value) && Context.ExceptionHandler != null) + return; if (propertyName != XmlName.Empty || TryGetPropertyName(node, parentNode, out propertyName)) { @@ -130,13 +132,15 @@ namespace Tizen.NUI.Xaml if (parentElement.SkipProperties.Contains(propertyName)) return; - var source = Values[parentNode]; + if (!Values.TryGetValue(parentNode, out var source) && Context.ExceptionHandler != null) + return; ProvideValue(ref value, node, source, propertyName); SetPropertyValue(source, propertyName, value, Context.RootElement, node, Context, node); } else if (IsCollectionItem(node, parentNode) && parentNode is IElementNode) { - var source = Values[parentNode]; + if (!Values.TryGetValue(parentNode, out var source) && Context.ExceptionHandler != null) + return; ProvideValue(ref value, node, source, XmlName.Empty); string contentProperty; Exception xpe = null; @@ -189,11 +193,13 @@ namespace Tizen.NUI.Xaml xpe = xpe ?? new XamlParseException($"Can not set the content of {((IElementNode)parentNode).XmlType.Name} as it doesn't have a ContentPropertyAttribute", node); if (Context.ExceptionHandler != null) Context.ExceptionHandler(xpe); - throw xpe; + else + throw xpe; } else if (IsCollectionItem(node, parentNode) && parentNode is ListNode) { - var source = Values[parentNode.Parent]; + if (!Values.TryGetValue(parentNode.Parent, out var source) && Context.ExceptionHandler != null) + return; ProvideValue(ref value, node, source, XmlName.Empty); var parentList = (ListNode)parentNode; if (Skips.Contains(parentList.XmlName)) @@ -285,11 +291,17 @@ namespace Tizen.NUI.Xaml { (serviceProvider.IProvideValueTarget as XamlValueTargetProvider).TargetProperty = GetTargetProperty(source, propertyName, Context, node); } - - if (markupExtension != null) - value = markupExtension.ProvideValue(serviceProvider); - else if (valueProvider != null) - value = valueProvider.ProvideValue(serviceProvider); + try { + if (markupExtension != null) + value = markupExtension.ProvideValue(serviceProvider); + else if (valueProvider != null) + value = valueProvider.ProvideValue(serviceProvider); + } catch (Exception e) { + if (Context.ExceptionHandler != null) + Context.ExceptionHandler(e); + else + throw; + } } static string GetContentPropertyName(IEnumerable attributes) @@ -722,6 +734,8 @@ namespace Tizen.NUI.Xaml if (xKey != null) resourceDictionary.Add(xKey, value); + else if (value is XamlStyle) + resourceDictionary.Add((XamlStyle)value); else if (value is ResourceDictionary) resourceDictionary.Add((ResourceDictionary)value); else diff --git a/src/Tizen.NUI/src/internal/Xaml/CreateValuesVisitor.cs b/src/Tizen.NUI/src/internal/Xaml/CreateValuesVisitor.cs index 499f12d..97462a7 100755 --- a/src/Tizen.NUI/src/internal/Xaml/CreateValuesVisitor.cs +++ b/src/Tizen.NUI/src/internal/Xaml/CreateValuesVisitor.cs @@ -1,5 +1,5 @@ /* - * Copyright(c) 2021 Samsung Electronics Co., Ltd. + * Copyright(c) 2022 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -161,11 +161,6 @@ namespace Tizen.NUI.Xaml } if (value is Element element) { - if (null != Application.Current) - { - Application.Current.XamlResourceChanged += element.OnResourcesChanged; - } - element.IsCreateByXaml = true; element.LineNumber = node.LineNumber; element.LinePosition = node.LinePosition; @@ -288,11 +283,6 @@ namespace Tizen.NUI.Xaml object ret = Activator.CreateInstance(nodeType, BindingFlags.CreateInstance | BindingFlags.Public | BindingFlags.Instance | BindingFlags.OptionalParamBinding, null, arguments, CultureInfo.CurrentCulture); if (ret is Element element) { - if (null != Application.Current) - { - Application.Current.XamlResourceChanged += element.OnResourcesChanged; - } - element.IsCreateByXaml = true; element.LineNumber = (node as ElementNode)?.LineNumber ?? -1; element.LinePosition = (node as ElementNode)?.LinePosition ?? -1; @@ -430,11 +420,6 @@ namespace Tizen.NUI.Xaml value = Activator.CreateInstance(nodeType); if (value is Element element) { - if (null != Application.Current) - { - Application.Current.XamlResourceChanged += element.OnResourcesChanged; - } - element.IsCreateByXaml = true; element.LineNumber = (node as ElementNode)?.LineNumber ?? -1; element.LinePosition = (node as ElementNode)?.LinePosition ?? -1; diff --git a/src/Tizen.NUI/src/internal/Xaml/FillResourceDictionariesVisitor.cs b/src/Tizen.NUI/src/internal/Xaml/FillResourceDictionariesVisitor.cs index 2b8abe8..eeae4f2 100755 --- a/src/Tizen.NUI/src/internal/Xaml/FillResourceDictionariesVisitor.cs +++ b/src/Tizen.NUI/src/internal/Xaml/FillResourceDictionariesVisitor.cs @@ -1,5 +1,5 @@ /* - * Copyright(c) 2021 Samsung Electronics Co., Ltd. + * Copyright(c) 2022 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -42,7 +42,7 @@ namespace Tizen.NUI.Xaml public void Visit(ValueNode node, INode parentNode) { - if (!typeof(ResourceDictionary).IsAssignableFrom(Context.Types[((IElementNode)parentNode)])) + if (!Context.Types.TryGetValue((IElementNode)parentNode, out var type) || !typeof(ResourceDictionary).IsAssignableFrom(type)) return; node.Accept(new ApplyPropertiesVisitor(Context, stopOnResourceDictionary: false), parentNode); @@ -54,13 +54,14 @@ namespace Tizen.NUI.Xaml public void Visit(ElementNode node, INode parentNode) { - var value = Values[node]; + if (!Values.TryGetValue(node, out var value) && Context.ExceptionHandler != null) + return; XmlName propertyName; //Set RD to VE if (typeof(ResourceDictionary).IsAssignableFrom(Context.Types[node]) && ApplyPropertiesVisitor.TryGetPropertyName(node, parentNode, out propertyName)) { - if ((propertyName.LocalName == "Resources" || - propertyName.LocalName.EndsWith(".Resources", StringComparison.Ordinal)) && value is ResourceDictionary) + if ((propertyName.LocalName == "XamlResources" || + propertyName.LocalName.EndsWith(".XamlResources", StringComparison.Ordinal)) && value is ResourceDictionary) { var source = Values[parentNode]; ApplyPropertiesVisitor.SetPropertyValue(source, propertyName, value, Context.RootElement, node, Context, node); @@ -70,7 +71,8 @@ namespace Tizen.NUI.Xaml //Only proceed further if the node is a keyless RD if (parentNode is IElementNode - && typeof(ResourceDictionary).IsAssignableFrom(Context.Types[((IElementNode)parentNode)]) + && Context.Types.TryGetValue((IElementNode)parentNode, out var parentType) + && typeof(ResourceDictionary).IsAssignableFrom(parentType) && !((IElementNode)parentNode).Properties.ContainsKey(XmlName.xKey)) node.Accept(new ApplyPropertiesVisitor(Context, stopOnResourceDictionary: false), parentNode); else if (parentNode is ListNode @@ -93,7 +95,8 @@ namespace Tizen.NUI.Xaml if (enode is null) return false; if (parentNode is IElementNode - && typeof(ResourceDictionary).IsAssignableFrom(Context.Types[((IElementNode)parentNode)]) + && Context.Types.TryGetValue((IElementNode)parentNode, out var parentType) + && typeof(ResourceDictionary).IsAssignableFrom(parentType) && !((IElementNode)parentNode).Properties.ContainsKey(XmlName.xKey)) return true; if (parentNode is ListNode diff --git a/src/Tizen.NUI/src/internal/Xaml/IResourcesLoader.cs b/src/Tizen.NUI/src/internal/Xaml/IResourcesLoader.cs index 8ea6349..732f23d 100755 --- a/src/Tizen.NUI/src/internal/Xaml/IResourcesLoader.cs +++ b/src/Tizen.NUI/src/internal/Xaml/IResourcesLoader.cs @@ -1,5 +1,5 @@ -/* - * Copyright(c) 2021 Samsung Electronics Co., Ltd. +/* + * Copyright(c) 2022 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,6 +25,6 @@ namespace Tizen.NUI internal interface IResourcesLoader { T CreateFromResource(string resourcePath, Assembly assembly, IXmlLineInfo lineInfo) where T : new(); - string GetResource(string resourcePath, Assembly assembly, IXmlLineInfo lineInfo); + string GetResource(string resourcePath, Assembly assembly, object target, IXmlLineInfo lineInfo); } } diff --git a/src/Tizen.NUI/src/internal/Xaml/ResourcesLoader.cs b/src/Tizen.NUI/src/internal/Xaml/ResourcesLoader.cs index 14cd470..433743f 100755 --- a/src/Tizen.NUI/src/internal/Xaml/ResourcesLoader.cs +++ b/src/Tizen.NUI/src/internal/Xaml/ResourcesLoader.cs @@ -1,5 +1,5 @@ -/* - * Copyright(c) 2021 Samsung Electronics Co., Ltd. +/* + * Copyright(c) 2022 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -28,10 +28,16 @@ namespace Tizen.NUI.Xaml { public T CreateFromResource(string resourcePath, Assembly assembly, IXmlLineInfo lineInfo) where T : new() { - var alternateResource = ResourceLoader.ResourceProvider?.Invoke(assembly.GetName(), resourcePath); + var rd = new T(); + var resourceLoadingResponse = ResourceLoader.ResourceProvider?.Invoke(new ResourceLoader.ResourceLoadingQuery + { + AssemblyName = assembly.GetName(), + ResourcePath = resourcePath, + Instance = rd + }); + var alternateResource = resourceLoadingResponse?.ResourceContent; if (alternateResource != null) { - var rd = new T(); rd.LoadFromXaml(alternateResource); return rd; } @@ -46,16 +52,20 @@ namespace Tizen.NUI.Xaml throw new XamlParseException($"No resource found for '{resourceId}'.", lineInfo); using (var reader = new StreamReader(stream)) { - var rd = new T(); rd.LoadFromXaml(reader.ReadToEnd()); return rd; } } } - public string GetResource(string resourcePath, Assembly assembly, IXmlLineInfo lineInfo) + public string GetResource(string resourcePath, Assembly assembly, object target, IXmlLineInfo lineInfo) { - var alternateResource = ResourceLoader.ResourceProvider?.Invoke(assembly.GetName(), resourcePath); + var resourceLoadingResponse = ResourceLoader.ResourceProvider?.Invoke(new ResourceLoader.ResourceLoadingQuery { + AssemblyName = assembly.GetName(), + ResourcePath = resourcePath, + Instance = target + }); + var alternateResource = resourceLoadingResponse?.ResourceContent; if (alternateResource != null) return alternateResource; diff --git a/src/Tizen.NUI/src/internal/Xaml/XamlLoader.cs b/src/Tizen.NUI/src/internal/Xaml/XamlLoader.cs index e3b803e..55edd7d 100755 --- a/src/Tizen.NUI/src/internal/Xaml/XamlLoader.cs +++ b/src/Tizen.NUI/src/internal/Xaml/XamlLoader.cs @@ -1,5 +1,5 @@ /* - * Copyright(c) 2021 Samsung Electronics Co., Ltd. + * Copyright(c) 2022 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -130,11 +130,13 @@ namespace Tizen.NUI.Xaml var rootnode = new RuntimeRootNode(new XmlType(reader.NamespaceURI, reader.Name, null), ret, (IXmlNamespaceResolver)reader); XamlParser.ParseXaml(rootnode, reader); + var doNotThrow = ResourceLoader.ExceptionHandler != null || Internals.XamlLoader.DoNotThrowOnExceptions; + void ehandler(Exception e) => ResourceLoader.ExceptionHandler?.Invoke((e, path)); Visit(rootnode, new HydrationContext { RootElement = ret, #pragma warning disable 0618 - ExceptionHandler = ResourceLoader.ExceptionHandler ?? (Internals.XamlLoader.DoNotThrowOnExceptions ? e => { } : (Action)null) + ExceptionHandler = doNotThrow ? ehandler : (Action)null #pragma warning restore 0618 }); break; @@ -178,11 +180,13 @@ namespace Tizen.NUI.Xaml var rootnode = new RuntimeRootNode(new XmlType(reader.NamespaceURI, reader.Name, null), view, (IXmlNamespaceResolver)reader); XamlParser.ParseXaml(rootnode, reader); + var doNotThrow = ResourceLoader.ExceptionHandler != null || Internals.XamlLoader.DoNotThrowOnExceptions; + void ehandler(Exception e) => ResourceLoader.ExceptionHandler?.Invoke((e, XamlFilePathAttribute.GetFilePathForObject(view))); Visit(rootnode, new HydrationContext { RootElement = view, #pragma warning disable 0618 - ExceptionHandler = ResourceLoader.ExceptionHandler ?? (Internals.XamlLoader.DoNotThrowOnExceptions ? e => { } : (Action)null) + ExceptionHandler = doNotThrow ? ehandler : (Action)null #pragma warning restore 0618 }); break; diff --git a/src/Tizen.NUI/src/internal/XamlBinding/Internals/ResourceLoader.cs b/src/Tizen.NUI/src/internal/XamlBinding/Internals/ResourceLoader.cs index 7c20e06..3910c7e 100755 --- a/src/Tizen.NUI/src/internal/XamlBinding/Internals/ResourceLoader.cs +++ b/src/Tizen.NUI/src/internal/XamlBinding/Internals/ResourceLoader.cs @@ -1,5 +1,5 @@ -/* - * Copyright(c) 2021 Samsung Electronics Co., Ltd. +/* + * Copyright(c) 2022 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,29 +23,39 @@ namespace Tizen.NUI.Binding.Internals { internal static class ResourceLoader { - static Func resourceProvider = (asmName, path) => - { - if (typeof(Theme).Assembly.GetName().FullName != asmName.FullName) + static Func _resourceProvider = (resourceLoadingQuery) => { + if (typeof(Theme).Assembly.GetName().FullName != resourceLoadingQuery.AssemblyName.FullName) { string resource = Tizen.Applications.Application.Current.DirectoryInfo.Resource; - path = resource + path; + resourceLoadingQuery.ResourcePath = resource + resourceLoadingQuery.ResourcePath; } - string ret = File.ReadAllText(path); - return ret; + string ret = File.ReadAllText(resourceLoadingQuery.ResourcePath); + return new ResourceLoadingResponse { ResourceContent = ret }; }; - - //takes a resource path, returns string content - public static Func ResourceProvider + public static Func ResourceProvider { - get => resourceProvider; + get => _resourceProvider; internal set { - DesignMode.IsDesignModeEnabled = true; - resourceProvider = value; + DesignMode.IsDesignModeEnabled = value != null; + _resourceProvider = value; } } - internal static Action ExceptionHandler { get; set; } + internal static Action<(Exception exception, string filepath)> ExceptionHandler { get; set; } + + public class ResourceLoadingQuery + { + public AssemblyName AssemblyName { get; set; } + public string ResourcePath { get; set; } + public object Instance { get; set; } + } + + public class ResourceLoadingResponse + { + public string ResourceContent { get; set; } + public bool UseDesignProperties { get; set; } + } } } diff --git a/src/Tizen.NUI/src/internal/XamlBinding/MergedStyle.cs b/src/Tizen.NUI/src/internal/XamlBinding/MergedStyle.cs index ebf6439..22572f1 100755 --- a/src/Tizen.NUI/src/internal/XamlBinding/MergedStyle.cs +++ b/src/Tizen.NUI/src/internal/XamlBinding/MergedStyle.cs @@ -36,7 +36,14 @@ namespace Tizen.NUI.Binding public IStyle Style { get { return style; } - set { SetStyle(ImplicitStyle, ClassStyles, value); } + set + { + if (style == value) + return; + if (value != null && !value.TargetType.IsAssignableFrom(TargetType)) + NUILog.Error($"Style TargetType {value.TargetType.FullName} is not compatible with element target type {TargetType}"); + SetStyle(ImplicitStyle, ClassStyles, value); + } } public IList StyleClass @@ -47,7 +54,7 @@ namespace Tizen.NUI.Binding if (styleClass == value) return; - if (styleClass != null && classStyles != null) + if (styleClass != null && classStyleProperties != null) foreach (var classStyleProperty in classStyleProperties) Target.RemoveDynamicResource(classStyleProperty); diff --git a/src/Tizen.NUI/src/internal/XamlBinding/ResourcesExtensions.cs b/src/Tizen.NUI/src/internal/XamlBinding/ResourcesExtensions.cs index b0ccc27..ad6e6ea 100755 --- a/src/Tizen.NUI/src/internal/XamlBinding/ResourcesExtensions.cs +++ b/src/Tizen.NUI/src/internal/XamlBinding/ResourcesExtensions.cs @@ -1,5 +1,5 @@ /* - * Copyright(c) 2021 Samsung Electronics Co., Ltd. + * Copyright(c) 2022 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -39,8 +39,13 @@ namespace Tizen.NUI.Binding if (ve.XamlResources != null) { foreach (KeyValuePair res in ve.XamlResources.MergedResources) - if (!resources.ContainsKey(res.Key)) - resources.Add(res.Key, res.Value); + { + // If a MergedDictionary value is overridden for a DynamicResource, + // it comes out later in the enumeration of MergedResources + // TryGetValue ensures we pull the up-to-date value for the key + if (!resources.ContainsKey(res.Key) && ve.XamlResources.TryGetValue(res.Key, out object value)) + resources.Add(res.Key, value); + } } } diff --git a/src/Tizen.NUI/src/public/Accessibility/Accessibility.cs b/src/Tizen.NUI/src/public/Accessibility/Accessibility.cs index 054cc9b..90eb52d 100755 --- a/src/Tizen.NUI/src/public/Accessibility/Accessibility.cs +++ b/src/Tizen.NUI/src/public/Accessibility/Accessibility.cs @@ -30,15 +30,10 @@ namespace Tizen.NUI.Accessibility [SuppressMessage("Microsoft.Design", "CA1724: Type names should not match namespaces")] [SuppressMessage("Microsoft.Design", "CA1001:Types that own disposable fields should be disposable", Justification = "This is a singleton class and is not disposed")] [EditorBrowsable(EditorBrowsableState.Never)] - public class Accessibility + public static class Accessibility { - #region Constructor, Destructor, Dispose - private Accessibility() - { - dummy = new View(); - dummy.Name = "dali-atspi-singleton"; - } - + #region Constructor + [SuppressMessage("Microsoft.Performance", "CA1810: Initialize reference type static fields inline", Justification = "Need to call native code")] static Accessibility() { enabledSignalHandler = () => @@ -53,31 +48,10 @@ namespace Tizen.NUI.Accessibility Interop.Accessibility.RegisterEnabledDisabledSignalHandler(enabledSignalHandler, disabledSignalHandler); } - - /// - /// destructor. This is HiddenAPI. recommended not to use in public. - /// - ~Accessibility() - { - Interop.Accessibility.RegisterEnabledDisabledSignalHandler(null, null); - - Tizen.Log.Debug("NUI", $"Accessibility is destroyed\n"); - } - #endregion Constructor, Destructor, Dispose - + #endregion Constructor #region Property /// - /// Instance for singleton - /// - // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API) - [EditorBrowsable(EditorBrowsableState.Never)] - public static Accessibility Instance - { - get => accessibility; - } - - /// /// Flag to check whether the state of Accessibility is enabled or not. /// /// @@ -95,20 +69,8 @@ namespace Tizen.NUI.Accessibility #endregion Property - #region Method /// - /// Get the current status - /// - /// Current enabled status - // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API) - [EditorBrowsable(EditorBrowsableState.Never)] - static public bool GetStatus() - { - return true; - } - - /// /// Start to speak /// /// Content to be spoken @@ -116,15 +78,10 @@ namespace Tizen.NUI.Accessibility /// // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API) [EditorBrowsable(EditorBrowsableState.Never)] - public bool Say(string sentence, bool discardable) + public static bool Say(string sentence, bool discardable) { - IntPtr callbackIntPtr = IntPtr.Zero; - if (sayFinishedEventHandler != null) - { - callback = SayFinishedEventCallback; - callbackIntPtr = Marshal.GetFunctionPointerForDelegate(callback); - } - bool ret = Interop.Accessibility.Say(View.getCPtr(dummy), sentence, discardable, callbackIntPtr); + bool ret = Interop.Accessibility.Say(sentence, discardable, Marshal.GetFunctionPointerForDelegate(callback)); + if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); return ret; } @@ -135,9 +92,9 @@ namespace Tizen.NUI.Accessibility /// true to be paused, false to be resumed // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API) [EditorBrowsable(EditorBrowsableState.Never)] - public void PauseResume(bool pause) + public static void PauseResume(bool pause) { - Interop.Accessibility.PauseResume(View.getCPtr(dummy), pause); + Interop.Accessibility.PauseResume(pause); if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); } @@ -147,9 +104,9 @@ namespace Tizen.NUI.Accessibility /// whether to cancel non-discardable readings as well // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API) [EditorBrowsable(EditorBrowsableState.Never)] - public void StopReading(bool alsoNonDiscardable) + public static void StopReading(bool alsoNonDiscardable) { - Interop.Accessibility.StopReading(View.getCPtr(dummy), alsoNonDiscardable); + Interop.Accessibility.StopReading(alsoNonDiscardable); if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); } @@ -159,9 +116,9 @@ namespace Tizen.NUI.Accessibility /// whether to suppress reading of screen-reader // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API) [EditorBrowsable(EditorBrowsableState.Never)] - public bool SuppressScreenReader(bool suppress) + public static bool SuppressScreenReader(bool suppress) { - bool ret = Interop.Accessibility.SuppressScreenReader(View.getCPtr(dummy), suppress); + bool ret = Interop.Accessibility.SuppressScreenReader(suppress); if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); return ret; } @@ -198,7 +155,7 @@ namespace Tizen.NUI.Accessibility /// // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API) [EditorBrowsable(EditorBrowsableState.Never)] - public View GetHighlightFrameView() + public static View GetHighlightFrameView() { var ptr = Interop.ControlDevel.DaliAccessibilityAccessibleGetHighlightActor(); if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); @@ -212,7 +169,7 @@ namespace Tizen.NUI.Accessibility /// // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API) [EditorBrowsable(EditorBrowsableState.Never)] - public void SetHighlightFrameView(View view) + public static void SetHighlightFrameView(View view) { Interop.ControlDevel.DaliAccessibilityAccessibleSetHighlightActor(View.getCPtr(view)); if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); @@ -223,13 +180,13 @@ namespace Tizen.NUI.Accessibility /// // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API) [EditorBrowsable(EditorBrowsableState.Never)] - public View GetCurrentlyHighlightedView() + public static View GetCurrentlyHighlightedView() { var ptr = Interop.ControlDevel.DaliAccessibilityAccessibleGetCurrentlyHighlightedActor(); if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); - return this.GetInstanceSafely(ptr); + return dummyHandle.GetInstanceSafely(ptr); } /// @@ -237,7 +194,7 @@ namespace Tizen.NUI.Accessibility /// // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API) [EditorBrowsable(EditorBrowsableState.Never)] - public bool ClearCurrentlyHighlightedView() + public static bool ClearCurrentlyHighlightedView() { var view = GetCurrentlyHighlightedView(); @@ -297,11 +254,7 @@ namespace Tizen.NUI.Accessibility /// // This will be public opened after ACR done. (Before ACR, need to be hidden as Inhouse API) [EditorBrowsable(EditorBrowsableState.Never)] - public event EventHandler SayFinished - { - add => sayFinishedEventHandler += value; - remove => sayFinishedEventHandler -= value; - } + public static event EventHandler SayFinished; /// /// Triggered whenever the value of IsEnabled would change from false to true @@ -319,50 +272,24 @@ namespace Tizen.NUI.Accessibility #endregion Event, Enum, Struct, ETC - - #region Internal - internal void PauseResume(View target, bool pause) - { - Interop.Accessibility.PauseResume(View.getCPtr(target), pause); - if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); - } - - internal bool Say(View target, string sentence, bool discardable) - { - IntPtr callbackIntPtr = IntPtr.Zero; - if (sayFinishedEventHandler != null) - { - callback = SayFinishedEventCallback; - callbackIntPtr = Marshal.GetFunctionPointerForDelegate(callback); - } - bool ret = Interop.Accessibility.Say(View.getCPtr(target), sentence, discardable, callbackIntPtr); - if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); - return ret; - } - #endregion Internal - - #region Private - private static readonly Accessibility accessibility = new Accessibility(); - - private event EventHandler sayFinishedEventHandler; [UnmanagedFunctionPointer(CallingConvention.StdCall)] private delegate void SayFinishedEventCallbackType(int result); - private SayFinishedEventCallbackType callback = null; + private static SayFinishedEventCallbackType callback = SayFinishedEventCallback; private static Interop.Accessibility.EnabledDisabledSignalHandler enabledSignalHandler = null; private static Interop.Accessibility.EnabledDisabledSignalHandler disabledSignalHandler = null; - private void SayFinishedEventCallback(int result) + private static void SayFinishedEventCallback(int result) { NUILog.Debug($"sayFinishedEventCallback(res={result}) called!"); - sayFinishedEventHandler?.Invoke(this, new SayFinishedEventArgs(result)); + SayFinished?.Invoke(typeof(Accessibility), new SayFinishedEventArgs(result)); } - private View dummy; + private static BaseHandle dummyHandle = new BaseHandle(); #endregion Private } diff --git a/src/Tizen.NUI/src/public/BaseComponents/View.cs b/src/Tizen.NUI/src/public/BaseComponents/View.cs index 4c6d186..185f04f 100755 --- a/src/Tizen.NUI/src/public/BaseComponents/View.cs +++ b/src/Tizen.NUI/src/public/BaseComponents/View.cs @@ -1,5 +1,5 @@ /* - * Copyright(c) 2021 Samsung Electronics Co., Ltd. + * Copyright(c) 2022 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -289,30 +289,6 @@ namespace Tizen.NUI.BaseComponents } } - /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API. - [EditorBrowsable(EditorBrowsableState.Never)] - public bool IsResourcesCreated - { - get - { - return Application.Current.IsResourcesCreated; - } - } - - /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API. - [EditorBrowsable(EditorBrowsableState.Never)] - public ResourceDictionary XamlResources - { - get - { - return Application.Current.XamlResources; - } - set - { - Application.Current.XamlResources = value; - } - } - /// /// The StyleName, type string. /// The value indicates DALi style name defined in json theme file. @@ -2638,19 +2614,6 @@ namespace Tizen.NUI.BaseComponents } } - [EditorBrowsable(EditorBrowsableState.Never)] - public XamlStyle XamlStyle - { - get - { - return (XamlStyle)GetValue(XamlStyleProperty); - } - set - { - SetValue(XamlStyleProperty, value); - } - } - /// /// The Color of View. This is an RGBA value. /// diff --git a/src/Tizen.NUI/src/public/BaseComponents/ViewAccessibility.cs b/src/Tizen.NUI/src/public/BaseComponents/ViewAccessibility.cs index c4bd853..876c8e0 100755 --- a/src/Tizen.NUI/src/public/BaseComponents/ViewAccessibility.cs +++ b/src/Tizen.NUI/src/public/BaseComponents/ViewAccessibility.cs @@ -229,7 +229,7 @@ namespace Tizen.NUI.BaseComponents { get { - return (this == Accessibility.Accessibility.Instance.GetCurrentlyHighlightedView()); + return (this == Accessibility.Accessibility.GetCurrentlyHighlightedView()); } } @@ -463,7 +463,9 @@ namespace Tizen.NUI.BaseComponents [EditorBrowsable(EditorBrowsableState.Never)] public void SetAccessibilityConstructor(Role role, AccessibilityInterface accessibilityInterface = AccessibilityInterface.None) { - Interop.ControlDevel.DaliToolkitDevelControlSetAccessibilityConstructor(SwigCPtr, (int)role, (int)accessibilityInterface); + // We have to store the interface flags until we remove SetAccessibilityConstructor and switch to native C# interfaces + AtspiInterfaceFlags = (1U << (int)accessibilityInterface); + Interop.ControlDevel.DaliToolkitDevelControlSetAccessibilityConstructor(SwigCPtr, (int)role); if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); } diff --git a/src/Tizen.NUI/src/public/BaseComponents/ViewAccessibilityEnum.cs b/src/Tizen.NUI/src/public/BaseComponents/ViewAccessibilityEnum.cs index 0da2876..31a19e6 100755 --- a/src/Tizen.NUI/src/public/BaseComponents/ViewAccessibilityEnum.cs +++ b/src/Tizen.NUI/src/public/BaseComponents/ViewAccessibilityEnum.cs @@ -25,6 +25,7 @@ namespace Tizen.NUI.BaseComponents /// /// Accessibility interface. /// + // Values are from Dali::Accessibility::AtspiInterface [EditorBrowsable(EditorBrowsableState.Never)] public enum AccessibilityInterface { @@ -37,17 +38,17 @@ namespace Tizen.NUI.BaseComponents /// Accessibility interface which can store numeric value /// [EditorBrowsable(EditorBrowsableState.Never)] - Value = 1, + Value = 26, /// /// Accessibility interface which can store editable texts /// [EditorBrowsable(EditorBrowsableState.Never)] - EditableText = 2, + EditableText = 9, /// /// Accessibility interface which can store a set of selected items /// [EditorBrowsable(EditorBrowsableState.Never)] - Selection = 3, + Selection = 21, } /// diff --git a/src/Tizen.NUI/src/public/BaseComponents/ViewAccessibilityWrappers.cs b/src/Tizen.NUI/src/public/BaseComponents/ViewAccessibilityWrappers.cs index 3fbc45c..6dfe09c 100644 --- a/src/Tizen.NUI/src/public/BaseComponents/ViewAccessibilityWrappers.cs +++ b/src/Tizen.NUI/src/public/BaseComponents/ViewAccessibilityWrappers.cs @@ -24,6 +24,9 @@ namespace Tizen.NUI.BaseComponents { private static AccessibilityStates AccessibilityInitialStates = new AccessibilityStates(); + // To be removed when native C# AT-SPI interfaces are implemented. + private uint? AtspiInterfaceFlags = null; + private static void RegisterAccessibilityDelegate() { InitializeAccessibilityDelegateAccessibleInterface(); @@ -68,6 +71,7 @@ namespace Tizen.NUI.BaseComponents ad.CalculateStates = AccessibilityCalculateStatesWrapper; ad.GetDescription = AccessibilityGetDescriptionWrapper; + ad.GetInterfaces = AccessibilityGetInterfaces; // Not a wrapper, entirely private implementation ad.GetName = AccessibilityGetNameWrapper; } @@ -93,6 +97,29 @@ namespace Tizen.NUI.BaseComponents return DuplicateString(description); } + private static uint AccessibilityGetInterfaces(IntPtr self) + { + // Currently a maximum of one AccessibilityInterface per View is supported. + // This will change when we implement AT-SPI interfaces as native C# interfaces. + // Then, this method will look like: + // + // uint flags = 0U; + // if (view is IAtspiSelection) flags |= (1U << (int)AccessibilityInterface.Selection) + // if (view is IAtspiValue) flags |= (1U << (int)AccessibilityInterface.Value) + // ... + // return flags; + + View view = GetViewFromRefObject(self); + + if (!view.AtspiInterfaceFlags.HasValue) + { + NUILog.Error("AtspiInterfaceFlags are not set!"); + return 0U; + } + + return view.AtspiInterfaceFlags.Value; + } + private static IntPtr AccessibilityGetNameWrapper(IntPtr self) { string name = GetViewFromRefObject(self).AccessibilityGetName(); diff --git a/src/Tizen.NUI/src/public/BaseComponents/ViewBindableProperty.cs b/src/Tizen.NUI/src/public/BaseComponents/ViewBindableProperty.cs index 51ff3ec..3cfc50c 100755 --- a/src/Tizen.NUI/src/public/BaseComponents/ViewBindableProperty.cs +++ b/src/Tizen.NUI/src/public/BaseComponents/ViewBindableProperty.cs @@ -1888,12 +1888,6 @@ namespace Tizen.NUI.BaseComponents }); /// - /// XamlStyleProperty - /// - [EditorBrowsable(EditorBrowsableState.Never)] - public static readonly BindableProperty XamlStyleProperty = BindableProperty.Create(nameof(XamlStyle), typeof(XamlStyle), typeof(View), default(XamlStyle), propertyChanged: (bindable, oldvalue, newvalue) => ((View)bindable).MergedStyle.Style = (XamlStyle)newvalue); - - /// /// EnableControlState property /// [EditorBrowsable(EditorBrowsableState.Never)] diff --git a/src/Tizen.NUI/src/public/BaseComponents/ViewInternal.cs b/src/Tizen.NUI/src/public/BaseComponents/ViewInternal.cs index 212cea8..6fc6bd6 100755 --- a/src/Tizen.NUI/src/public/BaseComponents/ViewInternal.cs +++ b/src/Tizen.NUI/src/public/BaseComponents/ViewInternal.cs @@ -1,5 +1,5 @@ -/* - * Copyright(c) 2021 Samsung Electronics Co., Ltd. +/* + * Copyright(c) 2022 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,11 +16,7 @@ */ using System; -using System.Collections.Generic; using System.ComponentModel; -using System.Diagnostics; -using System.Runtime.CompilerServices; -using Tizen.NUI.Binding; namespace Tizen.NUI.BaseComponents { @@ -30,21 +26,8 @@ namespace Tizen.NUI.BaseComponents /// 3 public partial class View { - private MergedStyle mergedStyle = null; internal string styleName; - internal MergedStyle MergedStyle - { - get - { - if (null == mergedStyle) - { - mergedStyle = new MergedStyle(GetType(), this); - } - - return mergedStyle; - } - } internal virtual LayoutItem CreateDefaultLayout() { return new AbsoluteLayout(); @@ -1038,8 +1021,7 @@ namespace Tizen.NUI.BaseComponents child.InternalParent = null; LayoutCount -= child.LayoutCount; - RemoveChildBindableObject(child); - + OnChildRemoved(child); if (ChildRemoved != null) { ChildRemovedEventArgs e = new ChildRemovedEventArgs diff --git a/src/Tizen.NUI/src/public/BaseComponents/ViewPublicMethods.cs b/src/Tizen.NUI/src/public/BaseComponents/ViewPublicMethods.cs index 489c7c0..f78edcb 100755 --- a/src/Tizen.NUI/src/public/BaseComponents/ViewPublicMethods.cs +++ b/src/Tizen.NUI/src/public/BaseComponents/ViewPublicMethods.cs @@ -1,5 +1,5 @@ -/* - * Copyright(c) 2020 Samsung Electronics Co., Ltd. +/* + * Copyright(c) 2022 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -158,6 +158,7 @@ namespace Tizen.NUI.BaseComponents if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); Children.Add(child); + OnChildAdded(child); if (ChildAdded != null) { @@ -167,8 +168,6 @@ namespace Tizen.NUI.BaseComponents }; ChildAdded(this, e); } - - AddChildBindableObject(child); } } diff --git a/src/Tizen.NUI/src/public/Common/BaseHandle.cs b/src/Tizen.NUI/src/public/Common/BaseHandle.cs old mode 100644 new mode 100755 index c033810..b50fd7f --- a/src/Tizen.NUI/src/public/Common/BaseHandle.cs +++ b/src/Tizen.NUI/src/public/Common/BaseHandle.cs @@ -1,5 +1,5 @@ /* - * Copyright(c) 2021 Samsung Electronics Co., Ltd. + * Copyright(c) 2022 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -608,11 +608,6 @@ namespace Tizen.NUI } disposed = true; - - if (null != Application.Current) - { - Application.Current.XamlResourceChanged -= OnResourcesChanged; - } DebugFileLogging.Instance.WriteLog($"BaseHandle.Dispose({type}) END"); DebugFileLogging.Instance.WriteLog($"============================="); NUILog.Debug($"BaseHandle.Dispose({type}) END"); diff --git a/src/Tizen.NUI/src/public/Common/Container.cs b/src/Tizen.NUI/src/public/Common/Container.cs index 6652914..9174575 100755 --- a/src/Tizen.NUI/src/public/Common/Container.cs +++ b/src/Tizen.NUI/src/public/Common/Container.cs @@ -1,5 +1,5 @@ /* - * Copyright(c) 2021 Samsung Electronics Co., Ltd. + * Copyright(c) 2022 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -19,6 +19,7 @@ using System; using System.Collections.Generic; using System.ComponentModel; using Tizen.NUI.BaseComponents; +using Tizen.NUI.Binding; using Tizen.NUI.Binding.Internals; namespace Tizen.NUI @@ -28,16 +29,76 @@ namespace Tizen.NUI /// added to them. /// /// 4 - public abstract class Container : Animatable + public abstract class Container : Animatable, IResourcesProvider { + /// XamlStyleProperty + [EditorBrowsable(EditorBrowsableState.Never)] + public static readonly BindableProperty XamlStyleProperty = BindableProperty.Create(nameof(XamlStyle), typeof(XamlStyle), typeof(Container), default(XamlStyle), propertyChanged: (bindable, oldvalue, newvalue) => ((View)bindable).MergedStyle.Style = (XamlStyle)newvalue); + internal BaseHandle InternalParent; private List childViews = new List(); + private MergedStyle mergedStyle = null; + ResourceDictionary _resources; + bool IResourcesProvider.IsResourcesCreated => _resources != null; internal Container(global::System.IntPtr cPtr, bool cMemoryOwn) : base(cPtr, cMemoryOwn) { // No un-managed data hence no need to store a native ptr } + /// This will be public opened in tizen_next after ACR done. Before ACR, need to be hidden as inhouse API. + [EditorBrowsable(EditorBrowsableState.Never)] + public ResourceDictionary XamlResources + { + get + { + if (_resources != null) + return _resources; + _resources = new ResourceDictionary(); + ((IResourceDictionary)_resources).ValuesChanged += OnResourcesChanged; + return _resources; + } + set + { + if (_resources == value) + return; + OnPropertyChanging(); + if (_resources != null) + ((IResourceDictionary)_resources).ValuesChanged -= OnResourcesChanged; + _resources = value; + OnResourcesChanged(value); + if (_resources != null) + ((IResourceDictionary)_resources).ValuesChanged += OnResourcesChanged; + OnPropertyChanged(); + } + } + + [EditorBrowsable(EditorBrowsableState.Never)] + public XamlStyle XamlStyle + { + get + { + return (XamlStyle)GetValue(XamlStyleProperty); + } + set + { + SetValue(XamlStyleProperty, value); + } + } + + internal MergedStyle MergedStyle + { + get + { + if (null == mergedStyle) + { + mergedStyle = new MergedStyle(GetType(), this); + } + + return mergedStyle; + } + } + /// /// List of children of Container. /// @@ -214,6 +275,55 @@ namespace Tizen.NUI internal abstract View FindCurrentChildById(uint id); + internal override void OnParentResourcesChanged(IEnumerable> values) + { + if (values == null) + return; + + if (!((IResourcesProvider)this).IsResourcesCreated || XamlResources.Count == 0) + { + base.OnParentResourcesChanged(values); + return; + } + + var innerKeys = new HashSet(); + var changedResources = new List>(); + foreach (KeyValuePair c in XamlResources) + innerKeys.Add(c.Key); + foreach (KeyValuePair value in values) + { + if (innerKeys.Add(value.Key)) + changedResources.Add(value); + } + if (changedResources.Count != 0) + OnResourcesChanged(changedResources); + } + + /// + /// Invoked whenever the binding context of the element changes. Implement this method to add class handling for this event. + /// + /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API. + [EditorBrowsable(EditorBrowsableState.Never)] + protected override void OnBindingContextChanged() + { + var gotBindingContext = false; + object bc = null; + + for (var index = 0; index < Children.Count; index++) + { + Element child = Children[index]; + + if (!gotBindingContext) + { + bc = BindingContext; + gotBindingContext = true; + } + + SetChildInheritedBindingContext(child, bc); + } + base.OnBindingContextChanged(); + } + private void DisposeIncludeChildren() { foreach (var child in Children) diff --git a/src/Tizen.NUI/src/public/Common/Layer.cs b/src/Tizen.NUI/src/public/Common/Layer.cs index 6e52bf2..a78c3cd 100755 --- a/src/Tizen.NUI/src/public/Common/Layer.cs +++ b/src/Tizen.NUI/src/public/Common/Layer.cs @@ -17,7 +17,6 @@ using System; using Tizen.NUI.BaseComponents; using System.ComponentModel; -using Tizen.NUI.Binding; namespace Tizen.NUI { @@ -28,7 +27,6 @@ namespace Tizen.NUI public class Layer : Container { private Window window; - private int layoutCount = 0; /// @@ -260,20 +258,6 @@ namespace Tizen.NUI } } - /// This will be public opened in tizen_next after ACR done. Before ACR, need to be hidden as inhouse API. - [EditorBrowsable(EditorBrowsableState.Never)] - public ResourceDictionary XamlResources - { - get - { - return Application.Current.XamlResources; - } - set - { - Application.Current.XamlResources = value; - } - } - /// /// Gets the Layer's ID /// Readonly @@ -324,7 +308,7 @@ namespace Tizen.NUI if (NDalicPINVOKE.SWIGPendingException.Pending) throw NDalicPINVOKE.SWIGPendingException.Retrieve(); Children.Add(child); - BindableObject.SetInheritedBindingContext(child, this?.BindingContext); + OnChildAdded(child); } } @@ -356,7 +340,7 @@ namespace Tizen.NUI Children.Remove(child); child.InternalParent = null; - + OnChildRemoved(child); LayoutCount -= child.LayoutCount; } diff --git a/src/Tizen.NUI/src/public/Events/Touch.cs b/src/Tizen.NUI/src/public/Events/Touch.cs index 817e662..4f39757 100755 --- a/src/Tizen.NUI/src/public/Events/Touch.cs +++ b/src/Tizen.NUI/src/public/Events/Touch.cs @@ -60,6 +60,9 @@ namespace Tizen.NUI /// /// Returns the total number of points in this TouchData. + /// Point means the touched point. + /// If there is one touch point, the point index is 0. + /// If there are two touch points, the point index has 0 and 1. /// /// The total number of points. /// 3 @@ -76,7 +79,7 @@ namespace Tizen.NUI /// point. This is returned by this method.
/// If a point is greater than GetPointCount(), then this method will return -1.
///
- /// The point required. + /// The index of a touch point /// The device ID of this point. /// 3 public int GetDeviceId(uint point) @@ -90,7 +93,7 @@ namespace Tizen.NUI /// Retrieves the state of the point specified.
/// If a point is greater than GetPointCount(), then this method will return PointState.Finished.
///
- /// The point required. + /// The index of a touch point. /// The state of the point specified. /// 3 public PointStateType GetState(uint point) @@ -101,11 +104,11 @@ namespace Tizen.NUI } /// - /// Retrieves the actor that was underneath the point specified.
+ /// Retrieves the view that was underneath the point specified.
/// If a point is greater than GetPointCount(), then this method will return an empty handle.
///
- /// The point required. - /// The actor that was underneath the point specified. + /// The index of a touch point. + /// The view that was underneath the point specified. /// 3 public View GetHitView(uint point) { @@ -117,14 +120,14 @@ namespace Tizen.NUI } /// - /// Retrieves the coordinates relative to the top-left of the hit actor at the point specified.
- /// The top-left of an actor is (0.0, 0.0, 0.5).
- /// If you require the local coordinates of another actor (for example, the parent of the hit actor), - /// then you should use Actor::ScreenToLocal().
+ /// Retrieves the coordinates relative to the top-left of the hit view at the point specified.
+ /// The top-left of an view is (0.0, 0.0, 0.5).
+ /// If you require the local coordinates of another view (for example, the parent of the hit view), + /// then you should use ScreenToLocal().
/// If a point is greater than GetPointCount(), then this method will return Vector2.Zero.
///
- /// The point required. - /// The coordinates relative to the top-left of the hit actor of the point specified. + /// The index of a touch point. + /// The coordinates relative to the top-left of the hit view of the point specified. /// 3 public Vector2 GetLocalPosition(uint point) { @@ -137,7 +140,7 @@ namespace Tizen.NUI /// Retrieves the coordinates relative to the top-left of the screen of the point specified.
/// If a point is greater than GetPointCount(), then this method will return Vector2.Zero.
///
- /// The point required. + /// The index of a touch point. /// The coordinates relative to the top-left of the screen of the point specified. /// 3 public Vector2 GetScreenPosition(uint point) @@ -152,7 +155,7 @@ namespace Tizen.NUI /// This is the average of both the horizontal and vertical radii of the press point.
/// If point is greater than GetPointCount(), then this method will return 0.0f.
/// - /// The point required. + /// The index of a touch point. /// The radius of the press point. /// 3 public float GetRadius(uint point) @@ -166,7 +169,7 @@ namespace Tizen.NUI /// Retrieves both the horizontal and the vertical radii of the press point.
/// If a point is greater than GetPointCount(), then this method will return Vector2.Zero.
/// - /// The point required. + /// The index of a touch point. /// The horizontal and vertical radii of the press point. /// 3 public Vector2 GetEllipseRadius(uint point) @@ -184,7 +187,7 @@ namespace Tizen.NUI /// A value greater than 1.0f means more pressure than normal has been applied.
/// If point is greater than GetPointCount(), then this method will return 1.0f.
/// - /// The point required. + /// The index of a touch point. /// The touch pressure. /// 3 public float GetPressure(uint point) @@ -197,7 +200,7 @@ namespace Tizen.NUI /// /// Get mouse device's button value (for example, right or left button) /// - /// The point required. + /// The index of a touch point. /// /// 5 /// This will be public opened in tizen_5.0 after ACR done. Before ACR, need to be hidden as inhouse API. diff --git a/src/Tizen.NUI/src/public/Xaml/XamlFilePathAttribute.cs b/src/Tizen.NUI/src/public/Xaml/XamlFilePathAttribute.cs index 3e90165..dcbe7c8 100755 --- a/src/Tizen.NUI/src/public/Xaml/XamlFilePathAttribute.cs +++ b/src/Tizen.NUI/src/public/Xaml/XamlFilePathAttribute.cs @@ -1,5 +1,5 @@ /* - * Copyright(c) 2021 Samsung Electronics Co., Ltd. + * Copyright(c) 2022 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -17,6 +17,8 @@ using System; using System.ComponentModel; +using System.Linq; +using System.Reflection; using System.Runtime.CompilerServices; namespace Tizen.NUI.Xaml @@ -28,10 +30,11 @@ namespace Tizen.NUI.Xaml { /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API. [EditorBrowsable(EditorBrowsableState.Never)] - public XamlFilePathAttribute([CallerFilePath] string filePath = "") - { - // Unused parameter - _ = filePath; - } + public XamlFilePathAttribute([CallerFilePath] string filePath = "") => FilePath = filePath; + + [EditorBrowsable(EditorBrowsableState.Never)] + public string FilePath { get; } + + internal static string GetFilePathForObject(object view) => (view?.GetType().GetTypeInfo().GetCustomAttributes(typeof(XamlFilePathAttribute), false).FirstOrDefault() as XamlFilePathAttribute)?.FilePath; } } diff --git a/src/Tizen.NUI/src/public/Xaml/XamlParseException.cs b/src/Tizen.NUI/src/public/Xaml/XamlParseException.cs index da1c3f5..168bbba 100755 --- a/src/Tizen.NUI/src/public/Xaml/XamlParseException.cs +++ b/src/Tizen.NUI/src/public/Xaml/XamlParseException.cs @@ -1,5 +1,5 @@ /* - * Copyright(c) 2021 Samsung Electronics Co., Ltd. + * Copyright(c) 2022 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -72,6 +72,11 @@ namespace Tizen.NUI.Xaml XmlInfo = xmlInfo; } + internal XamlParseException(string message, IServiceProvider serviceProvider, Exception innerException = null) + : this(message, GetLineInfo(serviceProvider), innerException) + { + } + /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API. [EditorBrowsable(EditorBrowsableState.Never)] public IXmlLineInfo XmlInfo { get; private set; } @@ -87,5 +92,9 @@ namespace Tizen.NUI.Xaml return message; return string.Format("Position {0}:{1}. {2}", xmlinfo.LineNumber, xmlinfo.LinePosition, message); } + + + static IXmlLineInfo GetLineInfo(IServiceProvider serviceProvider) + => (serviceProvider.GetService(typeof(IXmlLineInfoProvider)) is IXmlLineInfoProvider lineInfoProvider) ? lineInfoProvider.XmlLineInfo : new XmlLineInfo(); } } diff --git a/src/Tizen.NUI/src/public/XamlBinding/BindableObject.cs b/src/Tizen.NUI/src/public/XamlBinding/BindableObject.cs index 97d99a2..9bac951 100755 --- a/src/Tizen.NUI/src/public/XamlBinding/BindableObject.cs +++ b/src/Tizen.NUI/src/public/XamlBinding/BindableObject.cs @@ -1,5 +1,5 @@ -/* - * Copyright(c) 2021 Samsung Electronics Co., Ltd. +/* + * Copyright(c) 2022 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -37,36 +37,8 @@ namespace Tizen.NUI.Binding /// [EditorBrowsable(EditorBrowsableState.Never)] public static readonly BindableProperty BindingContextProperty = - BindableProperty.Create(nameof(BindingContext), typeof(object), typeof(BindableObject), null, propertyChanged: (BindableProperty.BindingPropertyChangedDelegate)((bindable, oldValue, newValue) => - { - var bindableObject = (BindableObject)bindable; - if (newValue != null) - { - bindableObject.bindingContext = newValue; - bindableObject.FlushBinding(); - - if (newValue is BindableObject targetBindableObject) - { - targetBindableObject.IsBinded = true; - } - } - }), - defaultValueCreator: (BindableProperty.CreateDefaultValueDelegate)((bindable) => - { - if (null != bindable.bindingContext) - { - return bindable.bindingContext; - } - - if (bindable is Container container) - { - return container.Parent?.BindingContext; - } - else - { - return null; - } - })); + BindableProperty.Create(nameof(BindingContext), typeof(object), typeof(BindableObject), default(object), BindingMode.OneWay, null, BindingContextPropertyChanged, + null, null, BindingContextPropertyBindingChanging); readonly Dictionary properties = new Dictionary(4); @@ -814,6 +786,18 @@ namespace Tizen.NUI.Binding set; } = false; + static void BindingContextPropertyChanged(BindableObject bindable, object oldvalue, object newvalue) + { + bindable.inheritedContext = null; + bindable.ApplyBindings(skipBindingContext: true, fromBindingContextChanged: true); + bindable.OnBindingContextChanged(); + + if (newvalue is BindableObject targetBindableObject) + { + targetBindableObject.IsBinded = true; + } + } + static void BindingContextPropertyBindingChanging(BindableObject bindable, BindingBase oldBindingBase, BindingBase newBindingBase) { object context = bindable.inheritedContext; @@ -1095,20 +1079,6 @@ namespace Tizen.NUI.Binding } } - internal void AddChildBindableObject(BindableObject child) - { - if (null != child) - { - children.Add(child); - child.FlushBinding(); - } - } - - internal void RemoveChildBindableObject(BindableObject child) - { - children.Remove(child); - } - internal void ReplaceBindingElement(Dictionary oldNameScope, Dictionary newNameScope) { var xElementToNameOfOld = new Dictionary(); @@ -1158,19 +1128,6 @@ namespace Tizen.NUI.Binding } } } - - private List children = new List(); - - private void FlushBinding() - { - ApplyBindings(skipBindingContext: true, fromBindingContextChanged: true); - OnBindingContextChanged(); - - foreach (var child in children) - { - child.FlushBinding(); - } - } } } diff --git a/src/Tizen.NUI/src/public/XamlBinding/Element.cs b/src/Tizen.NUI/src/public/XamlBinding/Element.cs index 21271a4..e92b21e 100755 --- a/src/Tizen.NUI/src/public/XamlBinding/Element.cs +++ b/src/Tizen.NUI/src/public/XamlBinding/Element.cs @@ -1,5 +1,5 @@ /* - * Copyright(c) 2021 Samsung Electronics Co., Ltd. + * Copyright(c) 2022 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -448,10 +448,7 @@ namespace Tizen.NUI.Binding internal virtual void OnParentResourcesChanged(object sender, ResourcesChangedEventArgs e) { - // if (e == ResourcesChangedEventArgs.StyleSheets) - // // ApplyStyleSheetsOnParentSet(); - // else - // OnParentResourcesChanged(e.Values); + OnParentResourcesChanged(e.Values); } internal virtual void OnParentResourcesChanged(IEnumerable> values) @@ -520,11 +517,6 @@ namespace Tizen.NUI.Binding object value; if (this.TryGetResource(key, out value)) OnResourceChanged(property, value); - - if (null != Application.Current) - { - Application.Current.XamlResourceChanged += OnResourcesChanged; - } } internal event EventHandler ParentSet; diff --git a/src/Tizen.NUI/src/public/XamlBinding/IValueConverter.cs b/src/Tizen.NUI/src/public/XamlBinding/IValueConverter.cs index 1ee2a5d..937ff82 100755 --- a/src/Tizen.NUI/src/public/XamlBinding/IValueConverter.cs +++ b/src/Tizen.NUI/src/public/XamlBinding/IValueConverter.cs @@ -1,4 +1,4 @@ -/* +/* * Copyright(c) 2021 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); diff --git a/src/Tizen.NUI/src/public/XamlBinding/ResourceDictionary.cs b/src/Tizen.NUI/src/public/XamlBinding/ResourceDictionary.cs index 797436b..1051090 100755 --- a/src/Tizen.NUI/src/public/XamlBinding/ResourceDictionary.cs +++ b/src/Tizen.NUI/src/public/XamlBinding/ResourceDictionary.cs @@ -1,5 +1,5 @@ /* - * Copyright(c) 2021 Samsung Electronics Co., Ltd. + * Copyright(c) 2022 Samsung Electronics Co., Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -25,8 +25,6 @@ using System.Globalization; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; - -using Tizen.NUI.Binding.Internals; using Tizen.NUI.Xaml; namespace Tizen.NUI.Binding diff --git a/src/Tizen.NUI/src/public/XamlBinding/XamlStyle.cs b/src/Tizen.NUI/src/public/XamlBinding/XamlStyle.cs index 64edce2..f1a9d74 100755 --- a/src/Tizen.NUI/src/public/XamlBinding/XamlStyle.cs +++ b/src/Tizen.NUI/src/public/XamlBinding/XamlStyle.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Reflection; using Tizen.NUI.StyleSheets; using System.ComponentModel; +using Tizen.NUI.BaseComponents; namespace Tizen.NUI.Binding { @@ -12,6 +13,9 @@ namespace Tizen.NUI.Binding { internal const string StyleClassPrefix = "Tizen.NUI.Binding.StyleClass."; + const int CleanupTrigger = 128; + int cleanupThreshold = CleanupTrigger; + readonly BindableProperty basedOnResourceProperty = BindableProperty.CreateAttached("BasedOnResource", typeof(XamlStyle), typeof(XamlStyle), default(XamlStyle), propertyChanged: OnBasedOnResourceChanged); @@ -106,6 +110,7 @@ namespace Tizen.NUI.Binding if (BaseResourceKey != null) bindable.SetDynamicResource(basedOnResourceProperty, BaseResourceKey); ApplyCore(bindable, BasedOn ?? GetBasedOnResource(bindable)); + CleanUpWeakReferences(); } [EditorBrowsable(EditorBrowsableState.Never)] @@ -168,11 +173,11 @@ namespace Tizen.NUI.Binding static void OnBasedOnResourceChanged(BindableObject bindable, object oldValue, object newValue) { - // Style style = (bindable as BaseHandle).Style; - // if (style == null) - // return; - // style.UnApplyCore(bindable, (Style)oldValue); - // style.ApplyCore(bindable, (Style)newValue); + XamlStyle style = (bindable as View).XamlStyle; + if (style == null) + return; + style.UnApplyCore(bindable, (XamlStyle)oldValue); + style.ApplyCore(bindable, (XamlStyle)newValue); } void UnApplyCore(BindableObject bindable, XamlStyle basedOn) @@ -192,5 +197,16 @@ namespace Tizen.NUI.Binding return true; return value.TargetType.IsAssignableFrom(TargetType); } - } + + void CleanUpWeakReferences() + { + if (targets.Count < cleanupThreshold) + { + return; + } + + targets.RemoveAll(t => !t.TryGetTarget(out _)); + cleanupThreshold = targets.Count + CleanupTrigger; + } + } } diff --git a/test/NUITestSample/NUITestSample/examples/AtspiTest.cs b/test/NUITestSample/NUITestSample/examples/AtspiTest.cs index 63eeed0..64b080b 100755 --- a/test/NUITestSample/NUITestSample/examples/AtspiTest.cs +++ b/test/NUITestSample/NUITestSample/examples/AtspiTest.cs @@ -76,35 +76,35 @@ namespace Tizen.TV.NUI.Example //var accessbilityStatus = NDalicPINVOKE.accessibility_get_status(View.getCPtr(view)); if (e.Key.KeyPressedName == "Return") { - Accessibility.Instance.SayFinished -= Instance_SayFinished; - Accessibility.Instance.Say("", true); + Accessibility.SayFinished -= Instance_SayFinished; + Accessibility.Say("", true); repeatFlag = false; } else if (e.Key.KeyPressedName == "Right") { - Accessibility.Instance.Say(testScript1, true); + Accessibility.Say(testScript1, true); } else if (e.Key.KeyPressedName == "Left") { - Accessibility.Instance.Say(testScript2, true); + Accessibility.Say(testScript2, true); } else if (e.Key.KeyPressedName == "Up") { - Accessibility.Instance.Say(testScript3, true); + Accessibility.Say(testScript3, true); } else if (e.Key.KeyPressedName == "Down") { repeatFlag = true; - Accessibility.Instance.SayFinished += Instance_SayFinished; - Accessibility.Instance.Say("my name is say api !!!", true); + Accessibility.SayFinished += Instance_SayFinished; + Accessibility.Say("my name is say api !!!", true); } else if (e.Key.KeyPressedName == "1") { - Accessibility.Instance.PauseResume(true); + Accessibility.PauseResume(true); } else if (e.Key.KeyPressedName == "2") { - Accessibility.Instance.PauseResume(false); + Accessibility.PauseResume(false); } } return false; @@ -115,7 +115,7 @@ namespace Tizen.TV.NUI.Example tlog.Fatal(tag, $"Instance_SayFinished()! State={e.State}"); if (e.State == Accessibility.SayFinishedState.Stopped) { - Accessibility.Instance.Say("ÀÌ°Ç Äݹé Å×½ºÆ® ÀÔ´Ï´Ù. this is callback test! ÄݹéÀ» »©·Á¸é È®ÀÎÅ°¸¦ ´©¸£¼¼¿ä. to remove callback please push Return key", true); + Accessibility.Say("ÀÌ°Ç Äݹé Å×½ºÆ® ÀÔ´Ï´Ù. this is callback test! ÄݹéÀ» »©·Á¸é È®ÀÎÅ°¸¦ ´©¸£¼¼¿ä. to remove callback please push Return key", true); } } diff --git a/test/Tizen.NUI.Tests/Tizen.NUI.Devel.Tests/testcase/public/Accessibility/TSAccessibility.cs b/test/Tizen.NUI.Tests/Tizen.NUI.Devel.Tests/testcase/public/Accessibility/TSAccessibility.cs index 19a38df..8ec5e18 100755 --- a/test/Tizen.NUI.Tests/Tizen.NUI.Devel.Tests/testcase/public/Accessibility/TSAccessibility.cs +++ b/test/Tizen.NUI.Tests/Tizen.NUI.Devel.Tests/testcase/public/Accessibility/TSAccessibility.cs @@ -28,24 +28,6 @@ namespace Tizen.NUI.Devel.Tests [Test] [Category("P1")] - [Description("Accessibility constructor.")] - [Property("SPEC", "Tizen.NUI.Accessibility.Accessibility C")] - [Property("SPEC_URL", "-")] - [Property("CRITERIA", "CONSTR")] - [Property("AUTHOR", "guowei.wang@samsung.com")] - public void AccessibilityConstructor() - { - tlog.Debug(tag, $"AccessibilityConstructor START"); - - var testingTarget = Accessibility.Accessibility.Instance; ; - Assert.IsNotNull(testingTarget, "Can't create success object Accessibility"); - Assert.IsInstanceOf(testingTarget, "Should be an instance of Accessibility type."); - - tlog.Debug(tag, $"AccessibilityConstructor END (OK)"); - } - - [Test] - [Category("P1")] [Description("Accessibility GetStatus.")] [Property("SPEC", "Tizen.NUI.Accessibility.GetStatus M")] [Property("SPEC_URL", "-")] @@ -80,11 +62,7 @@ namespace Tizen.NUI.Devel.Tests { tlog.Debug(tag, $"AccessibilitySay START"); - var testingTarget = Accessibility.Accessibility.Instance; ; - Assert.IsNotNull(testingTarget, "Can't create success object Accessibility"); - Assert.IsInstanceOf(testingTarget, "Should be an instance of Accessibility type."); - - var result = testingTarget.Say("Hi,Bixby! Please help to order a sandwich.", true); + var result = Accessibility.Accessibility.Say("Hi,Bixby! Please help to order a sandwich.", true); tlog.Debug(tag, "Status : " + result); tlog.Debug(tag, $"AccessibilitySay END (OK)"); @@ -101,13 +79,9 @@ namespace Tizen.NUI.Devel.Tests { tlog.Debug(tag, $"AccessibilityPauseResume START"); - var testingTarget = Accessibility.Accessibility.Instance; ; - Assert.IsNotNull(testingTarget, "Can't create success object Accessibility"); - Assert.IsInstanceOf(testingTarget, "Should be an instance of Accessibility type."); - try { - testingTarget.PauseResume(true); + Accessibility.Accessibility.PauseResume(true); } catch (Exception e) { @@ -129,13 +103,9 @@ namespace Tizen.NUI.Devel.Tests { tlog.Debug(tag, $"AccessibilityStopReading START"); - var testingTarget = Accessibility.Accessibility.Instance; ; - Assert.IsNotNull(testingTarget, "Can't create success object Accessibility"); - Assert.IsInstanceOf(testingTarget, "Should be an instance of Accessibility type."); - try { - testingTarget.StopReading(true); + Accessibility.Accessibility.StopReading(true); } catch (Exception e) { @@ -157,13 +127,9 @@ namespace Tizen.NUI.Devel.Tests { tlog.Debug(tag, $"AccessibilitySuppressScreenReader START"); - var testingTarget = Accessibility.Accessibility.Instance; ; - Assert.IsNotNull(testingTarget, "Can't create success object Accessibility"); - Assert.IsInstanceOf(testingTarget, "Should be an instance of Accessibility type."); - try { - testingTarget.SuppressScreenReader(false); + Accessibility.Accessibility.SuppressScreenReader(false); } catch (Exception e) { @@ -233,10 +199,6 @@ namespace Tizen.NUI.Devel.Tests { tlog.Debug(tag, $"AccessibilitySetHighlightFrameView START"); - var testingTarget = Accessibility.Accessibility.Instance; ; - Assert.IsNotNull(testingTarget, "Can't create success object Accessibility"); - Assert.IsInstanceOf(testingTarget, "Should be an instance of Accessibility type."); - using (View view = new View()) { view.Size = new Size(100, 50); @@ -246,11 +208,11 @@ namespace Tizen.NUI.Devel.Tests try { - testingTarget.SetHighlightFrameView(view); + Accessibility.Accessibility.SetHighlightFrameView(view); - var result = testingTarget.GetHighlightFrameView(); + var result = Accessibility.Accessibility.GetHighlightFrameView(); tlog.Debug(tag, "HighlightFrameView : " + result); - tlog.Debug(tag, "ClearCurrentlyHighlightedView : " + testingTarget.ClearCurrentlyHighlightedView()); + tlog.Debug(tag, "ClearCurrentlyHighlightedView : " + Accessibility.Accessibility.ClearCurrentlyHighlightedView()); } catch (Exception e) { @@ -275,12 +237,8 @@ namespace Tizen.NUI.Devel.Tests { tlog.Debug(tag, $"AccessibilitySayFinished START"); - var testingTarget = Accessibility.Accessibility.Instance; - Assert.IsNotNull(testingTarget, "Can't create success object Accessibility"); - Assert.IsInstanceOf(testingTarget, "Should be an instance of Accessibility type."); - - testingTarget.SayFinished += OnSayFinished; - testingTarget.SayFinished -= OnSayFinished; + Accessibility.Accessibility.SayFinished += OnSayFinished; + Accessibility.Accessibility.SayFinished -= OnSayFinished; tlog.Debug(tag, $"AccessibilitySayFinished END (OK)"); }