[NUI] Do not set value of property again when theme is changed.
authorhuayong.xu <huayong.xu@samsung.com>
Tue, 22 Feb 2022 09:18:29 +0000 (17:18 +0800)
committerdongsug-song <35130733+dongsug-song@users.noreply.github.com>
Tue, 29 Mar 2022 03:10:12 +0000 (12:10 +0900)
Originally although property value of a view is set, if theme is
changed, the value would be restored to the default value.
This is not expected.
This patch is to check if the value has been set already or not,
if set, do not set the value again.

src/Tizen.NUI/src/public/BaseComponents/Style/ViewStyle.cs
src/Tizen.NUI/src/public/BaseComponents/View.cs
src/Tizen.NUI/src/public/XamlBinding/BindableObject.cs
test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/ThemeChangeSample.cs [new file with mode: 0755]

index f605db8..73d0beb 100755 (executable)
@@ -576,7 +576,7 @@ namespace Tizen.NUI.BaseComponents
 
                 if (destinationProperty != null)
                 {
-                    SetValue(destinationProperty, sourceValue);
+                    InternalSetValue(destinationProperty, sourceValue);
                 }
             }
 
index 18ceac8..d14a94c 100755 (executable)
@@ -47,6 +47,7 @@ namespace Tizen.NUI.BaseComponents
         private LayoutTransition layoutTransition;
         private TransitionOptions transitionOptions = null;
         private ThemeData themeData;
+        private bool isThemeChanged = false;
 
         // List of constraints
         private Constraint widthConstraint = null;
@@ -3056,8 +3057,10 @@ namespace Tizen.NUI.BaseComponents
         [EditorBrowsable(EditorBrowsableState.Never)]
         protected virtual void OnThemeChanged(object sender, ThemeChangedEventArgs e)
         {
+            isThemeChanged = true;
             if (string.IsNullOrEmpty(styleName)) ApplyStyle(ThemeManager.GetUpdateStyleWithoutClone(GetType()));
             else ApplyStyle(ThemeManager.GetUpdateStyleWithoutClone(styleName));
+            isThemeChanged = false;
         }
 
         /// <summary>
@@ -3100,9 +3103,15 @@ namespace Tizen.NUI.BaseComponents
 
                 bindablePropertyOfView.TryGetValue(sourceProperty.PropertyName, out var destinationProperty);
 
+                // Do not set value again when theme is changed and the value has been set already.
+                if (isThemeChanged && ChangedPropertiesSetExcludingStyle.Contains(destinationProperty))
+                {
+                    continue;
+                }
+
                 if (destinationProperty != null)
                 {
-                    SetValue(destinationProperty, sourceValue);
+                    InternalSetValue(destinationProperty, sourceValue);
                 }
             }
         }
index 9bac951..90b709b 100755 (executable)
@@ -94,13 +94,13 @@ namespace Tizen.NUI.Binding
                 {
                     nameToBindableProperty2.TryGetValue(keyValuePair.Key, out var bindableProperty);
 
-                    if (null != bindableProperty && (SettedPropeties.Contains(bindableProperty) || other.SettedPropeties.Contains(bindableProperty)))
+                    if (null != bindableProperty && (ChangedPropertiesSet.Contains(bindableProperty) || other.ChangedPropertiesSet.Contains(bindableProperty)))
                     {
                         object value = other.GetValue(bindableProperty);
 
                         if (null != value)
                         {
-                            SetValue(keyValuePair.Value, value);
+                            InternalSetValue(keyValuePair.Value, value);
                         }
                     }
                 }
@@ -268,6 +268,12 @@ namespace Tizen.NUI.Binding
         [EditorBrowsable(EditorBrowsableState.Never)]
         public void SetValue(BindableProperty property, object value)
         {
+            InternalSetValue(property, value);
+            ChangedPropertiesSetExcludingStyle.Add(property);
+        }
+
+        internal void InternalSetValue(BindableProperty property, object value)
+        {
             if (true == IsBinded)
             {
                 SetValue(property, value, false, true);
@@ -300,20 +306,34 @@ namespace Tizen.NUI.Binding
                 OnPropertyChangedWithData(property);
             }
 
-            SettedPropeties.Add(property);
+            ChangedPropertiesSet.Add(property);
+        }
+
+        private HashSet<BindableProperty> changedPropertiesSet;
+        private HashSet<BindableProperty> ChangedPropertiesSet
+        {
+            get
+            {
+                if (null == changedPropertiesSet)
+                {
+                    changedPropertiesSet = new HashSet<BindableProperty>();
+                }
+
+                return changedPropertiesSet;
+            }
         }
 
-        private HashSet<BindableProperty> settedPropeties;
-        private HashSet<BindableProperty> SettedPropeties
+        private HashSet<BindableProperty> changedPropertiesSetExcludingStyle;
+        internal protected HashSet<BindableProperty> ChangedPropertiesSetExcludingStyle
         {
             get
             {
-                if (null == settedPropeties)
+                if (null == changedPropertiesSetExcludingStyle)
                 {
-                    settedPropeties = new HashSet<BindableProperty>();
+                    changedPropertiesSetExcludingStyle = new HashSet<BindableProperty>();
                 }
 
-                return settedPropeties;
+                return changedPropertiesSetExcludingStyle;
             }
         }
 
diff --git a/test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/ThemeChangeSample.cs b/test/Tizen.NUI.Samples/Tizen.NUI.Samples/Samples/ThemeChangeSample.cs
new file mode 100755 (executable)
index 0000000..3410d04
--- /dev/null
@@ -0,0 +1,181 @@
+using System;
+using System.Linq;
+using Tizen.NUI.Components;
+using Tizen.NUI.BaseComponents;
+using Tizen.Applications.ThemeManager;
+
+namespace Tizen.NUI.Samples
+{
+    public class ThemeChangeSample : IExample
+    {
+        private ThemeLoader themeLoader;
+
+        public void Activate()
+        {
+            themeLoader = new ThemeLoader();
+
+            var mainPage = new ContentPage()
+            {
+                ThemeChangeSensitive = true,
+                AppBar = new AppBar()
+                {
+                    AutoNavigationContent = false,
+                    Title = "NUI theme sample",
+                    //Actions = new View[] { closeButton },
+                },
+                Content = new ScrollableBase()
+                {
+                    Layout = new LinearLayout()
+                    {
+                        LinearOrientation = LinearLayout.Orientation.Vertical,
+                        CellPadding = new Size2D(20, 20)
+                    },
+                    WidthResizePolicy = ResizePolicyType.FillToParent,
+                    HeightResizePolicy = ResizePolicyType.FillToParent,
+                    Padding = new Extents(30, 30, 20, 20)
+                }
+            };
+
+            string[] ids = (string[])themeLoader.QueryIds();
+            if (ids != null && ids.Contains("org.tizen.default-dark-theme") || ids.Contains("org.tizen.default-light-theme"))
+            {
+                var title = $"Current theme: {(themeLoader.CurrentTheme.Id == "org.tizen.default-dark-theme" ? "Dark" : "Light")}";
+
+                mainPage.Content.Add(CreateClickableItem("Theme change", title, delegate (View view)
+                {
+                    TextLabel text = view.Children[1] as TextLabel;
+
+                    if (themeLoader.CurrentTheme.Id == "org.tizen.default-dark-theme")
+                    {
+                        var theme = themeLoader.LoadTheme("org.tizen.default-light-theme");
+                        Tizen.Log.Info("test", $"Id: {theme.Id}, Version: {theme.Version}");
+                        themeLoader.CurrentTheme = theme;
+                        text.Text = "Current theme: Light";
+                    }
+                    else
+                    {
+                        var theme = themeLoader.LoadTheme("org.tizen.default-dark-theme");
+                        Tizen.Log.Info("test", $"Id: {theme.Id}, Version: {theme.Version}");
+                        themeLoader.CurrentTheme = theme;
+                        text.Text = "Current theme: Dark";
+                    }
+                }));
+
+                mainPage.Content.Add(CreateItem("Switch", CreateSwitchExample()));
+            }
+            else
+            {
+                mainPage.AppBar.Title = "No proper theme is found!";
+            }
+
+            NUIApplication.GetDefaultWindow().GetDefaultNavigator().Push(mainPage);
+        }
+
+        public void Deactivate()
+        {
+            NUIApplication.GetDefaultWindow().GetDefaultNavigator().Pop();
+
+            themeLoader.Dispose();
+            themeLoader = null;
+        }
+
+        private View CreateItem(string title, View content)
+        {
+            var item = new View()
+            {
+                WidthResizePolicy = ResizePolicyType.FillToParent,
+                HeightResizePolicy = ResizePolicyType.FitToChildren,
+                Layout = new LinearLayout()
+                {
+                    LinearOrientation = LinearLayout.Orientation.Vertical,
+                },
+                BackgroundColor = new Color("#88888860"),
+                CornerRadius = 16.0f,
+                Padding = 20,
+            };
+            item.Add(new TextLabel()
+            {
+                PixelSize = 22.0f,
+                Text = title,
+                Padding = new Extents(0, 0, 0, 20)
+            });
+            item.Add(content);
+            return item;
+        }
+
+        private View CreateClickableItem(string title, string subtitle, Action<View> clicked)
+        {
+            var item = new View()
+            {
+                WidthResizePolicy = ResizePolicyType.FillToParent,
+                HeightResizePolicy = ResizePolicyType.FitToChildren,
+                Layout = new LinearLayout()
+                {
+                    LinearOrientation = LinearLayout.Orientation.Vertical,
+                },
+                BackgroundColor = new Color("#88888860"),
+                CornerRadius = 16.0f,
+                Padding = 20,
+                LeaveRequired = true,
+            };
+            item.TouchEvent += (s, e) => {
+                var state = e.Touch.GetState(0);
+                if (state == PointStateType.Down)
+                {
+                    ((View)s).BackgroundColor = new Color("#888888BB");
+                }
+                else if (state == PointStateType.Up)
+                {
+                    ((View)s).BackgroundColor = new Color("#88888860");
+                    clicked?.Invoke(item);
+                }
+                else if (state == PointStateType.Leave || state == PointStateType.Interrupted)
+                {
+                    ((View)s).BackgroundColor = new Color("#88888860");
+                }
+                return true;
+            };
+            item.Add(new TextLabel()
+            {
+                PixelSize = 22.0f,
+                Text = title,
+                Padding = new Extents(0, 0, 0, 20)
+            });
+            item.Add(new TextLabel()
+            {
+                PixelSize = 32.0f,
+                Text = subtitle,
+                VerticalAlignment = VerticalAlignment.Center,
+            });
+            return item;
+        }
+
+        private View CreateSwitchExample()
+        {
+            var view = new View()
+            {
+                WidthResizePolicy = ResizePolicyType.FillToParent,
+                HeightResizePolicy = ResizePolicyType.FitToChildren,
+            };
+            var textLabel = new TextLabel()
+            {
+                Text = "Auto update : on",
+                TextColor = Color.Red,
+            };
+            view.Add(textLabel);
+
+            var switchButton = new Switch()
+            {
+                ParentOrigin = ParentOrigin.CenterRight,
+                PivotPoint = PivotPoint.CenterRight,
+                PositionUsesPivotPoint = true,
+                IsSelected = true,
+            };
+            switchButton.SelectedChanged += (s, e) => {
+                textLabel.Text = $"Daily auto update : {(((Switch)s).IsSelected ? "on" : "off")}";
+            };
+            view.Add(switchButton);
+            return view;
+        }
+    }
+}