diff --git a/src/Tizen.NUI/src/public/BaseComponents/ImageView.cs b/src/Tizen.NUI/src/public/BaseComponents/ImageView.cs index af61687e383..95ecb539ff3 100755 --- a/src/Tizen.NUI/src/public/BaseComponents/ImageView.cs +++ b/src/Tizen.NUI/src/public/BaseComponents/ImageView.cs @@ -1344,13 +1344,15 @@ internal override void ApplyCornerRadius() if (backgroundExtraData == null) return; - // Update corner radius properties to image by ActionUpdateProperty - if (backgroundExtraData.CornerRadius != null) + if (backgroundExtraDataUpdatedFlag.HasFlag(BackgroundExtraDataUpdatedFlag.ContentsCornerRadius)) { - Interop.View.InternalUpdateVisualPropertyVector4(this.SwigCPtr, ImageView.Property.IMAGE, Visual.Property.CornerRadius, Vector4.getCPtr(backgroundExtraData.CornerRadius)); + if (backgroundExtraData.CornerRadius != null) + { + Interop.View.InternalUpdateVisualPropertyVector4(this.SwigCPtr, ImageView.Property.IMAGE, Visual.Property.CornerRadius, Vector4.getCPtr(backgroundExtraData.CornerRadius)); + } + Interop.View.InternalUpdateVisualPropertyInt(this.SwigCPtr, ImageView.Property.IMAGE, Visual.Property.CornerRadiusPolicy, (int)backgroundExtraData.CornerRadiusPolicy); } - Interop.View.InternalUpdateVisualPropertyInt(this.SwigCPtr, ImageView.Property.IMAGE, Visual.Property.CornerRadiusPolicy, (int)backgroundExtraData.CornerRadiusPolicy); } internal override void ApplyBorderline() @@ -1359,11 +1361,13 @@ internal override void ApplyBorderline() if (backgroundExtraData == null) return; - - // Update borderline properties to image by ActionUpdateProperty - Interop.View.InternalUpdateVisualPropertyFloat(this.SwigCPtr, ImageView.Property.IMAGE, Visual.Property.BorderlineWidth, backgroundExtraData.BorderlineWidth); - Interop.View.InternalUpdateVisualPropertyVector4(this.SwigCPtr, ImageView.Property.IMAGE, Visual.Property.BorderlineColor, Vector4.getCPtr(backgroundExtraData.BorderlineColor ?? Color.Black)); - Interop.View.InternalUpdateVisualPropertyFloat(this.SwigCPtr, ImageView.Property.IMAGE, Visual.Property.BorderlineOffset, backgroundExtraData.BorderlineOffset); + if (backgroundExtraDataUpdatedFlag.HasFlag(BackgroundExtraDataUpdatedFlag.ContentsBorderline)) + { + // Update borderline properties to image by ActionUpdateProperty + Interop.View.InternalUpdateVisualPropertyFloat(this.SwigCPtr, ImageView.Property.IMAGE, Visual.Property.BorderlineWidth, backgroundExtraData.BorderlineWidth); + Interop.View.InternalUpdateVisualPropertyVector4(this.SwigCPtr, ImageView.Property.IMAGE, Visual.Property.BorderlineColor, Vector4.getCPtr(backgroundExtraData.BorderlineColor ?? Color.Black)); + Interop.View.InternalUpdateVisualPropertyFloat(this.SwigCPtr, ImageView.Property.IMAGE, Visual.Property.BorderlineOffset, backgroundExtraData.BorderlineOffset); + } } internal ResourceLoadingStatusType GetResourceStatus() @@ -1633,6 +1637,10 @@ protected virtual void UpdateImage() } } + // We already applied background extra data now. + backgroundExtraDataUpdatedFlag &= ~BackgroundExtraDataUpdatedFlag.ContentsCornerRadius; + backgroundExtraDataUpdatedFlag &= ~BackgroundExtraDataUpdatedFlag.ContentsBorderline; + // Do Fitting Buffer when desired dimension is set // TODO : Couldn't we do this job in dali-engine side. if (_desired_width != -1 && _desired_height != -1) diff --git a/src/Tizen.NUI/src/public/BaseComponents/ViewBindableProperty.cs b/src/Tizen.NUI/src/public/BaseComponents/ViewBindableProperty.cs index ac40787b648..6fb7c5484a8 100755 --- a/src/Tizen.NUI/src/public/BaseComponents/ViewBindableProperty.cs +++ b/src/Tizen.NUI/src/public/BaseComponents/ViewBindableProperty.cs @@ -291,6 +291,14 @@ public partial class View view.backgroundExtraData = null; + // Background extra data is not valid anymore. We should ignore lazy UpdateBackgroundExtraData + view.backgroundExtraDataUpdatedFlag = BackgroundExtraDataUpdatedFlag.None; + if (view.backgroundExtraDataUpdateProcessAttachedFlag) + { + ProcessorController.Instance.ProcessorOnceEvent -= view.UpdateBackgroundExtraData; + view.backgroundExtraDataUpdateProcessAttachedFlag = false; + } + propertyValue.Dispose(); propertyValue = null; } @@ -298,6 +306,10 @@ public partial class View defaultValueCreator: (bindable) => { var view = (View)bindable; + + // Sync as current properties + view?.UpdateBackgroundExtraData(); + PropertyMap tmp = new PropertyMap(); var propertyValue = Object.GetProperty(view.SwigCPtr, Property.BACKGROUND); propertyValue.Get(tmp); @@ -1876,6 +1888,9 @@ public partial class View { var view = (View)bindable; + // Sync as current properties + view?.UpdateBackgroundExtraData(); + PropertyMap map = new PropertyMap(); Tizen.NUI.Object.GetProperty((System.Runtime.InteropServices.HandleRef)view.SwigCPtr, View.Property.SHADOW).Get(map); @@ -1907,6 +1922,9 @@ public partial class View { var view = (View)bindable; + // Sync as current properties + view?.UpdateBackgroundExtraData(); + PropertyMap map = new PropertyMap(); Tizen.NUI.Object.GetProperty((System.Runtime.InteropServices.HandleRef)view.SwigCPtr, View.Property.SHADOW).Get(map); @@ -1922,7 +1940,7 @@ public partial class View { var view = (View)bindable; (view.backgroundExtraData ?? (view.backgroundExtraData = new BackgroundExtraData())).CornerRadius = (Vector4)newValue; - view.ApplyCornerRadius(); + view.UpdateBackgroundExtraData(BackgroundExtraDataUpdatedFlag.CornerRadius); }, defaultValueCreator: (bindable) => { @@ -1941,7 +1959,7 @@ public partial class View if (view.backgroundExtraData.CornerRadius != null) { - view.ApplyCornerRadius(); + view.UpdateBackgroundExtraData(BackgroundExtraDataUpdatedFlag.CornerRadius); } }, defaultValueCreator: (bindable) => @@ -1958,7 +1976,7 @@ public partial class View { var view = (View)bindable; (view.backgroundExtraData ?? (view.backgroundExtraData = new BackgroundExtraData())).BorderlineWidth = (float)newValue; - view.ApplyBorderline(); + view.UpdateBackgroundExtraData(BackgroundExtraDataUpdatedFlag.Borderline); }, defaultValueCreator: (bindable) => { @@ -2032,7 +2050,7 @@ public partial class View { var view = (View)bindable; (view.backgroundExtraData ?? (view.backgroundExtraData = new BackgroundExtraData())).BorderlineOffset = (float)newValue; - view.ApplyBorderline(); + view.UpdateBackgroundExtraData(BackgroundExtraDataUpdatedFlag.Borderline); }, defaultValueCreator: (bindable) => { @@ -2576,6 +2594,8 @@ private void SetBackgroundImage(string value) { if (string.IsNullOrEmpty(value)) { + backgroundExtraDataUpdatedFlag &= ~BackgroundExtraDataUpdatedFlag.Background; + var empty = new PropertyValue(); // Clear background Object.SetProperty(SwigCPtr, Property.BACKGROUND, empty); @@ -2629,6 +2649,8 @@ private void SetBackgroundImage(string value) map.Add(Visual.Property.Type, imageType); } + backgroundExtraDataUpdatedFlag &= ~BackgroundExtraDataUpdatedFlag.Background; + var mapValue = new PropertyValue(map); Object.SetProperty(SwigCPtr, Property.BACKGROUND, mapValue); @@ -2679,6 +2701,9 @@ private void SetBackgroundImageBorder(Rectangle value) map[Visual.Property.Type] = new PropertyValue((int)Visual.Type.NPatch); } + // Background extra data flag is not meanful anymore. + backgroundExtraDataUpdatedFlag &= ~BackgroundExtraDataUpdatedFlag.Background; + Tizen.NUI.Object.SetProperty((System.Runtime.InteropServices.HandleRef)SwigCPtr, View.Property.BACKGROUND, new PropertyValue(map)); } @@ -2691,7 +2716,7 @@ private void SetBorderlineColor(Color value) (backgroundExtraData ?? (backgroundExtraData = new BackgroundExtraData())).BorderlineColor = value; - ApplyBorderline(); + UpdateBackgroundExtraData(BackgroundExtraDataUpdatedFlag.Borderline); } private void SetBackgroundColor(Color value) @@ -2727,6 +2752,8 @@ private void SetBackgroundColor(Color value) .Add(Visual.Property.BorderlineColor, borderlineColor) .Add(Visual.Property.BorderlineOffset, borderlineOffset); + backgroundExtraDataUpdatedFlag &= ~BackgroundExtraDataUpdatedFlag.Background; + var mapValue = new PropertyValue(map); Object.SetProperty(SwigCPtr, Property.BACKGROUND, mapValue); @@ -2803,6 +2830,7 @@ private void SetOpacity(float? value) private void SetShadow(ShadowBase value) { + backgroundExtraDataUpdatedFlag &= ~BackgroundExtraDataUpdatedFlag.Shadow; Tizen.NUI.Object.SetProperty((System.Runtime.InteropServices.HandleRef)SwigCPtr, View.Property.SHADOW, value == null ? new PropertyValue() : value.ToPropertyValue(this)); } } diff --git a/src/Tizen.NUI/src/public/BaseComponents/ViewInternal.cs b/src/Tizen.NUI/src/public/BaseComponents/ViewInternal.cs index dc168bb438d..49a346e3c65 100755 --- a/src/Tizen.NUI/src/public/BaseComponents/ViewInternal.cs +++ b/src/Tizen.NUI/src/public/BaseComponents/ViewInternal.cs @@ -30,6 +30,29 @@ public partial class View { internal string styleName; + [Flags] + internal enum BackgroundExtraDataUpdatedFlag : byte + { + BackgroundCornerRadius = 1 << 0, + BackgroundBorderline = 1 << 1, + ShadowCornerRadius = 1 << 2, + ContentsCornerRadius = 1 << 3, /// Subclass cases. + ContentsBorderline = 1 << 4, /// Subclass cases. + + Background = BackgroundCornerRadius | BackgroundBorderline, + Shadow = ShadowCornerRadius, + + CornerRadius = BackgroundCornerRadius | ShadowCornerRadius | ContentsCornerRadius, + Borderline = BackgroundBorderline | ContentsBorderline, + + None = 0, + All = Background | Shadow, + } + + internal BackgroundExtraDataUpdatedFlag backgroundExtraDataUpdatedFlag = BackgroundExtraDataUpdatedFlag.None; + + private bool backgroundExtraDataUpdateProcessAttachedFlag = false; + internal virtual LayoutItem CreateDefaultLayout() { return new AbsoluteLayout(); @@ -1058,12 +1081,21 @@ internal bool IsTopLevelView() /// internal bool IsBackgroundEmpty() { - int visualType = (int)Visual.Type.Invalid; Interop.View.InternalRetrievingVisualPropertyInt(this.SwigCPtr, Property.BACKGROUND, Visual.Property.Type, out visualType); return visualType == (int)Visual.Type.Invalid; } + /// + /// Check whether Current view don't has ShadowVisual or not. + /// + internal bool IsShadowEmpty() + { + int visualType = (int)Visual.Type.Invalid; + Interop.View.InternalRetrievingVisualPropertyInt(this.SwigCPtr, Property.SHADOW, Visual.Property.Type, out visualType); + return visualType == (int)Visual.Type.Invalid; + } + internal void SetKeyInputFocus() { Interop.ViewInternal.SetKeyInputFocus(SwigCPtr); @@ -1151,20 +1183,98 @@ internal ResourceLoadingStatusType GetBackgroundResourceStatus() return (ResourceLoadingStatusType)Interop.View.GetVisualResourceStatus(this.SwigCPtr, Property.BACKGROUND); } + /// + /// Lazy call to UpdateBackgroundExtraData. + /// Collect Properties need to be update, and set properties that starts the Processing. + /// + internal virtual void UpdateBackgroundExtraData(BackgroundExtraDataUpdatedFlag flag) + { + if (backgroundExtraData == null) + { + return; + } + + if (!backgroundExtraDataUpdatedFlag.HasFlag(flag)) + { + backgroundExtraDataUpdatedFlag |= flag; + if (!backgroundExtraDataUpdateProcessAttachedFlag) + { + backgroundExtraDataUpdateProcessAttachedFlag = true; + ProcessorController.Instance.ProcessorOnceEvent += UpdateBackgroundExtraData; + // Call process hardly. + ProcessorController.Instance.Awake(); + } + } + } + + /// + /// Callback function to Lazy UpdateBackgroundExtraData. + /// + private void UpdateBackgroundExtraData(object source, EventArgs e) + { + // Note : To allow event attachment during UpdateBackgroundExtraData, let we make flag as false before call UpdateBackgroundExtraData(). + backgroundExtraDataUpdateProcessAttachedFlag = false; + UpdateBackgroundExtraData(); + } + + /// + /// Update background extra data properties synchronously. + /// After call this API, All background extra data properties updated. + /// + internal virtual void UpdateBackgroundExtraData() + { + if (backgroundExtraData == null) + { + return; + } + + if (IsShadowEmpty()) + { + backgroundExtraDataUpdatedFlag &= ~BackgroundExtraDataUpdatedFlag.Shadow; + } + if (!Rectangle.IsNullOrZero(backgroundExtraData.BackgroundImageBorder)) + { + backgroundExtraDataUpdatedFlag &= ~BackgroundExtraDataUpdatedFlag.Background; + } + + if (backgroundExtraDataUpdatedFlag == BackgroundExtraDataUpdatedFlag.None) + { + return; + } + + if ((backgroundExtraDataUpdatedFlag & BackgroundExtraDataUpdatedFlag.Borderline) != BackgroundExtraDataUpdatedFlag.None) + { + ApplyBorderline(); + } + if ((backgroundExtraDataUpdatedFlag & BackgroundExtraDataUpdatedFlag.CornerRadius) != BackgroundExtraDataUpdatedFlag.None) + { + ApplyCornerRadius(); + } + backgroundExtraDataUpdatedFlag = BackgroundExtraDataUpdatedFlag.None; + } + /// TODO open as a protected level internal virtual void ApplyCornerRadius() { if (backgroundExtraData == null) return; - // Update corner radius properties to background and shadow by ActionUpdateProperty - if (backgroundExtraData.CornerRadius != null) + if (backgroundExtraDataUpdatedFlag.HasFlag(BackgroundExtraDataUpdatedFlag.BackgroundCornerRadius)) { - Interop.View.InternalUpdateVisualPropertyVector4(this.SwigCPtr, View.Property.BACKGROUND, Visual.Property.CornerRadius, Vector4.getCPtr(backgroundExtraData.CornerRadius)); - Interop.View.InternalUpdateVisualPropertyVector4(this.SwigCPtr, View.Property.SHADOW, Visual.Property.CornerRadius, Vector4.getCPtr(backgroundExtraData.CornerRadius)); + if (backgroundExtraData.CornerRadius != null) + { + Interop.View.InternalUpdateVisualPropertyVector4(this.SwigCPtr, View.Property.BACKGROUND, Visual.Property.CornerRadius, Vector4.getCPtr(backgroundExtraData.CornerRadius)); + } + Interop.View.InternalUpdateVisualPropertyInt(this.SwigCPtr, View.Property.BACKGROUND, Visual.Property.CornerRadiusPolicy, (int)backgroundExtraData.CornerRadiusPolicy); + } + if (backgroundExtraDataUpdatedFlag.HasFlag(BackgroundExtraDataUpdatedFlag.ShadowCornerRadius)) + { + if (backgroundExtraData.CornerRadius != null) + { + Interop.View.InternalUpdateVisualPropertyVector4(this.SwigCPtr, View.Property.SHADOW, Visual.Property.CornerRadius, Vector4.getCPtr(backgroundExtraData.CornerRadius)); + } + Interop.View.InternalUpdateVisualPropertyInt(this.SwigCPtr, View.Property.SHADOW, Visual.Property.CornerRadiusPolicy, (int)backgroundExtraData.CornerRadiusPolicy); } - Interop.View.InternalUpdateVisualPropertyInt(this.SwigCPtr, View.Property.BACKGROUND, Visual.Property.CornerRadiusPolicy, (int)backgroundExtraData.CornerRadiusPolicy); - Interop.View.InternalUpdateVisualPropertyInt(this.SwigCPtr, View.Property.SHADOW, Visual.Property.CornerRadiusPolicy, (int)backgroundExtraData.CornerRadiusPolicy); } /// TODO open as a protected level @@ -1172,7 +1282,6 @@ internal virtual void ApplyBorderline() { if (backgroundExtraData == null) return; - // ActionUpdateProperty works well only if BACKGROUND visual setup before. // If view don't have BACKGROUND visual, we set transparent background color in default. if (IsBackgroundEmpty()) @@ -1185,9 +1294,12 @@ internal virtual void ApplyBorderline() } // Update borderline properties to background by ActionUpdateProperty - Interop.View.InternalUpdateVisualPropertyFloat(this.SwigCPtr, View.Property.BACKGROUND, Visual.Property.BorderlineWidth, backgroundExtraData.BorderlineWidth); - Interop.View.InternalUpdateVisualPropertyVector4(this.SwigCPtr, View.Property.BACKGROUND, Visual.Property.BorderlineColor, Vector4.getCPtr(backgroundExtraData.BorderlineColor ?? Color.Black)); - Interop.View.InternalUpdateVisualPropertyFloat(this.SwigCPtr, View.Property.BACKGROUND, Visual.Property.BorderlineOffset, backgroundExtraData.BorderlineOffset); + if (backgroundExtraDataUpdatedFlag.HasFlag(BackgroundExtraDataUpdatedFlag.BackgroundBorderline)) + { + Interop.View.InternalUpdateVisualPropertyFloat(this.SwigCPtr, View.Property.BACKGROUND, Visual.Property.BorderlineWidth, backgroundExtraData.BorderlineWidth); + Interop.View.InternalUpdateVisualPropertyVector4(this.SwigCPtr, View.Property.BACKGROUND, Visual.Property.BorderlineColor, Vector4.getCPtr(backgroundExtraData.BorderlineColor ?? Color.Black)); + Interop.View.InternalUpdateVisualPropertyFloat(this.SwigCPtr, View.Property.BACKGROUND, Visual.Property.BorderlineOffset, backgroundExtraData.BorderlineOffset); + } } /// @@ -1335,6 +1447,13 @@ protected override void Dispose(DisposeTypes type) view.InternalParent = null; } + backgroundExtraDataUpdatedFlag = BackgroundExtraDataUpdatedFlag.None; + if (backgroundExtraDataUpdateProcessAttachedFlag) + { + ProcessorController.Instance.ProcessorOnceEvent -= UpdateBackgroundExtraData; + backgroundExtraDataUpdateProcessAttachedFlag = false; + } + LayoutCount = 0; NUILog.Debug($"[Dispose] View.Dispose({type}) END");