addMethod?.Invoke(source, new[] { value });
return;
}
- if (xpe == null && Context.Types[parentElement].GetRuntimeMethods().Any(mi => mi.Name == "Add" && mi.GetParameters().Length == 1))
+ if (xpe == null && Context.Types[parentElement].GetRuntimeMethods().Any
+ (mi => mi.Name == "Add" && mi.GetParameters().Length == 1 && mi.GetParameters()[0].ParameterType.IsAssignableFrom(value.GetType())))
{
//if there are similar parameters in the function, this will exist issue.
var addMethod = Context.Types[parentElement].GetRuntimeMethods().First(mi => mi.Name == "Add" && mi.GetParameters().Length == 1);
MethodInfo addMethod;
if (xpe == null && (addMethod = collection.GetType().GetRuntimeMethods().First(mi => mi.Name == "Add" && mi.GetParameters().Length == 1)) != null)
{
- addMethod.Invoke(collection, new[] { Values[node] });
+ addMethod.Invoke(collection, new[] { value });
return;
}
xpe = xpe ?? new XamlParseException($"Value of {parentList.XmlName.LocalName} does not have a Add() method", node);
if (converterTypeName == null)
{
- converterTypeName = toType.FullName + "TypeConverter";
+ if (toType == typeof(Type))
+ {
+ converterTypeName = typeof(TypeTypeConverter).FullName;
+ }
+ else
+ {
+ converterTypeName = toType.FullName + "TypeConverter";
+ }
}
var convertertype = Type.GetType(converterTypeName);
--- /dev/null
+/*
+ * Copyright(c) 2021 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using Tizen.NUI;
+using Tizen.NUI.Binding;
+
+namespace Tizen.NUI.Xaml
+{
+ [RuntimeNameProperty(nameof(Name))]
+ internal sealed class VisualState
+ {
+ public VisualState()
+ {
+ Setters = new ObservableCollection<Setter>();
+ }
+
+ public string Name { get; set; }
+ public IList<Setter> Setters { get; }
+ public Type TargetType { get; set; }
+
+ internal VisualState Clone()
+ {
+ var clone = new VisualState { Name = Name, TargetType = TargetType };
+ foreach (var setter in Setters)
+ {
+ clone.Setters.Add(setter);
+ }
+
+ return clone;
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright(c) 2021 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using Tizen.NUI;
+using Tizen.NUI.Binding;
+
+namespace Tizen.NUI.Xaml
+{
+ [RuntimeNameProperty(nameof(Name))]
+ [ContentProperty(nameof(States))]
+ internal sealed class VisualStateGroup
+ {
+ public VisualStateGroup()
+ {
+ States = new WatchAddList<VisualState>(OnStatesChanged);
+ }
+
+ public Type TargetType { get; set; }
+ public string Name { get; set; }
+ public IList<VisualState> States { get; }
+ public VisualState CurrentState { get; internal set; }
+
+ internal VisualState GetState(string name)
+ {
+ foreach (VisualState state in States)
+ {
+ if (string.CompareOrdinal(state.Name, name) == 0)
+ {
+ return state;
+ }
+ }
+
+ return null;
+ }
+
+ internal VisualStateGroup Clone()
+ {
+ var clone = new VisualStateGroup { TargetType = TargetType, Name = Name, CurrentState = CurrentState };
+ foreach (VisualState state in States)
+ {
+ clone.States.Add(state.Clone());
+ }
+
+ return clone;
+ }
+
+ internal event EventHandler StatesChanged;
+
+ void OnStatesChanged(IList<VisualState> list)
+ {
+ if (list.Any(state => string.IsNullOrEmpty(state.Name)))
+ {
+ throw new InvalidOperationException("State names may not be null or empty");
+ }
+
+ StatesChanged?.Invoke(this, EventArgs.Empty);
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright(c) 2021 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using Tizen.NUI;
+using Tizen.NUI.Binding;
+
+namespace Tizen.NUI.Xaml
+{
+ internal class VisualStateGroupList : IList<VisualStateGroup>
+ {
+ readonly IList<VisualStateGroup> _internalList;
+
+ void Validate(IList<VisualStateGroup> groups)
+ {
+ // If we have 1 group, no need to worry about duplicate group names
+ if (groups.Count > 1)
+ {
+ if (groups.GroupBy(vsg => vsg.Name).Any(g => g.Count() > 1))
+ {
+ throw new InvalidOperationException("VisualStateGroup Names must be unique");
+ }
+ }
+
+ // State names must be unique within this group list, so pull in all
+ // the states in all the groups, group them by name, and see if we have
+ // and duplicates
+ if (groups.SelectMany(group => group.States).GroupBy(state => state.Name).Any(g => g.Count() > 1))
+ {
+ throw new InvalidOperationException("VisualState Names must be unique");
+ }
+ }
+
+ public VisualStateGroupList()
+ {
+ _internalList = new WatchAddList<VisualStateGroup>(Validate);
+ }
+
+ void ValidateOnStatesChanged(object sender, EventArgs eventArgs)
+ {
+ Validate(_internalList);
+ }
+
+ public IEnumerator<VisualStateGroup> GetEnumerator()
+ {
+ return _internalList.GetEnumerator();
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return ((IEnumerable)_internalList).GetEnumerator();
+ }
+
+ public void Add(VisualStateGroup item)
+ {
+ _internalList.Add(item);
+ item.StatesChanged += ValidateOnStatesChanged;
+ }
+
+ public void Clear()
+ {
+ foreach (var group in _internalList)
+ {
+ group.StatesChanged -= ValidateOnStatesChanged;
+ }
+
+ _internalList.Clear();
+ }
+
+ public bool Contains(VisualStateGroup item)
+ {
+ return _internalList.Contains(item);
+ }
+
+ public void CopyTo(VisualStateGroup[] array, int arrayIndex)
+ {
+ _internalList.CopyTo(array, arrayIndex);
+ }
+
+ public bool Remove(VisualStateGroup item)
+ {
+ item.StatesChanged -= ValidateOnStatesChanged;
+ return _internalList.Remove(item);
+ }
+
+ public int Count => _internalList.Count;
+
+ public bool IsReadOnly => false;
+
+ public int IndexOf(VisualStateGroup item)
+ {
+ return _internalList.IndexOf(item);
+ }
+
+ public void Insert(int index, VisualStateGroup item)
+ {
+ item.StatesChanged += ValidateOnStatesChanged;
+ _internalList.Insert(index, item);
+ }
+
+ public void RemoveAt(int index)
+ {
+ _internalList[index].StatesChanged -= ValidateOnStatesChanged;
+ _internalList.RemoveAt(index);
+ }
+
+ public VisualStateGroup this[int index]
+ {
+ get => _internalList[index];
+ set => _internalList[index] = value;
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright(c) 2021 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using Tizen.NUI;
+using Tizen.NUI.Binding;
+
+namespace Tizen.NUI.Xaml
+{
+ internal static class VisualStateGroupListExtensions
+ {
+ internal static IList<VisualStateGroup> Clone(this IList<VisualStateGroup> groups)
+ {
+ var actual = new VisualStateGroupList();
+ foreach (var group in groups)
+ {
+ actual.Add(group.Clone());
+ }
+
+ return actual;
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright(c) 2021 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using Tizen.NUI;
+using Tizen.NUI.Binding;
+
+namespace Tizen.NUI.Xaml
+{
+ internal static class VisualStateManager
+ {
+ internal class CommonStates
+ {
+ public const string Normal = "Normal";
+ public const string Disabled = "Disabled";
+ public const string Focused = "Focused";
+ }
+
+ private static VisualStateGroupList visualStateGroups;
+ public static readonly BindableProperty VisualStateGroupsProperty =
+ BindableProperty.CreateAttached("VisualStateGroups", typeof(VisualStateGroupList), typeof(/*VisualElement*/BaseHandle),
+ defaultValue: null, propertyChanged: VisualStateGroupsPropertyChanged,
+ defaultValueCreator: (BindableObject obj)=>
+ {
+ if (null == visualStateGroups)
+ {
+ visualStateGroups = new VisualStateGroupList();
+ }
+
+ return visualStateGroups;
+ });
+
+ static void VisualStateGroupsPropertyChanged(BindableObject bindable, object oldValue, object newValue)
+ {
+ GoToState((/*VisualElement*/BaseHandle)bindable, CommonStates.Normal);
+ }
+
+ public static IList<VisualStateGroup> GetVisualStateGroups(/*VisualElement*/BaseHandle visualElement)
+ {
+ return (IList<VisualStateGroup>)visualElement.GetValue(VisualStateGroupsProperty);
+ }
+
+ public static void SetVisualStateGroups(/*VisualElement*/BaseHandle visualElement, VisualStateGroupList value)
+ {
+ visualElement.SetValue(VisualStateGroupsProperty, value);
+ }
+
+ public static bool GoToState(/*VisualElement*/BaseHandle visualElement, string name)
+ {
+ if (!visualElement.IsSet(VisualStateGroupsProperty))
+ {
+ return false;
+ }
+
+ var groups = (IList<VisualStateGroup>)visualElement.GetValue(VisualStateGroupsProperty);
+
+ foreach (VisualStateGroup group in groups)
+ {
+ if (group.CurrentState?.Name == name)
+ {
+ // We're already in the target state; nothing else to do
+ return true;
+ }
+
+ // See if this group contains the new state
+ var target = group.GetState(name);
+ if (target == null)
+ {
+ continue;
+ }
+
+ // If we've got a new state to transition to, unapply the setters from the current state
+ if (group.CurrentState != null)
+ {
+ foreach (Setter setter in group.CurrentState.Setters)
+ {
+ setter.UnApply(visualElement);
+ }
+ }
+
+ // Update the current state
+ group.CurrentState = target;
+
+ // Apply the setters from the new state
+ foreach (Setter setter in target.Setters)
+ {
+ setter.Apply(visualElement);
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+
+ public static bool HasVisualStateGroups(this /*VisualElement*/BaseHandle element)
+ {
+ return element.IsSet(VisualStateGroupsProperty);
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright(c) 2021 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Linq;
+using Tizen.NUI;
+using Tizen.NUI.Binding;
+
+namespace Tizen.NUI.Xaml
+{
+ internal class WatchAddList<T> : IList<T>
+ {
+ readonly Action<List<T>> _onAdd;
+ readonly List<T> _internalList;
+
+ public WatchAddList(Action<List<T>> onAdd)
+ {
+ _onAdd = onAdd;
+ _internalList = new List<T>();
+ }
+
+ public IEnumerator<T> GetEnumerator()
+ {
+ return _internalList.GetEnumerator();
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return ((IEnumerable)_internalList).GetEnumerator();
+ }
+
+ public void Add(T item)
+ {
+ _internalList.Add(item);
+ _onAdd(_internalList);
+ }
+
+ public void Clear()
+ {
+ _internalList.Clear();
+ }
+
+ public bool Contains(T item)
+ {
+ return _internalList.Contains(item);
+ }
+
+ public void CopyTo(T[] array, int arrayIndex)
+ {
+ _internalList.CopyTo(array, arrayIndex);
+ }
+
+ public bool Remove(T item)
+ {
+ return _internalList.Remove(item);
+ }
+
+ public int Count => _internalList.Count;
+
+ public bool IsReadOnly => false;
+
+ public int IndexOf(T item)
+ {
+ return _internalList.IndexOf(item);
+ }
+
+ public void Insert(int index, T item)
+ {
+ _internalList.Insert(index, item);
+ _onAdd(_internalList);
+ }
+
+ public void RemoveAt(int index)
+ {
+ _internalList.RemoveAt(index);
+ }
+
+ public T this[int index]
+ {
+ get => _internalList[index];
+ set => _internalList[index] = value;
+ }
+ }
+}
+++ /dev/null
-/*
- * Copyright(c) 2021 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.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
-using System;
-using System.Collections;
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.Linq;
-using Tizen.NUI;
-using Tizen.NUI.Binding;
-
-namespace Tizen.NUI.Xaml
-{
- internal static class VisualStateManager
- {
- internal class CommonStates
- {
- public const string Normal = "Normal";
- public const string Disabled = "Disabled";
- public const string Focused = "Focused";
- }
-
- public static readonly BindableProperty VisualStateGroupsProperty =
- BindableProperty.CreateAttached("VisualStateGroups", typeof(VisualStateGroupList), typeof(/*VisualElement*/BaseHandle),
- defaultValue: null, propertyChanged: VisualStateGroupsPropertyChanged,
- defaultValueCreator: bindable => new VisualStateGroupList());
-
- static void VisualStateGroupsPropertyChanged(BindableObject bindable, object oldValue, object newValue)
- {
- GoToState((/*VisualElement*/BaseHandle)bindable, CommonStates.Normal);
- }
-
- public static IList<VisualStateGroup> GetVisualStateGroups(/*VisualElement*/BaseHandle visualElement)
- {
- return (IList<VisualStateGroup>)visualElement.GetValue(VisualStateGroupsProperty);
- }
-
- public static void SetVisualStateGroups(/*VisualElement*/BaseHandle visualElement, VisualStateGroupList value)
- {
- visualElement.SetValue(VisualStateGroupsProperty, value);
- }
-
- public static bool GoToState(/*VisualElement*/BaseHandle visualElement, string name)
- {
- if (!visualElement.IsSet(VisualStateGroupsProperty))
- {
- return false;
- }
-
- var groups = (IList<VisualStateGroup>)visualElement.GetValue(VisualStateGroupsProperty);
-
- foreach (VisualStateGroup group in groups)
- {
- if (group.CurrentState?.Name == name)
- {
- // We're already in the target state; nothing else to do
- return true;
- }
-
- // See if this group contains the new state
- var target = group.GetState(name);
- if (target == null)
- {
- continue;
- }
-
- // If we've got a new state to transition to, unapply the setters from the current state
- if (group.CurrentState != null)
- {
- foreach (Setter setter in group.CurrentState.Setters)
- {
- setter.UnApply(visualElement);
- }
- }
-
- // Update the current state
- group.CurrentState = target;
-
- // Apply the setters from the new state
- foreach (Setter setter in target.Setters)
- {
- setter.Apply(visualElement);
- }
-
- return true;
- }
-
- return false;
- }
-
- public static bool HasVisualStateGroups(this /*VisualElement*/BaseHandle element)
- {
- return element.IsSet(VisualStateGroupsProperty);
- }
- }
-
- internal class VisualStateGroupList : IList<VisualStateGroup>
- {
- readonly IList<VisualStateGroup> _internalList;
-
- void Validate(IList<VisualStateGroup> groups)
- {
- // If we have 1 group, no need to worry about duplicate group names
- if (groups.Count > 1)
- {
- if (groups.GroupBy(vsg => vsg.Name).Any(g => g.Count() > 1))
- {
- throw new InvalidOperationException("VisualStateGroup Names must be unique");
- }
- }
-
- // State names must be unique within this group list, so pull in all
- // the states in all the groups, group them by name, and see if we have
- // and duplicates
- if (groups.SelectMany(group => group.States)
- .GroupBy(state => state.Name)
- .Any(g => g.Count() > 1))
- {
- throw new InvalidOperationException("VisualState Names must be unique");
- }
- }
-
- public VisualStateGroupList()
- {
- _internalList = new WatchAddList<VisualStateGroup>(Validate);
- }
-
- void ValidateOnStatesChanged(object sender, EventArgs eventArgs)
- {
- Validate(_internalList);
- }
-
- public IEnumerator<VisualStateGroup> GetEnumerator()
- {
- return _internalList.GetEnumerator();
- }
-
- IEnumerator IEnumerable.GetEnumerator()
- {
- return ((IEnumerable)_internalList).GetEnumerator();
- }
-
- public void Add(VisualStateGroup item)
- {
- _internalList.Add(item);
- item.StatesChanged += ValidateOnStatesChanged;
- }
-
- public void Clear()
- {
- foreach (var group in _internalList)
- {
- group.StatesChanged -= ValidateOnStatesChanged;
- }
-
- _internalList.Clear();
- }
-
- public bool Contains(VisualStateGroup item)
- {
- return _internalList.Contains(item);
- }
-
- public void CopyTo(VisualStateGroup[] array, int arrayIndex)
- {
- _internalList.CopyTo(array, arrayIndex);
- }
-
- public bool Remove(VisualStateGroup item)
- {
- item.StatesChanged -= ValidateOnStatesChanged;
- return _internalList.Remove(item);
- }
-
- public int Count => _internalList.Count;
-
- public bool IsReadOnly => false;
-
- public int IndexOf(VisualStateGroup item)
- {
- return _internalList.IndexOf(item);
- }
-
- public void Insert(int index, VisualStateGroup item)
- {
- item.StatesChanged += ValidateOnStatesChanged;
- _internalList.Insert(index, item);
- }
-
- public void RemoveAt(int index)
- {
- _internalList[index].StatesChanged -= ValidateOnStatesChanged;
- _internalList.RemoveAt(index);
- }
-
- public VisualStateGroup this[int index]
- {
- get => _internalList[index];
- set => _internalList[index] = value;
- }
- }
-
- [RuntimeNameProperty(nameof(Name))]
- [ContentProperty(nameof(States))]
- internal sealed class VisualStateGroup
- {
- public VisualStateGroup()
- {
- States = new WatchAddList<VisualState>(OnStatesChanged);
- }
-
- public Type TargetType { get; set; }
- public string Name { get; set; }
- public IList<VisualState> States { get; }
- public VisualState CurrentState { get; internal set; }
-
- internal VisualState GetState(string name)
- {
- foreach (VisualState state in States)
- {
- if (string.CompareOrdinal(state.Name, name) == 0)
- {
- return state;
- }
- }
-
- return null;
- }
-
- internal VisualStateGroup Clone()
- {
- var clone = new VisualStateGroup { TargetType = TargetType, Name = Name, CurrentState = CurrentState };
- foreach (VisualState state in States)
- {
- clone.States.Add(state.Clone());
- }
-
- return clone;
- }
-
- internal event EventHandler StatesChanged;
-
- void OnStatesChanged(IList<VisualState> list)
- {
- if (list.Any(state => string.IsNullOrEmpty(state.Name)))
- {
- throw new InvalidOperationException("State names may not be null or empty");
- }
-
- StatesChanged?.Invoke(this, EventArgs.Empty);
- }
- }
-
- [RuntimeNameProperty(nameof(Name))]
- internal sealed class VisualState
- {
- public VisualState()
- {
- Setters = new ObservableCollection<Setter>();
- }
-
- public string Name { get; set; }
- public IList<Setter> Setters { get; }
- public Type TargetType { get; set; }
-
- internal VisualState Clone()
- {
- var clone = new VisualState { Name = Name, TargetType = TargetType };
- foreach (var setter in Setters)
- {
- clone.Setters.Add(setter);
- }
-
- return clone;
- }
- }
-
- internal static class VisualStateGroupListExtensions
- {
- internal static IList<VisualStateGroup> Clone(this IList<VisualStateGroup> groups)
- {
- var actual = new VisualStateGroupList();
- foreach (var group in groups)
- {
- actual.Add(group.Clone());
- }
-
- return actual;
- }
- }
-
- internal class WatchAddList<T> : IList<T>
- {
- readonly Action<List<T>> _onAdd;
- readonly List<T> _internalList;
-
- public WatchAddList(Action<List<T>> onAdd)
- {
- _onAdd = onAdd;
- _internalList = new List<T>();
- }
-
- public IEnumerator<T> GetEnumerator()
- {
- return _internalList.GetEnumerator();
- }
-
- IEnumerator IEnumerable.GetEnumerator()
- {
- return ((IEnumerable)_internalList).GetEnumerator();
- }
-
- public void Add(T item)
- {
- _internalList.Add(item);
- _onAdd(_internalList);
- }
-
- public void Clear()
- {
- _internalList.Clear();
- }
-
- public bool Contains(T item)
- {
- return _internalList.Contains(item);
- }
-
- public void CopyTo(T[] array, int arrayIndex)
- {
- _internalList.CopyTo(array, arrayIndex);
- }
-
- public bool Remove(T item)
- {
- return _internalList.Remove(item);
- }
-
- public int Count => _internalList.Count;
-
- public bool IsReadOnly => false;
-
- public int IndexOf(T item)
- {
- return _internalList.IndexOf(item);
- }
-
- public void Insert(int index, T item)
- {
- _internalList.Insert(index, item);
- _onAdd(_internalList);
- }
-
- public void RemoveAt(int index)
- {
- _internalList.RemoveAt(index);
- }
-
- public T this[int index]
- {
- get => _internalList[index];
- set => _internalList[index] = value;
- }
- }
-}
--- /dev/null
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Reflection;
+using Tizen.NUI.StyleSheets;
+using Tizen.NUI.BaseComponents;
+
+namespace Tizen.NUI.Binding
+{
+ internal sealed class MergedStyle : IStyle
+ {
+ ////If the base type is one of these, stop registering dynamic resources further
+ ////The last one (typeof(Element)) is a safety guard as we might be creating VisualElement directly in internal code
+ static readonly IList<Type> s_stopAtTypes = new List<Type> { typeof(View), typeof(Element) };
+
+ IList<BindableProperty> _classStyleProperties;
+
+ readonly List<BindableProperty> _implicitStyles = new List<BindableProperty>();
+
+ IList<XamlStyle> _classStyles;
+
+ IStyle _implicitStyle;
+
+ IStyle _style;
+
+ IList<string> _styleClass;
+
+ public MergedStyle(Type targetType, BindableObject target)
+ {
+ Target = target;
+ TargetType = targetType;
+ RegisterImplicitStyles();
+ Apply(Target);
+ }
+
+ public IStyle Style
+ {
+ get { return _style; }
+ set { SetStyle(ImplicitStyle, ClassStyles, value); }
+ }
+
+ public IList<string> StyleClass
+ {
+ get { return _styleClass; }
+ set
+ {
+ if (_styleClass == value)
+ return;
+
+ if (_styleClass != null && _classStyles != null)
+ foreach (var classStyleProperty in _classStyleProperties)
+ Target.RemoveDynamicResource(classStyleProperty);
+
+ _styleClass = value;
+
+ if (_styleClass != null)
+ {
+ _classStyleProperties = new List<BindableProperty>();
+ foreach (var styleClass in _styleClass)
+ {
+ var classStyleProperty = BindableProperty.Create("ClassStyle", typeof(IList<XamlStyle>), typeof(View), default(IList<XamlStyle>),
+ propertyChanged: (bindable, oldvalue, newvalue) => ((View)bindable)._mergedStyle.OnClassStyleChanged());
+ _classStyleProperties.Add(classStyleProperty);
+ Target.OnSetDynamicResource(classStyleProperty, Tizen.NUI.Binding.XamlStyle.StyleClassPrefix + styleClass);
+ }
+ }
+ }
+ }
+
+ public BindableObject Target { get; }
+
+ IList<XamlStyle> ClassStyles
+ {
+ get { return _classStyles; }
+ set { SetStyle(ImplicitStyle, value, Style); }
+ }
+
+ IStyle ImplicitStyle
+ {
+ get { return _implicitStyle; }
+ set { SetStyle(value, ClassStyles, Style); }
+ }
+
+ public void Apply(BindableObject bindable)
+ {
+ ImplicitStyle?.Apply(bindable);
+ if (ClassStyles != null)
+ foreach (var classStyle in ClassStyles)
+ ((IStyle)classStyle)?.Apply(bindable);
+ Style?.Apply(bindable);
+ }
+
+ public Type TargetType { get; }
+
+ public void UnApply(BindableObject bindable)
+ {
+ Style?.UnApply(bindable);
+ if (ClassStyles != null)
+ foreach (var classStyle in ClassStyles)
+ ((IStyle)classStyle)?.UnApply(bindable);
+ ImplicitStyle?.UnApply(bindable);
+ }
+
+ void OnClassStyleChanged()
+ {
+ ClassStyles = _classStyleProperties.Select(p => (Target.GetValue(p) as IList<XamlStyle>)?.FirstOrDefault(s => s.CanBeAppliedTo(TargetType))).ToList();
+ }
+
+ void OnImplicitStyleChanged()
+ {
+ var first = true;
+ foreach (BindableProperty implicitStyleProperty in _implicitStyles)
+ {
+ var implicitStyle = (XamlStyle)Target.GetValue(implicitStyleProperty);
+ if (implicitStyle != null)
+ {
+ if (first || implicitStyle.ApplyToDerivedTypes)
+ {
+ ImplicitStyle = implicitStyle;
+ return;
+ }
+ }
+ first = false;
+ }
+ }
+
+ void RegisterImplicitStyles()
+ {
+ Type type = TargetType;
+ if (type == null)
+ {
+ return;
+ }
+ while (true)
+ {
+ BindableProperty implicitStyleProperty = BindableProperty.Create(nameof(ImplicitStyle), typeof(XamlStyle), typeof(View), default(XamlStyle),
+ propertyChanged: (bindable, oldvalue, newvalue) => OnImplicitStyleChanged());
+ _implicitStyles.Add(implicitStyleProperty);
+ Target.SetDynamicResource(implicitStyleProperty, type.FullName);
+ type = type.GetTypeInfo().BaseType;
+ if (s_stopAtTypes.Contains(type))
+ return;
+ }
+ }
+
+ void SetStyle(IStyle implicitStyle, IList<XamlStyle> classStyles, IStyle style)
+ {
+ bool shouldReApplyStyle = implicitStyle != ImplicitStyle || classStyles != ClassStyles || Style != style;
+ bool shouldReApplyClassStyle = implicitStyle != ImplicitStyle || classStyles != ClassStyles;
+ bool shouldReApplyImplicitStyle = implicitStyle != ImplicitStyle && (Style as XamlStyle == null || ((XamlStyle)Style).CanCascade);
+
+ if (shouldReApplyStyle)
+ Style?.UnApply(Target);
+ if (shouldReApplyClassStyle && ClassStyles != null)
+ foreach (var classStyle in ClassStyles)
+ ((IStyle)classStyle)?.UnApply(Target);
+ if (shouldReApplyImplicitStyle)
+ ImplicitStyle?.UnApply(Target);
+
+ _implicitStyle = implicitStyle;
+ _classStyles = classStyles;
+ _style = style;
+
+ if (shouldReApplyImplicitStyle)
+ ImplicitStyle?.Apply(Target);
+ if (shouldReApplyClassStyle && ClassStyles != null)
+ foreach (var classStyle in ClassStyles)
+ ((IStyle)classStyle)?.Apply(Target);
+ if (shouldReApplyStyle)
+ Style?.Apply(Target);
+ }
+ }
+}
\ No newline at end of file
--- /dev/null
+using System;
+using Tizen.NUI.Binding;
+
+namespace Tizen.NUI.StyleSheets
+{
+ internal interface IStyle
+ {
+ Type TargetType { get; }
+
+ void Apply(BindableObject bindable);
+ void UnApply(BindableObject bindable);
+ }
+}
using System.ComponentModel;
using System.Diagnostics;
using System.Runtime.CompilerServices;
+using Tizen.NUI.Binding;
namespace Tizen.NUI.BaseComponents
{
/// <since_tizen> 3 </since_tizen>
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 class ThemeData
{
[Flags]
remove { ValuesChanged -= value; }
}
+ internal void Add(XamlStyle style)
+ {
+ if (string.IsNullOrEmpty(style.Class))
+ Add(style.TargetType.FullName, style);
+ else
+ {
+ IList<XamlStyle> classes;
+ object outclasses;
+ if (!TryGetValue(XamlStyle.StyleClassPrefix + style.Class, out outclasses) || (classes = outclasses as IList<XamlStyle>) == null)
+ classes = new List<XamlStyle>();
+ classes.Add(style);
+ this[XamlStyle.StyleClassPrefix + style.Class] = classes;
+ }
+ }
+
/// 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 void Add(ResourceDictionary mergedResourceDictionary)
--- /dev/null
+using System;
+using System.Collections.Generic;
+using System.Reflection;
+using Tizen.NUI.StyleSheets;
+using System.ComponentModel;
+
+namespace Tizen.NUI.Binding
+{
+ /// <since_tizen> 6 </since_tizen>
+ /// This will be public opened in tizen_6.0 after ACR done. Before ACR, need to be hidden as inhouse API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ [ContentProperty("Setters")]
+ public sealed class XamlStyle : IStyle
+ {
+ internal const string StyleClassPrefix = "Tizen.NUI.Binding.StyleClass.";
+
+ readonly BindableProperty _basedOnResourceProperty = BindableProperty.CreateAttached("BasedOnResource", typeof(XamlStyle), typeof(XamlStyle), default(XamlStyle),
+ propertyChanged: OnBasedOnResourceChanged);
+
+ readonly List<WeakReference<BindableObject>> _targets = new List<WeakReference<BindableObject>>(4);
+
+ XamlStyle _basedOnStyle;
+
+ string _baseResourceKey;
+
+ IList<Behavior> _behaviors;
+
+ IList<TriggerBase> _triggers;
+
+ /// <since_tizen> 6 </since_tizen>
+ /// 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 XamlStyle([TypeConverter(typeof(TypeTypeConverter))][Parameter("TargetType")] Type targetType)
+ {
+ if (targetType == null)
+ throw new ArgumentNullException(nameof(targetType));
+
+ TargetType = targetType;
+ Setters = new List<Setter>();
+ }
+
+ /// <since_tizen> 6 </since_tizen>
+ /// 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 bool ApplyToDerivedTypes { get; set; }
+
+ /// <since_tizen> 6 </since_tizen>
+ /// 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 XamlStyle BasedOn
+ {
+ get { return _basedOnStyle; }
+ set
+ {
+ if (_basedOnStyle == value)
+ return;
+ if (!ValidateBasedOn(value))
+ throw new ArgumentException("BasedOn.TargetType is not compatible with TargetType");
+ XamlStyle oldValue = _basedOnStyle;
+ _basedOnStyle = value;
+ BasedOnChanged(oldValue, value);
+ if (value != null)
+ BaseResourceKey = null;
+ }
+ }
+
+ /// <since_tizen> 6 </since_tizen>
+ /// 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 string BaseResourceKey
+ {
+ get { return _baseResourceKey; }
+ set
+ {
+ if (_baseResourceKey == value)
+ return;
+ _baseResourceKey = value;
+ //update all DynamicResources
+ foreach (WeakReference<BindableObject> bindableWr in _targets)
+ {
+ BindableObject target;
+ if (!bindableWr.TryGetTarget(out target))
+ continue;
+ target.RemoveDynamicResource(_basedOnResourceProperty);
+ if (value != null)
+ target.SetDynamicResource(_basedOnResourceProperty, value);
+ }
+ if (value != null)
+ BasedOn = null;
+ }
+ }
+
+ internal IList<Behavior> Behaviors
+ {
+ get { return _behaviors ?? (_behaviors = new AttachedCollection<Behavior>()); }
+ }
+
+ /// 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 bool CanCascade { get; set; }
+
+ /// 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 string Class { get; set; }
+
+ /// 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 IList<Setter> Setters { get; }
+
+ /// This will be public opened in tizen_next after ACR done. Before ACR, need to be hidden as inhouse API.
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public IList<TriggerBase> Triggers
+ {
+ get { return _triggers ?? (_triggers = new AttachedCollection<TriggerBase>()); }
+ }
+
+ void IStyle.Apply(BindableObject bindable)
+ {
+ _targets.Add(new WeakReference<BindableObject>(bindable));
+ if (BaseResourceKey != null)
+ bindable.SetDynamicResource(_basedOnResourceProperty, BaseResourceKey);
+ ApplyCore(bindable, BasedOn ?? GetBasedOnResource(bindable));
+ }
+
+ /// <since_tizen> 6 </since_tizen>
+ /// 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 Type TargetType { get; }
+
+ void IStyle.UnApply(BindableObject bindable)
+ {
+ UnApplyCore(bindable, BasedOn ?? GetBasedOnResource(bindable));
+ bindable.RemoveDynamicResource(_basedOnResourceProperty);
+ _targets.RemoveAll(wr =>
+ {
+ BindableObject target;
+ return wr.TryGetTarget(out target) && target == bindable;
+ });
+ }
+
+ internal bool CanBeAppliedTo(Type targetType)
+ {
+ if (TargetType == targetType)
+ return true;
+ if (!ApplyToDerivedTypes)
+ return false;
+ do
+ {
+ targetType = targetType.GetTypeInfo().BaseType;
+ if (TargetType == targetType)
+ return true;
+ } while (targetType != typeof(Element));
+ return false;
+ }
+
+ void ApplyCore(BindableObject bindable, XamlStyle basedOn)
+ {
+ if (basedOn != null)
+ ((IStyle)basedOn).Apply(bindable);
+
+ foreach (Setter setter in Setters)
+ setter.Apply(bindable, true);
+ ((AttachedCollection<Behavior>)Behaviors).AttachTo(bindable);
+ ((AttachedCollection<TriggerBase>)Triggers).AttachTo(bindable);
+ }
+
+ void BasedOnChanged(XamlStyle oldValue, XamlStyle newValue)
+ {
+ foreach (WeakReference<BindableObject> bindableRef in _targets)
+ {
+ BindableObject bindable;
+ if (!bindableRef.TryGetTarget(out bindable))
+ continue;
+
+ UnApplyCore(bindable, oldValue);
+ ApplyCore(bindable, newValue);
+ }
+ }
+
+ XamlStyle GetBasedOnResource(BindableObject bindable)
+ {
+ return (XamlStyle)bindable.GetValue(_basedOnResourceProperty);
+ }
+
+ static void OnBasedOnResourceChanged(BindableObject bindable, object oldValue, object newValue)
+ {
+ // Style style = (bindable as /*VisualElement*/BaseHandle).Style;
+ // if (style == null)
+ // return;
+ // style.UnApplyCore(bindable, (Style)oldValue);
+ // style.ApplyCore(bindable, (Style)newValue);
+ }
+
+ void UnApplyCore(BindableObject bindable, XamlStyle basedOn)
+ {
+ ((AttachedCollection<TriggerBase>)Triggers).DetachFrom(bindable);
+ ((AttachedCollection<Behavior>)Behaviors).DetachFrom(bindable);
+ foreach (Setter setter in Setters)
+ setter.UnApply(bindable, true);
+
+ if (basedOn != null)
+ ((IStyle)basedOn).UnApply(bindable);
+ }
+
+ bool ValidateBasedOn(XamlStyle value)
+ {
+ if (value == null)
+ return true;
+ return value.TargetType.IsAssignableFrom(TargetType);
+ }
+ }
+}