From 825f1668e7c24e10f5ac385c10b6f1d0004dc049 Mon Sep 17 00:00:00 2001 From: s-fernandez-v Date: Wed, 15 Sep 2021 20:41:34 +0200 Subject: [PATCH] Updated to NoesisGUI 3.1.1 version --- .gitignore | 4 +- .../Core/Src/Core/ContentPropertyAttribute.cs | 3 +- Src/Noesis/Core/Src/Core/Events.cs | 28 +----- Src/Noesis/Core/Src/Core/Extend.cs | 39 +++++++- Src/Noesis/Core/Src/Core/ExtendImports.cs | 1 + .../Src/Core/StyleTypedPropertyAttribute.cs | 37 ++++++++ .../Core/Src/Core/TemplatePartAttribute.cs | 36 ++++++++ Src/Noesis/Core/Src/Proxies/BaseComponent.cs | 5 ++ .../Core/Src/Proxies/ColumnDefinition.cs | 7 ++ Src/Noesis/Core/Src/Proxies/ComboBox.cs | 18 ++++ .../Src/Proxies/DependencyObjectExtend.cs | 70 +++++++++++++++ .../Src/Proxies/DependencyPropertyExtend.cs | 36 ++++++-- .../Core/Src/Proxies/DynamicTextureSource.cs | 21 ++--- .../Core/Src/Proxies/FrameworkElement.cs | 26 ++++++ .../Src/Proxies/FrameworkElementExtend.cs | 4 + .../Core/Src/Proxies/NoesisGUI_PINVOKE.cs | 54 ++++++++++++ Src/Noesis/Core/Src/Proxies/PasswordBox.cs | 18 ++++ Src/Noesis/Core/Src/Proxies/RowDefinition.cs | 7 ++ Src/Noesis/Core/Src/Proxies/TextBox.cs | 18 ++++ .../Src/Interactivity/EventTriggerBase.cs | 72 +++++++++++---- .../Core/Src/Interactivity/GamepadTrigger.cs | 9 ++ .../Core/Src/Interactivity/KeyTrigger.cs | 9 ++ .../StoryboardCompletedTrigger.cs | 23 +---- .../Interactivity/TargetedTriggerAction.cs | 83 +++--------------- .../MediaPlayers/GE/Native/build_arm.sh | 4 +- .../GE/Native/libGEMediaPlayer.cpp | 7 +- Src/NoesisApp/MediaPlayers/GE/Native/mp | Bin 0 -> 25632 bytes Src/NoesisApp/MediaPlayers/GE/Native/mp.cpp | 70 +++++++++++++++ .../MediaPlayers/GE/Src/GEMediaPlayer.cs | 9 +- .../GE/runtimes/linux-arm64/native/mp | Bin 0 -> 25632 bytes 30 files changed, 549 insertions(+), 169 deletions(-) create mode 100644 Src/Noesis/Core/Src/Core/StyleTypedPropertyAttribute.cs create mode 100644 Src/Noesis/Core/Src/Core/TemplatePartAttribute.cs create mode 100644 Src/NoesisApp/MediaPlayers/GE/Native/mp create mode 100644 Src/NoesisApp/MediaPlayers/GE/runtimes/linux-arm64/native/mp diff --git a/.gitignore b/.gitignore index 8675a57..cd1cd03 100644 --- a/.gitignore +++ b/.gitignore @@ -244,4 +244,6 @@ project.lock.json Src/Samples/ BuildManagedSDK.py -Samples.sln \ No newline at end of file +Samples.sln + +Src/NoesisApp/Controls/* \ No newline at end of file diff --git a/Src/Noesis/Core/Src/Core/ContentPropertyAttribute.cs b/Src/Noesis/Core/Src/Core/ContentPropertyAttribute.cs index 99b0406..e4ca5d0 100644 --- a/Src/Noesis/Core/Src/Core/ContentPropertyAttribute.cs +++ b/Src/Noesis/Core/Src/Core/ContentPropertyAttribute.cs @@ -12,8 +12,7 @@ public sealed class ContentPropertyAttribute : Attribute /// Gets the name of the property that is the content property. /// The name of the property that is the content property. - public string Name { get{ return this._name; } - } + public string Name { get{ return this._name; } } /// Initializes a new instance of the ContentPropertyAttribute class. public ContentPropertyAttribute() { } diff --git a/Src/Noesis/Core/Src/Core/Events.cs b/Src/Noesis/Core/Src/Core/Events.cs index 7feccd8..5340604 100644 --- a/Src/Noesis/Core/Src/Core/Events.cs +++ b/Src/Noesis/Core/Src/Core/Events.cs @@ -168,7 +168,7 @@ public static void AddHandler(UIElement element, IntPtr routedEventPtr, Delegate { events = new EventHandlerStore(element); _elements.Add(ptr, events); - Noesis_Dependency_RegisterDestroyed(cPtr); + element.Destroyed += OnElementDestroyed; } long routedEventKey = routedEventPtr.ToInt64(); @@ -222,7 +222,7 @@ public static void RemoveHandler(UIElement element, IntPtr routedEventPtr, Deleg if (events._binds.Count == 0) { - Noesis_Dependency_UnregisterDestroyed(cPtr); + element.Destroyed -= OnElementDestroyed; _elements.Remove(ptr); } } @@ -302,7 +302,7 @@ public static void AddHandler(UIElement element, string eventId, Delegate handle { events = new EventHandlerStore(element); _elements.Add(ptr, events); - Noesis_Dependency_RegisterDestroyed(cPtr); + element.Destroyed += OnElementDestroyed; } long eventKey = eventId.GetHashCode(); @@ -362,7 +362,7 @@ public static void RemoveHandler(UIElement element, string eventId, Delegate han if (events._binds.Count == 0) { - Noesis_Dependency_UnregisterDestroyed(cPtr); + element.Destroyed -= OnElementDestroyed; _elements.Remove(ptr); } } @@ -416,11 +416,6 @@ private static void RaiseEvent(IntPtr cPtrType, IntPtr cPtr, string eventId, #endregion #region Private members - static EventHandlerStore() - { - Noesis_Dependency_SetDestroyedCallback(_destroyedCallback); - } - private EventHandlerStore(UIElement element) { _element = BaseComponent.getCPtr(element).Handle; @@ -446,14 +441,8 @@ internal static void Clear(EventHandlerStore[] events) View._Rendering.Clear(); } - private delegate void DestroyedCallback(IntPtr d); - private static DestroyedCallback _destroyedCallback = OnElementDestroyed; - - [MonoPInvokeCallback(typeof(DestroyedCallback))] private static void OnElementDestroyed(IntPtr d) { - Noesis_Dependency_UnregisterDestroyed(d); - EventHandlerStore events; long ptr = d.ToInt64(); if (_elements.TryGetValue(ptr, out events)) @@ -485,15 +474,6 @@ private static extern void Noesis_Event_Bind(RaiseEventCallback callback, [DllImport(Library.Name)] private static extern void Noesis_Event_Unbind(RaiseEventCallback callback, IntPtr element, [MarshalAs(UnmanagedType.LPWStr)]string eventId); - - [DllImport(Library.Name)] - private static extern void Noesis_Dependency_SetDestroyedCallback(DestroyedCallback callback); - - [DllImport(Library.Name)] - private static extern void Noesis_Dependency_RegisterDestroyed(IntPtr cPtr); - - [DllImport(Library.Name)] - private static extern void Noesis_Dependency_UnregisterDestroyed(IntPtr cPtr); #endregion } diff --git a/Src/Noesis/Core/Src/Core/Extend.cs b/Src/Noesis/Core/Src/Core/Extend.cs index bd56b5f..8640570 100644 --- a/Src/Noesis/Core/Src/Core/Extend.cs +++ b/Src/Noesis/Core/Src/Core/Extend.cs @@ -121,6 +121,7 @@ public static void RegisterCallbacks() _frameworkElementMeasure, _frameworkElementArrange, _frameworkElementConnectEvent, + _frameworkElementApplyTemplate, _freezableClone, _toString, @@ -250,7 +251,7 @@ public static void UnregisterCallbacks() Noesis_RegisterReflectionCallbacks( null, null, - null, null, null, null, null, + null, null, null, null, null, null, null, null, null, null, null, null, null, null, @@ -1174,7 +1175,8 @@ private enum ExtendTypeOverrides Measure = 8, Arrange = 16, Connect = 32, - Clone = 64 + Template = 64, + Clone = 128 } private struct ExtendPropertyData @@ -1491,6 +1493,9 @@ private static ExtendTypeData CreateNativeTypeData(System.Type type, IntPtr nati MethodInfo connectMethod = FindMethod(type, "ConnectEvent", new Type[] { typeof(object), typeof(string), typeof(string) }); if (IsOverride(connectMethod)) overrides |= ExtendTypeOverrides.Connect; + MethodInfo templateMethod = FindMethod(type, "OnApplyTemplate", new Type[] { }); + if (IsOverride(templateMethod)) overrides |= ExtendTypeOverrides.Template; + MethodInfo cloneMethod = FindMethod(type, "CloneCommonCore", new Type[] { typeof(Freezable) }); if (IsOverride(cloneMethod)) overrides |= ExtendTypeOverrides.Clone; @@ -1973,6 +1978,27 @@ private static bool FrameworkElementConnectEvent(IntPtr cPtr, return false; } + //////////////////////////////////////////////////////////////////////////////////////////////// + private delegate void Callback_FrameworkElementApplyTemplate(IntPtr cPtr); + private static Callback_FrameworkElementApplyTemplate _frameworkElementApplyTemplate = FrameworkElementApplyTemplate; + + [MonoPInvokeCallback(typeof(Callback_FrameworkElementApplyTemplate))] + private static void FrameworkElementApplyTemplate(IntPtr cPtr) + { + try + { + FrameworkElement element = (FrameworkElement)GetExtendInstance(cPtr); + if (element != null) + { + element.OnApplyTemplate(); + } + } + catch (Exception e) + { + Error.UnhandledException(e); + } + } + //////////////////////////////////////////////////////////////////////////////////////////////// private delegate void Callback_FreezableClone(IntPtr cPtrType, IntPtr cPtrClone, IntPtr cPtrSource); @@ -4940,10 +4966,10 @@ private static BaseComponent GetProxyInstance(IntPtr cPtr, bool ownMemory, Nativ return (BaseComponent)Binding.DoNothing; } - long ptr = cPtr.ToInt64(); lock (_proxies) { WeakReference wr; + long ptr = cPtr.ToInt64(); if (_proxies.TryGetValue(ptr, out wr)) { if (wr != null) @@ -4966,7 +4992,12 @@ private static BaseComponent GetProxyInstance(IntPtr cPtr, bool ownMemory, Nativ } } - return ((NativeTypeComponentInfo)info).Creator(cPtr, ownMemory); + if (BaseComponent.GetNumReferences(cPtr) > 0) + { + return ((NativeTypeComponentInfo)info).Creator(cPtr, ownMemory); + } + + return null; } //////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/Src/Noesis/Core/Src/Core/ExtendImports.cs b/Src/Noesis/Core/Src/Core/ExtendImports.cs index 52d16d7..c3361ef 100644 --- a/Src/Noesis/Core/Src/Core/ExtendImports.cs +++ b/Src/Noesis/Core/Src/Core/ExtendImports.cs @@ -54,6 +54,7 @@ static extern void Noesis_RegisterReflectionCallbacks( Callback_FrameworkElementMeasure callback_FrameworkElementMeasure, Callback_FrameworkElementArrange callback_FrameworkElementArrange, Callback_FrameworkElementConnectEvent callback_FrameworkElementConnectEvent, + Callback_FrameworkElementApplyTemplate callback_FrameworkElementApplyTemplate, Callback_FreezableClone callback_FreezableClone, Callback_ToString callback_ToString, Callback_Equals callback_Equals, diff --git a/Src/Noesis/Core/Src/Core/StyleTypedPropertyAttribute.cs b/Src/Noesis/Core/Src/Core/StyleTypedPropertyAttribute.cs new file mode 100644 index 0000000..c15ba8d --- /dev/null +++ b/Src/Noesis/Core/Src/Core/StyleTypedPropertyAttribute.cs @@ -0,0 +1,37 @@ +using System; + +namespace Noesis +{ + /// + /// This attribute is applied to the class and determine the target type which should be used for + /// the properties of type Style. The definition inherits to the subclasses or the derived class + /// can redefine the target type for the property already defined in the base class. + /// + [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] + public sealed class StyleTypedPropertyAttribute : Attribute + { + /// Default constructor + public StyleTypedPropertyAttribute() { } + + /// + /// The property name of type Style + /// + public string Property + { + get { return _property; } + set { _property = value; } + } + + /// + /// Target type of the Style that should be used for the Property + /// + public Type StyleTargetType + { + get { return _styleTargetType; } + set { _styleTargetType = value; } + } + + private string _property; + private Type _styleTargetType; + } +} diff --git a/Src/Noesis/Core/Src/Core/TemplatePartAttribute.cs b/Src/Noesis/Core/Src/Core/TemplatePartAttribute.cs new file mode 100644 index 0000000..a27892b --- /dev/null +++ b/Src/Noesis/Core/Src/Core/TemplatePartAttribute.cs @@ -0,0 +1,36 @@ +using System; + +namespace Noesis +{ + /// + /// Style authors should be able to identify the part type used for styling the specific class. + /// The part is usually required in the style and should have a specific predefined name. + /// + [AttributeUsage(AttributeTargets.Class, AllowMultiple = true)] + public sealed class TemplatePartAttribute : Attribute + { + /// Default constructor + public TemplatePartAttribute() { } + + /// + /// Part name used by the class to indentify required element in the style + /// + public string Name + { + get { return _name; } + set { _name = value; } + } + + /// + /// Type of the element that should be used as a part with specified name + /// + public Type Type + { + get { return _type; } + set { _type = value; } + } + + private string _name; + private Type _type; + } +} diff --git a/Src/Noesis/Core/Src/Proxies/BaseComponent.cs b/Src/Noesis/Core/Src/Proxies/BaseComponent.cs index f785f45..b3115cb 100644 --- a/Src/Noesis/Core/Src/Proxies/BaseComponent.cs +++ b/Src/Noesis/Core/Src/Proxies/BaseComponent.cs @@ -62,6 +62,11 @@ internal static void Release(IntPtr cPtr) { NoesisGUI_PINVOKE.BaseComponent_Release(cPtr); } + public static int GetNumReferences(IntPtr cPtr) { + int ret = NoesisGUI_PINVOKE.BaseComponent_GetNumReferences(cPtr); + return ret; + } + internal static IntPtr Extend(string typeName) { return NoesisGUI_PINVOKE.Extend_BaseComponent(Marshal.StringToHGlobalAnsi(typeName)); } diff --git a/Src/Noesis/Core/Src/Proxies/ColumnDefinition.cs b/Src/Noesis/Core/Src/Proxies/ColumnDefinition.cs index c78cc98..30b2258 100644 --- a/Src/Noesis/Core/Src/Proxies/ColumnDefinition.cs +++ b/Src/Noesis/Core/Src/Proxies/ColumnDefinition.cs @@ -93,6 +93,13 @@ protected override IntPtr CreateCPtr(Type type, out bool registerExtend) { } } + public new float ActualWidth { + get { + float ret = NoesisGUI_PINVOKE.ColumnDefinition_ActualWidth_get(swigCPtr); + return ret; + } + } + } } diff --git a/Src/Noesis/Core/Src/Proxies/ComboBox.cs b/Src/Noesis/Core/Src/Proxies/ComboBox.cs index d360d5f..e3b7dfc 100644 --- a/Src/Noesis/Core/Src/Proxies/ComboBox.cs +++ b/Src/Noesis/Core/Src/Proxies/ComboBox.cs @@ -72,6 +72,13 @@ public static DependencyProperty MaxDropDownHeightProperty { } } + public static DependencyProperty PlaceholderProperty { + get { + IntPtr cPtr = NoesisGUI_PINVOKE.ComboBox_PlaceholderProperty_get(); + return (DependencyProperty)Noesis.Extend.GetProxy(cPtr, false); + } + } + public static DependencyProperty SelectionBoxItemProperty { get { IntPtr cPtr = NoesisGUI_PINVOKE.ComboBox_SelectionBoxItemProperty_get(); @@ -175,6 +182,17 @@ public string Text { } } + public string Placeholder { + set { + NoesisGUI_PINVOKE.ComboBox_Placeholder_set(swigCPtr, value != null ? value : string.Empty); + } + get { + IntPtr strPtr = NoesisGUI_PINVOKE.ComboBox_Placeholder_get(swigCPtr); + string str = Noesis.Extend.StringFromNativeUtf8(strPtr); + return str; + } + } + internal new static IntPtr Extend(string typeName) { return NoesisGUI_PINVOKE.Extend_ComboBox(Marshal.StringToHGlobalAnsi(typeName)); } diff --git a/Src/Noesis/Core/Src/Proxies/DependencyObjectExtend.cs b/Src/Noesis/Core/Src/Proxies/DependencyObjectExtend.cs index c51de19..3b896ff 100644 --- a/Src/Noesis/Core/Src/Proxies/DependencyObjectExtend.cs +++ b/Src/Noesis/Core/Src/Proxies/DependencyObjectExtend.cs @@ -877,6 +877,69 @@ private struct EnumPropsInfo #endregion + #region Destroyed event + public delegate void DestroyedHandler(IntPtr d); + public event DestroyedHandler Destroyed + { + add + { + long ptr = swigCPtr.Handle.ToInt64(); + if (!_Destroyed.ContainsKey(ptr)) + { + _Destroyed.Add(ptr, null); + + Noesis_Dependency_Destroyed_Bind(_raiseDestroyed, swigCPtr); + } + + _Destroyed[ptr] += value; + } + remove + { + long ptr = swigCPtr.Handle.ToInt64(); + if (_Destroyed.ContainsKey(ptr)) + { + + _Destroyed[ptr] -= value; + + if (_Destroyed[ptr] == null) + { + Noesis_Dependency_Destroyed_Unbind(_raiseDestroyed, swigCPtr); + + _Destroyed.Remove(ptr); + } + } + } + } + + internal delegate void RaiseDestroyedCallback(IntPtr cPtr); + private static RaiseDestroyedCallback _raiseDestroyed = RaiseDestroyed; + + [MonoPInvokeCallback(typeof(RaiseDestroyedCallback))] + private static void RaiseDestroyed(IntPtr cPtr) + { + try + { + if (Noesis.Extend.Initialized) + { + long ptr = cPtr.ToInt64(); + DestroyedHandler handler = null; + if (_Destroyed.TryGetValue(ptr, out handler)) + { + handler?.Invoke(cPtr); + _Destroyed.Remove(ptr); + } + } + } + catch (Exception exception) + { + Noesis.Error.UnhandledException(exception); + } + } + + internal static Dictionary _Destroyed = + new Dictionary(); + #endregion + #region Imports //////////////////////////////////////////////////////////////////////////////////////////////// @@ -1043,6 +1106,13 @@ private static extern void Noesis_DependencySet_BaseComponent(IntPtr dependencyO private static extern void Noesis_Dependency_EnumProps(IntPtr dependencyObject, int id, NoesisEnumPropertiesCallback callback); + //////////////////////////////////////////////////////////////////////////////////////////////// + [DllImport(Library.Name)] + private static extern void Noesis_Dependency_Destroyed_Bind(RaiseDestroyedCallback callback, HandleRef instance); + + [DllImport(Library.Name)] + private static extern void Noesis_Dependency_Destroyed_Unbind(RaiseDestroyedCallback callback, HandleRef instance); + #endregion } diff --git a/Src/Noesis/Core/Src/Proxies/DependencyPropertyExtend.cs b/Src/Noesis/Core/Src/Proxies/DependencyPropertyExtend.cs index 7f57503..cca1b24 100644 --- a/Src/Noesis/Core/Src/Proxies/DependencyPropertyExtend.cs +++ b/Src/Noesis/Core/Src/Proxies/DependencyPropertyExtend.cs @@ -30,6 +30,23 @@ public static DependencyProperty RegisterAttached(string name, Type propertyType return RegisterCommon(name, propertyType, ownerType, defaultMetadata); } + public DependencyProperty AddOwner(Type ownerType) + { + return AddOwner(ownerType, null); + } + + public DependencyProperty AddOwner(Type ownerType, PropertyMetadata metadata) + { + if (metadata != null) + { + ValidateDefaultValue(Name, PropertyType, ownerType, metadata.DefaultValue); + } + + IntPtr ownerTypePtr = Noesis.Extend.EnsureNativeType(ownerType, false); + IntPtr dp = Noesis_AddOwnerDependencyProperty(swigCPtr, ownerTypePtr, PropertyMetadata.getCPtr(metadata)); + return new DependencyProperty(dp, false); + } + public void OverrideMetadata(Type forType, PropertyMetadata typeMetadata) { if (forType == null) @@ -52,8 +69,7 @@ public void OverrideMetadata(Type forType, PropertyMetadata typeMetadata) IntPtr forTypePtr = Noesis.Extend.EnsureNativeType(forType, false); - Noesis_OverrideMetadata(forTypePtr, swigCPtr.Handle, - PropertyMetadata.getCPtr(typeMetadata).Handle); + Noesis_OverrideMetadata(forTypePtr, swigCPtr, PropertyMetadata.getCPtr(typeMetadata)); DependencyPropertyRegistry.Override(this, forType, typeMetadata); } @@ -77,7 +93,7 @@ internal static DependencyProperty RegisterCommon(string name, Type propertyType // Create and register dependency property IntPtr dependencyPtr = Noesis_RegisterDependencyProperty(ownerTypePtr, - name, nativeType, PropertyMetadata.getCPtr(propertyMetadata).Handle); + name, nativeType, PropertyMetadata.getCPtr(propertyMetadata)); DependencyProperty dependencyProperty = existingProperty; if (!ReferenceEquals(dependencyProperty, null)) @@ -242,16 +258,18 @@ private static Dictionary CreateValidTypes() #region Imports - //////////////////////////////////////////////////////////////////////////////////////////////// [DllImport(Library.Name)] - private static extern IntPtr Noesis_RegisterDependencyProperty(IntPtr classType, + private static extern IntPtr Noesis_RegisterDependencyProperty(IntPtr ownerType, [MarshalAs(UnmanagedType.LPStr)]string propertyName, - IntPtr propertyType, IntPtr propertyMetadata); + IntPtr propertyType, HandleRef propertyMetadata); + + [DllImport(Library.Name)] + private static extern IntPtr Noesis_AddOwnerDependencyProperty(HandleRef source, + IntPtr ownerType, HandleRef propertyMetadata); - //////////////////////////////////////////////////////////////////////////////////////////////// [DllImport(Library.Name)] - private static extern void Noesis_OverrideMetadata(IntPtr classType, - IntPtr dependencyProperty, IntPtr propertyMetadata); + private static extern void Noesis_OverrideMetadata(IntPtr forType, + HandleRef dependencyProperty, HandleRef propertyMetadata); #endregion } diff --git a/Src/Noesis/Core/Src/Proxies/DynamicTextureSource.cs b/Src/Noesis/Core/Src/Proxies/DynamicTextureSource.cs index 53c6d88..be407c0 100644 --- a/Src/Noesis/Core/Src/Proxies/DynamicTextureSource.cs +++ b/Src/Noesis/Core/Src/Proxies/DynamicTextureSource.cs @@ -39,27 +39,22 @@ public DynamicTextureSource(uint width, uint height, TextureRenderCallback callb #region Private members private static IntPtr Create(uint width, uint height, TextureRenderCallback callback, object user) { - CallbackInfo info = new CallbackInfo { Callback = callback }; - int callbackId = info.GetHashCode(); - _callbacks[callbackId] = info; + int callbackId = CallbackId++; + _callbacks[callbackId] = callback; IntPtr userPtr = Noesis.Extend.GetInstanceHandle(user).Handle; return DynamicTextureSource_Create(width, height, callbackId, _removeCallback, _renderCallback, userPtr); } - private struct CallbackInfo { - public TextureRenderCallback Callback; - } - private delegate IntPtr NoesisTextureRenderCallback(int callbackId, IntPtr devicePtr, IntPtr userPtr); private static NoesisTextureRenderCallback _renderCallback = OnTextureRender; [MonoPInvokeCallback(typeof(NoesisTextureRenderCallback))] private static IntPtr OnTextureRender(int callbackId, IntPtr devicePtr, IntPtr userPtr) { try { if (Noesis.Extend.Initialized) { - CallbackInfo info = _callbacks[callbackId]; + TextureRenderCallback callback = _callbacks[callbackId]; RenderDevice device = (RenderDevice)Noesis.Extend.GetProxy(devicePtr, false); object user = Noesis.Extend.GetProxy(userPtr, false); - Texture texture = info.Callback(device, user); + Texture texture = callback(device, user); return Noesis.Extend.GetInstanceHandle(texture).Handle; } } @@ -81,7 +76,9 @@ private static void OnRemoveCallback(int callbackId) { } } - private static Dictionary _callbacks = new Dictionary(); + private static int CallbackId = 0; + private static Dictionary _callbacks = + new Dictionary(); [DllImport(Library.Name)] private static extern IntPtr DynamicTextureSource_Create(uint width, uint height, int callbackId, @@ -89,6 +86,10 @@ private static extern IntPtr DynamicTextureSource_Create(uint width, uint height #endregion + public void Resize(uint width, uint height) { + NoesisGUI_PINVOKE.DynamicTextureSource_Resize(swigCPtr, width, height); + } + public int PixelWidth { get { int ret = NoesisGUI_PINVOKE.DynamicTextureSource_PixelWidth_get(swigCPtr); diff --git a/Src/Noesis/Core/Src/Proxies/FrameworkElement.cs b/Src/Noesis/Core/Src/Proxies/FrameworkElement.cs index d8c1e64..a4fcdc5 100644 --- a/Src/Noesis/Core/Src/Proxies/FrameworkElement.cs +++ b/Src/Noesis/Core/Src/Proxies/FrameworkElement.cs @@ -142,6 +142,15 @@ protected override IntPtr CreateCPtr(Type type, out bool registerExtend) { } } + public static FlowDirection GetFlowDirection(DependencyObject d) { + FlowDirection ret = (FlowDirection)NoesisGUI_PINVOKE.FrameworkElement_GetFlowDirection(DependencyObject.getCPtr(d)); + return ret; + } + + public static void SetFlowDirection(DependencyObject d, FlowDirection flowDirection) { + NoesisGUI_PINVOKE.FrameworkElement_SetFlowDirection(DependencyObject.getCPtr(d), (int)flowDirection); + } + public BindingExpression GetBindingExpression(DependencyProperty dp) { IntPtr cPtr = NoesisGUI_PINVOKE.FrameworkElement_GetBindingExpression(swigCPtr, DependencyProperty.getCPtr(dp)); return (BindingExpression)Noesis.Extend.GetProxy(cPtr, false); @@ -252,6 +261,13 @@ public static DependencyProperty DefaultStyleKeyProperty { } } + public static DependencyProperty FlowDirectionProperty { + get { + IntPtr cPtr = NoesisGUI_PINVOKE.FrameworkElement_FlowDirectionProperty_get(); + return (DependencyProperty)Noesis.Extend.GetProxy(cPtr, false); + } + } + public static DependencyProperty FocusVisualStyleProperty { get { IntPtr cPtr = NoesisGUI_PINVOKE.FrameworkElement_FocusVisualStyleProperty_get(); @@ -537,6 +553,16 @@ public Type DefaultStyleKey { } } + public FlowDirection FlowDirection { + set { + NoesisGUI_PINVOKE.FrameworkElement_FlowDirection_set(swigCPtr, (int)value); + } + get { + FlowDirection ret = (FlowDirection)NoesisGUI_PINVOKE.FrameworkElement_FlowDirection_get(swigCPtr); + return ret; + } + } + public Style FocusVisualStyle { set { NoesisGUI_PINVOKE.FrameworkElement_FocusVisualStyle_set(swigCPtr, Style.getCPtr(value)); diff --git a/Src/Noesis/Core/Src/Proxies/FrameworkElementExtend.cs b/Src/Noesis/Core/Src/Proxies/FrameworkElementExtend.cs index 7fddb1f..f93597a 100644 --- a/Src/Noesis/Core/Src/Proxies/FrameworkElementExtend.cs +++ b/Src/Noesis/Core/Src/Proxies/FrameworkElementExtend.cs @@ -56,6 +56,10 @@ internal protected virtual bool ConnectEvent(object source, string eventName, st return false; } + internal protected virtual void OnApplyTemplate() + { + } + #region FindResource implementation private object FindResourceHelper(string key) diff --git a/Src/Noesis/Core/Src/Proxies/NoesisGUI_PINVOKE.cs b/Src/Noesis/Core/Src/Proxies/NoesisGUI_PINVOKE.cs index 0508ce5..be2d40d 100644 --- a/Src/Noesis/Core/Src/Proxies/NoesisGUI_PINVOKE.cs +++ b/Src/Noesis/Core/Src/Proxies/NoesisGUI_PINVOKE.cs @@ -384,6 +384,9 @@ internal class NoesisGUI_PINVOKE { [DllImport(Library.Name)] public static extern void BaseComponent_Release(IntPtr jarg1); + [DllImport(Library.Name)] + public static extern int BaseComponent_GetNumReferences(IntPtr jarg1); + [DllImport(Library.Name)] public static extern IntPtr Bool_GetStaticType(); @@ -1362,6 +1365,9 @@ internal class NoesisGUI_PINVOKE { [DllImport(Library.Name)] public static extern IntPtr TextureSource_Texture_get(HandleRef jarg1); + [DllImport(Library.Name)] + public static extern void DynamicTextureSource_Resize(HandleRef jarg1, uint jarg2, uint jarg3); + [DllImport(Library.Name)] public static extern int DynamicTextureSource_PixelWidth_get(HandleRef jarg1); @@ -4826,6 +4832,12 @@ internal class NoesisGUI_PINVOKE { [DllImport(Library.Name)] public static extern IntPtr new_FrameworkElement(); + [DllImport(Library.Name)] + public static extern int FrameworkElement_GetFlowDirection(HandleRef jarg1); + + [DllImport(Library.Name)] + public static extern void FrameworkElement_SetFlowDirection(HandleRef jarg1, int jarg2); + [DllImport(Library.Name)] public static extern IntPtr FrameworkElement_GetBindingExpression(HandleRef jarg1, HandleRef jarg2); @@ -4888,6 +4900,9 @@ internal class NoesisGUI_PINVOKE { [DllImport(Library.Name)] public static extern IntPtr FrameworkElement_DefaultStyleKeyProperty_get(); + [DllImport(Library.Name)] + public static extern IntPtr FrameworkElement_FlowDirectionProperty_get(); + [DllImport(Library.Name)] public static extern IntPtr FrameworkElement_FocusVisualStyleProperty_get(); @@ -5017,6 +5032,12 @@ internal class NoesisGUI_PINVOKE { [DllImport(Library.Name)] public static extern IntPtr FrameworkElement_DefaultStyleKey_get(HandleRef jarg1); + [DllImport(Library.Name)] + public static extern void FrameworkElement_FlowDirection_set(HandleRef jarg1, int jarg2); + + [DllImport(Library.Name)] + public static extern int FrameworkElement_FlowDirection_get(HandleRef jarg1); + [DllImport(Library.Name)] public static extern void FrameworkElement_FocusVisualStyle_set(HandleRef jarg1, HandleRef jarg2); @@ -7101,6 +7122,9 @@ internal class NoesisGUI_PINVOKE { [DllImport(Library.Name)] public static extern IntPtr ComboBox_MaxDropDownHeightProperty_get(); + [DllImport(Library.Name)] + public static extern IntPtr ComboBox_PlaceholderProperty_get(); + [DllImport(Library.Name)] public static extern IntPtr ComboBox_SelectionBoxItemProperty_get(); @@ -7159,6 +7183,12 @@ internal class NoesisGUI_PINVOKE { [DllImport(Library.Name)] public static extern IntPtr ComboBox_Text_get(HandleRef jarg1); + [DllImport(Library.Name)] + public static extern void ComboBox_Placeholder_set(HandleRef jarg1, [MarshalAs(UnmanagedType.LPWStr)]string jarg2); + + [DllImport(Library.Name)] + public static extern IntPtr ComboBox_Placeholder_get(HandleRef jarg1); + [DllImport(Library.Name)] public static extern void CanExecuteRoutedEventArgs_CanExecute_set(HandleRef jarg1, bool jarg2); @@ -7874,6 +7904,9 @@ internal class NoesisGUI_PINVOKE { [DllImport(Library.Name)] public static extern float ColumnDefinition_MaxWidth_get(HandleRef jarg1); + [DllImport(Library.Name)] + public static extern float ColumnDefinition_ActualWidth_get(HandleRef jarg1); + [DllImport(Library.Name)] public static extern IntPtr new_ColumnDefinitionCollection(); @@ -7907,6 +7940,9 @@ internal class NoesisGUI_PINVOKE { [DllImport(Library.Name)] public static extern float RowDefinition_MinHeight_get(HandleRef jarg1); + [DllImport(Library.Name)] + public static extern float RowDefinition_ActualHeight_get(HandleRef jarg1); + [DllImport(Library.Name)] public static extern IntPtr new_RowDefinitionCollection(); @@ -8466,6 +8502,9 @@ internal class NoesisGUI_PINVOKE { [DllImport(Library.Name)] public static extern IntPtr PasswordBox_PasswordCharProperty_get(); + [DllImport(Library.Name)] + public static extern IntPtr PasswordBox_PlaceholderProperty_get(); + [DllImport(Library.Name)] public static extern IntPtr PasswordBox_SelectionBrushProperty_get(); @@ -8511,6 +8550,12 @@ internal class NoesisGUI_PINVOKE { [DllImport(Library.Name)] public static extern float PasswordBox_SelectionOpacity_get(HandleRef jarg1); + [DllImport(Library.Name)] + public static extern void PasswordBox_Placeholder_set(HandleRef jarg1, [MarshalAs(UnmanagedType.LPWStr)]string jarg2); + + [DllImport(Library.Name)] + public static extern IntPtr PasswordBox_Placeholder_get(HandleRef jarg1); + [DllImport(Library.Name)] public static extern IntPtr new_Popup(); @@ -10021,6 +10066,9 @@ internal class NoesisGUI_PINVOKE { [DllImport(Library.Name)] public static extern IntPtr TextBox_MinLinesProperty_get(); + [DllImport(Library.Name)] + public static extern IntPtr TextBox_PlaceholderProperty_get(); + [DllImport(Library.Name)] public static extern IntPtr TextBox_TextAlignmentProperty_get(); @@ -10093,6 +10141,12 @@ internal class NoesisGUI_PINVOKE { [DllImport(Library.Name)] public static extern IntPtr TextBox_TextView_get(HandleRef jarg1); + [DllImport(Library.Name)] + public static extern void TextBox_Placeholder_set(HandleRef jarg1, [MarshalAs(UnmanagedType.LPWStr)]string jarg2); + + [DllImport(Library.Name)] + public static extern IntPtr TextBox_Placeholder_get(HandleRef jarg1); + [DllImport(Library.Name)] [return: MarshalAs(UnmanagedType.U1)] public static extern bool DragCompletedEventArgs_Canceled_get(HandleRef jarg1); diff --git a/Src/Noesis/Core/Src/Proxies/PasswordBox.cs b/Src/Noesis/Core/Src/Proxies/PasswordBox.cs index 0e65892..e48dd94 100644 --- a/Src/Noesis/Core/Src/Proxies/PasswordBox.cs +++ b/Src/Noesis/Core/Src/Proxies/PasswordBox.cs @@ -81,6 +81,13 @@ public static DependencyProperty PasswordCharProperty { } } + public static DependencyProperty PlaceholderProperty { + get { + IntPtr cPtr = NoesisGUI_PINVOKE.PasswordBox_PlaceholderProperty_get(); + return (DependencyProperty)Noesis.Extend.GetProxy(cPtr, false); + } + } + public static DependencyProperty SelectionBrushProperty { get { IntPtr cPtr = NoesisGUI_PINVOKE.PasswordBox_SelectionBrushProperty_get(); @@ -163,6 +170,17 @@ public float SelectionOpacity { } } + public string Placeholder { + set { + NoesisGUI_PINVOKE.PasswordBox_Placeholder_set(swigCPtr, value != null ? value : string.Empty); + } + get { + IntPtr strPtr = NoesisGUI_PINVOKE.PasswordBox_Placeholder_get(swigCPtr); + string str = Noesis.Extend.StringFromNativeUtf8(strPtr); + return str; + } + } + internal new static IntPtr Extend(string typeName) { return NoesisGUI_PINVOKE.Extend_PasswordBox(Marshal.StringToHGlobalAnsi(typeName)); } diff --git a/Src/Noesis/Core/Src/Proxies/RowDefinition.cs b/Src/Noesis/Core/Src/Proxies/RowDefinition.cs index 0e732fb..b6d1f1c 100644 --- a/Src/Noesis/Core/Src/Proxies/RowDefinition.cs +++ b/Src/Noesis/Core/Src/Proxies/RowDefinition.cs @@ -93,6 +93,13 @@ protected override IntPtr CreateCPtr(Type type, out bool registerExtend) { } } + public new float ActualHeight { + get { + float ret = NoesisGUI_PINVOKE.RowDefinition_ActualHeight_get(swigCPtr); + return ret; + } + } + } } diff --git a/Src/Noesis/Core/Src/Proxies/TextBox.cs b/Src/Noesis/Core/Src/Proxies/TextBox.cs index cb3b849..c9d81cf 100644 --- a/Src/Noesis/Core/Src/Proxies/TextBox.cs +++ b/Src/Noesis/Core/Src/Proxies/TextBox.cs @@ -121,6 +121,13 @@ public static DependencyProperty MinLinesProperty { } } + public static DependencyProperty PlaceholderProperty { + get { + IntPtr cPtr = NoesisGUI_PINVOKE.TextBox_PlaceholderProperty_get(); + return (DependencyProperty)Noesis.Extend.GetProxy(cPtr, false); + } + } + public static DependencyProperty TextAlignmentProperty { get { IntPtr cPtr = NoesisGUI_PINVOKE.TextBox_TextAlignmentProperty_get(); @@ -251,6 +258,17 @@ public Visual TextView { } } + public string Placeholder { + set { + NoesisGUI_PINVOKE.TextBox_Placeholder_set(swigCPtr, value != null ? value : string.Empty); + } + get { + IntPtr strPtr = NoesisGUI_PINVOKE.TextBox_Placeholder_get(swigCPtr); + string str = Noesis.Extend.StringFromNativeUtf8(strPtr); + return str; + } + } + internal new static IntPtr Extend(string typeName) { return NoesisGUI_PINVOKE.Extend_TextBox(Marshal.StringToHGlobalAnsi(typeName)); } diff --git a/Src/NoesisApp/Core/Src/Interactivity/EventTriggerBase.cs b/Src/NoesisApp/Core/Src/Interactivity/EventTriggerBase.cs index 025fa8b..12a4dca 100644 --- a/Src/NoesisApp/Core/Src/Interactivity/EventTriggerBase.cs +++ b/Src/NoesisApp/Core/Src/Interactivity/EventTriggerBase.cs @@ -142,8 +142,12 @@ private void UpdateSource(object associatedObject) newSource.GetType(), GetType())); } + UnregisterSource(oldSource); + _source = GetPtr(newSource); + RegisterSource(newSource); + if (AssociatedObject != null) { OnSourceChangedImpl(oldSource, newSource); @@ -151,19 +155,6 @@ private void UpdateSource(object associatedObject) } } - private struct EventWrapper - { - public WeakReference weak; - - public static readonly MethodInfo InvokeMethod = typeof(EventWrapper).GetMethod( - "Invoke", BindingFlags.Instance | BindingFlags.NonPublic); - - private void Invoke(object sender, Noesis.EventArgs e) - { - ((EventTriggerBase)weak.Target)?.OnEventImpl(sender, e); - } - } - private void RegisterEvent(object source, string eventName) { if (source != null && !string.IsNullOrEmpty(eventName)) @@ -190,12 +181,12 @@ private void RegisterEvent(object source, string eventName) eventName)); } } - - EventWrapper wrapper = new EventWrapper { weak = new WeakReference(this) }; - - _event = ev; - _handler = Delegate.CreateDelegate(ev.EventHandlerType, wrapper, EventWrapper.InvokeMethod); - _event.AddEventHandler(source, _handler); + else + { + _event = ev; + _handler = Delegate.CreateDelegate(ev.EventHandlerType, this, OnEventMethod); + _event.AddEventHandler(source, _handler); + } } } @@ -228,6 +219,42 @@ private static bool IsValidEvent(EventInfo eventInfo) return false; } + #region Source registration + private void RegisterSource(object source) + { + if (source is DependencyObject) + { + DependencyObject dob = (DependencyObject)source; + dob.Destroyed += OnSourceDestroyed; + } + else + { + _keepSource = source; + } + } + + private void UnregisterSource(object source) + { + if (source is DependencyObject) + { + DependencyObject dob = (DependencyObject)source; + dob.Destroyed -= OnSourceDestroyed; + } + else + { + _keepSource = source; + } + } + + private void OnSourceDestroyed(IntPtr d) + { + _source = IntPtr.Zero; + _event = null; + _handler = null; + } + #endregion + + #region SourceName resolver public object SourceNameResolver { get { return GetValue(SourceNameResolverProperty); } @@ -245,11 +272,18 @@ static void OnSourceNameResolverChanged(DependencyObject d, DependencyPropertyCh trigger.UpdateSource(trigger.AssociatedObject); } } + #endregion + + #region Private members + public static readonly MethodInfo OnEventMethod = typeof(EventTriggerBase).GetMethod( + "OnEventImpl", BindingFlags.Instance | BindingFlags.NonPublic); Type _sourceType; IntPtr _source; + object _keepSource; Delegate _handler; EventInfo _event; + #endregion } public abstract class EventTriggerBase : EventTriggerBase where T : class diff --git a/Src/NoesisApp/Core/Src/Interactivity/GamepadTrigger.cs b/Src/NoesisApp/Core/Src/Interactivity/GamepadTrigger.cs index df2bc1b..8bb840f 100644 --- a/Src/NoesisApp/Core/Src/Interactivity/GamepadTrigger.cs +++ b/Src/NoesisApp/Core/Src/Interactivity/GamepadTrigger.cs @@ -134,6 +134,8 @@ private void RegisterSource() { source.KeyUp += OnButtonPress; } + + source.Destroyed += OnSourceDestroyed; } _source = GetPtr(source); @@ -144,6 +146,8 @@ private void UnregisterSource(GamepadTriggerFiredOn firedOn) UIElement source = (UIElement)GetProxy(_source); if (source != null) { + source.Destroyed -= OnSourceDestroyed; + if (firedOn == GamepadTriggerFiredOn.ButtonDown) { source.KeyDown -= OnButtonPress; @@ -157,6 +161,11 @@ private void UnregisterSource(GamepadTriggerFiredOn firedOn) _source = IntPtr.Zero; } + private void OnSourceDestroyed(IntPtr d) + { + _source = IntPtr.Zero; + } + private UIElement GetRoot(Visual current) { UIElement root = null; diff --git a/Src/NoesisApp/Core/Src/Interactivity/KeyTrigger.cs b/Src/NoesisApp/Core/Src/Interactivity/KeyTrigger.cs index bf10c94..71983a9 100644 --- a/Src/NoesisApp/Core/Src/Interactivity/KeyTrigger.cs +++ b/Src/NoesisApp/Core/Src/Interactivity/KeyTrigger.cs @@ -128,6 +128,8 @@ private void RegisterSource() { source.KeyUp += OnKeyPress; } + + source.Destroyed += OnSourceDestroyed; } _source = GetPtr(source); @@ -138,6 +140,8 @@ private void UnregisterSource(KeyTriggerFiredOn firedOn) UIElement source = (UIElement)GetProxy(_source); if (source != null) { + source.Destroyed -= OnSourceDestroyed; + if (firedOn == KeyTriggerFiredOn.KeyDown) { source.KeyDown -= OnKeyPress; @@ -151,6 +155,11 @@ private void UnregisterSource(KeyTriggerFiredOn firedOn) _source = IntPtr.Zero; } + private void OnSourceDestroyed(IntPtr d) + { + _source = IntPtr.Zero; + } + private UIElement GetRoot(Visual current) { UIElement root = null; diff --git a/Src/NoesisApp/Core/Src/Interactivity/StoryboardCompletedTrigger.cs b/Src/NoesisApp/Core/Src/Interactivity/StoryboardCompletedTrigger.cs index d857b3b..7791d5a 100644 --- a/Src/NoesisApp/Core/Src/Interactivity/StoryboardCompletedTrigger.cs +++ b/Src/NoesisApp/Core/Src/Interactivity/StoryboardCompletedTrigger.cs @@ -22,7 +22,7 @@ protected override void OnDetaching() Storyboard storyboard = Storyboard; if (storyboard != null) { - storyboard.Completed -= _wrapper.Completed; + storyboard.Completed -= OnStoryboardCompleted; } base.OnDetaching(); @@ -35,11 +35,11 @@ protected override void OnStoryboardChanged(DependencyPropertyChangedEventArgs e if (oldStoryboard != null) { - oldStoryboard.Completed -= _wrapper.Completed; + oldStoryboard.Completed -= OnStoryboardCompleted; } if (newStoryboard != null) { - newStoryboard.Completed += _wrapper.Completed; + newStoryboard.Completed += OnStoryboardCompleted; } } @@ -47,22 +47,5 @@ private void OnStoryboardCompleted(object sender, EventArgs e) { InvokeActions(e); } - - public StoryboardCompletedTrigger() - { - _wrapper = new EventWrapper { wr = new System.WeakReference(this) }; - } - - private struct EventWrapper - { - public System.WeakReference wr; - - public void Completed(object sender, EventArgs e) - { - ((StoryboardCompletedTrigger)wr.Target)?.OnStoryboardCompleted(sender, e); - } - } - - private EventWrapper _wrapper; } } diff --git a/Src/NoesisApp/Core/Src/Interactivity/TargetedTriggerAction.cs b/Src/NoesisApp/Core/Src/Interactivity/TargetedTriggerAction.cs index db0a122..2145a12 100644 --- a/Src/NoesisApp/Core/Src/Interactivity/TargetedTriggerAction.cs +++ b/Src/NoesisApp/Core/Src/Interactivity/TargetedTriggerAction.cs @@ -134,11 +134,11 @@ private void UpdateTarget(object associatedObject) newTarget.GetType(), GetType())); } - UnregisterTarget(oldTarget, _target); + UnregisterTarget(oldTarget); _target = GetPtr(newTarget); - RegisterTarget(newTarget, _target); + RegisterTarget(newTarget); if (AssociatedObject != null) { @@ -148,61 +148,25 @@ private void UpdateTarget(object associatedObject) } #region Target registration - private void RegisterTarget(object newTarget, IntPtr cPtr) + private void RegisterTarget(object target) { - if (newTarget is DependencyObject) + if (target is DependencyObject) { - DependencyObject dob = (DependencyObject)newTarget; - long ptr = cPtr.ToInt64(); - List actions; - if (!targets.TryGetValue(ptr, out actions)) - { - actions = new List(); - targets.Add(ptr, actions); - } - - actions.Add(this); - - if (BindingOperations.GetBinding(dob, TargetDestroyedProperty) == null) - { - BindingOperations.SetBinding(dob, TargetDestroyedProperty, new Binding("Visibility") - { - RelativeSource = new RelativeSource { AncestorType = typeof(UIElement) } - }); - } + DependencyObject dob = (DependencyObject)target; + dob.Destroyed += OnTargetDestroyed; } else { - _keepTarget = newTarget; + _keepTarget = target; } } - private void UnregisterTarget(object oldTarget, IntPtr cPtr) + private void UnregisterTarget(object target) { - if (oldTarget is DependencyObject) + if (target is DependencyObject) { - DependencyObject dob = (DependencyObject)oldTarget; - long ptr = cPtr.ToInt64(); - List actions; - if (targets.TryGetValue(ptr, out actions)) - { - int numActions = actions.Count; - for (int i = 0; i < numActions; ++i) - { - TargetedTriggerAction action = actions[i]; - if (action == this) - { - _target = IntPtr.Zero; - actions.RemoveAt(i); - break; - } - } - - if (actions.Count == 0) - { - targets.Remove(ptr); - } - } + DependencyObject dob = (DependencyObject)target; + dob.Destroyed -= OnTargetDestroyed; } else { @@ -210,31 +174,10 @@ private void UnregisterTarget(object oldTarget, IntPtr cPtr) } } - private static readonly DependencyProperty TargetDestroyedProperty = DependencyProperty.Register( - ".TargetDestroyed", typeof(Visibility), typeof(TargetedTriggerAction), - new PropertyMetadata(TargetDestroyed, OnTargetDestroyedChanged)); - - private static void OnTargetDestroyedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + private void OnTargetDestroyed(IntPtr d) { - if ((Visibility)e.NewValue == TargetDestroyed) - { - IntPtr cPtr = GetPtr(d); - long ptr = cPtr.ToInt64(); - List actions; - if (targets.TryGetValue(ptr, out actions)) - { - while (actions.Count > 0) - { - actions[0].UnregisterTarget(d, cPtr); - } - - targets.Remove(ptr); - } - } + _target = IntPtr.Zero; } - - private const Visibility TargetDestroyed = (Visibility)(-1); - private static Dictionary> targets = new Dictionary>(); #endregion #region TargetName resolver diff --git a/Src/NoesisApp/MediaPlayers/GE/Native/build_arm.sh b/Src/NoesisApp/MediaPlayers/GE/Native/build_arm.sh index d5632ae..f9ee76d 100644 --- a/Src/NoesisApp/MediaPlayers/GE/Native/build_arm.sh +++ b/Src/NoesisApp/MediaPlayers/GE/Native/build_arm.sh @@ -1,2 +1,2 @@ -arm-linux-gnueabihf-gcc mp.cpp -o ../runtimes/linux-arm/native/mp -g -std=c++11 -fPIC -I. -I/usr/include `pkg-config --cflags --libs gstreamer-1.0 gstreamer-plugins-base-1.0 gstreamer-allocators-1.0 gstreamer-video-1.0 gstreamer-app-1.0` -arm-linux-gnueabihf-gcc libGEMediaPlayer.cpp -o ../runtimes/linux-arm/native/libMediaPlayer.so -g -std=c++11 -fPIC -I. -I/usr/include -lEGL -lGLESv2 -shared -pthread +arm-linux-gnueabihf-gcc mp.cpp -o ../runtimes/linux-arm/native/mp -g -std=c++11 -fPIC -I. -I/usr/include `pkg-config --cflags --libs gstreamer-1.0 gstreamer-plugins-base-1.0 gstreamer-allocators-1.0 gstreamer-video-1.0 gstreamer-app-1.0` --sysroot /home/pizzi/Noesis/GE/Max10Updater/rootfs +arm-linux-gnueabihf-gcc libGEMediaPlayer.cpp -o ../runtimes/linux-arm/native/libMediaPlayer.so -g -std=c++11 -fPIC -I. -I/usr/include -lEGL -lGLESv2 -shared -pthread --sysroot /home/pizzi/Noesis/GE/Max10Updater/rootfs diff --git a/Src/NoesisApp/MediaPlayers/GE/Native/libGEMediaPlayer.cpp b/Src/NoesisApp/MediaPlayers/GE/Native/libGEMediaPlayer.cpp index d26f654..d612283 100644 --- a/Src/NoesisApp/MediaPlayers/GE/Native/libGEMediaPlayer.cpp +++ b/Src/NoesisApp/MediaPlayers/GE/Native/libGEMediaPlayer.cpp @@ -228,7 +228,8 @@ extern "C" void* CreateState() extern "C" void DestroyState(void* state) { GstMediaPlayerState* st = (GstMediaPlayerState*)state; - kill(st->child, SIGTERM); + kill(st->child, SIGKILL); + waitpid(st->child, NULL, 0); char tmpVideoPath[256]; strcpy(tmpVideoPath, st->tmpDir); @@ -305,8 +306,6 @@ extern "C" bool OpenMedia(void* state, const void* streamPtr, const char* stream execlp("./mp", "mp", st->tmpDir, streamSizeStr, (char*)NULL); } - signal(SIGCHLD, SIG_IGN); - MediaPlayerCommand command; socklen_t socklen = sizeof(sockaddr_un); recvfrom(st->serverSocket, &command, sizeof(MediaPlayerCommand), 0, (sockaddr*)&st->clientSockaddr, &socklen); @@ -577,7 +576,7 @@ extern "C" void RenderFrame(void* state) glEGLImageTargetTexture2DOES(GL_TEXTURE_EXTERNAL_OES, EGL_NO_IMAGE_KHR); eglDestroyImageKHR(display, image); close(st->fd); - st->fd = -1; + // st->fd = -1; // st->fd = 0; st->lastRenderTime = st->time; diff --git a/Src/NoesisApp/MediaPlayers/GE/Native/mp b/Src/NoesisApp/MediaPlayers/GE/Native/mp new file mode 100644 index 0000000000000000000000000000000000000000..6d774bda82a2306fb0ec560d0544deb1819de899 GIT binary patch literal 25632 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 O>Vus4s|h0SEdSq_lKJ8Q literal 0 HcmV?d00001 diff --git a/Src/NoesisApp/MediaPlayers/GE/Native/mp.cpp b/Src/NoesisApp/MediaPlayers/GE/Native/mp.cpp index 2392062..1260242 100644 --- a/Src/NoesisApp/MediaPlayers/GE/Native/mp.cpp +++ b/Src/NoesisApp/MediaPlayers/GE/Native/mp.cpp @@ -89,6 +89,67 @@ static GstFlowReturn NewSample(GstElement* sink, void* data) return GST_FLOW_ERROR; } +static GstFlowReturn NewPreroll(GstElement* sink, void* data) +{ + GstSample *sample; + + g_signal_emit_by_name (sink, "pull-preroll", &sample); + if (sample) + { + gint64 time; + gst_element_query_position(sink, GST_FORMAT_TIME, &time); + + GstCaps* caps = gst_sample_get_caps (sample); + GstStructure* s = gst_caps_get_structure (caps, 0); + gint width; + gint height; + gst_structure_get_int (s, "width", &width); + gst_structure_get_int (s, "height", &height); + + GstBuffer* buffer = gst_sample_get_buffer(sample); + GstMapInfo map; + if (gst_buffer_map(buffer, &map, GST_MAP_READ)) + { + GstMemory* mem = gst_buffer_peek_memory(buffer, 0); + + int gst_fd = gst_dmabuf_memory_get_fd(mem); + int fd = dup(gst_fd); + gst_buffer_unmap (buffer, &map); + msghdr msg; + iovec iov; + cmsghdr *cmsg; + char cmsg_buffer[sizeof(cmsghdr) + sizeof(int)]; + MediaPlayerCommand command; + command.cmd = MPC_NewFrame; + command.arg[0] = time; + command.arg[1] = (((uint64_t)width) << 32) | height; + memset(&msg, 0, sizeof(msghdr)); + memset(&iov, 0, sizeof(iovec)); + iov.iov_base = &command; + iov.iov_len = sizeof(MediaPlayerCommand); + msg.msg_name = &serverSockaddr; + msg.msg_namelen = sizeof(sockaddr_un); + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + msg.msg_control = cmsg_buffer; + msg.msg_controllen = sizeof(cmsg_buffer); + cmsg = CMSG_FIRSTHDR(&msg); + cmsg->cmsg_len = sizeof(cmsg_buffer); + cmsg->cmsg_level = SOL_SOCKET; + cmsg->cmsg_type = SCM_RIGHTS; + *((int *)CMSG_DATA(cmsg)) = fd; + int clientSocket = *(int*)data; + sendmsg(clientSocket, &msg, 0); + close(fd); + } + + gst_sample_unref (sample); + return GST_FLOW_OK; + } + + return GST_FLOW_ERROR; +} + static const gint64 Status_EOS = 1; static const gint64 Status_ERROR = 2; static const gint64 Status_READY = 3; @@ -306,6 +367,7 @@ int main(int argc, char** argv) GstElement* sink = gst_bin_get_by_name (GST_BIN (pipeline), "sink"); g_object_set (sink, "emit-signals", TRUE, NULL); g_signal_connect (sink, "new-sample", G_CALLBACK (NewSample), &clientSocket); + g_signal_connect (sink, "new-preroll", G_CALLBACK (NewPreroll), &clientSocket); gst_object_unref(sink); gint64 dimensions = 0; @@ -410,7 +472,15 @@ int main(int argc, char** argv) fcntl(clientSocket, F_SETFL, flags); gst_element_set_state (pipeline, GST_STATE_PAUSED); + // Wait for the pipeline to preroll + gst_element_get_state (pipeline, NULL, NULL, GST_CLOCK_TIME_NONE); + gst_element_seek_simple (pipeline, GST_FORMAT_TIME, (GstSeekFlags)(GST_SEEK_FLAG_ACCURATE | GST_SEEK_FLAG_FLUSH), 0); + + gst_element_set_state (pipeline, GST_STATE_PAUSED); + + // Wait for the pipeline to preroll + gst_element_get_state (pipeline, NULL, NULL, GST_CLOCK_TIME_NONE); } else if (command.cmd == MPC_Seek) { diff --git a/Src/NoesisApp/MediaPlayers/GE/Src/GEMediaPlayer.cs b/Src/NoesisApp/MediaPlayers/GE/Src/GEMediaPlayer.cs index 9920ad4..5fee4b4 100644 --- a/Src/NoesisApp/MediaPlayers/GE/Src/GEMediaPlayer.cs +++ b/Src/NoesisApp/MediaPlayers/GE/Src/GEMediaPlayer.cs @@ -13,9 +13,10 @@ static GEMediaPlayer() InitMediaPlayer(); } - GEMediaPlayer(MediaElement owner, string uri) + GEMediaPlayer(MediaElement owner, Uri uri) { - _stream = Noesis.GUI.LoadXamlResource(uri); + string path = uri.GetPath(); + _stream = Noesis.GUI.LoadXamlResource(path); if (_stream != null) { _state = CreateState(); @@ -34,7 +35,7 @@ static GEMediaPlayer() _mediaFailedFnHandle = GCHandle.Alloc(mediaFailedFn); long streamSize = _stream.Length; - OpenMedia(_state, GCHandle.ToIntPtr(_streamHandle), uri, streamSize, readFn, seekFn, mediaOpenedFn, mediaEndedFn, mediaFailedFn); + OpenMedia(_state, GCHandle.ToIntPtr(_streamHandle), path, streamSize, readFn, seekFn, mediaOpenedFn, mediaEndedFn, mediaFailedFn); } owner.View.Rendering += OnRendering; } @@ -159,7 +160,7 @@ public override ImageSource TextureSource get { return _textureSource; } } - public static MediaPlayer Create(MediaElement owner, string uri, object user) + public static MediaPlayer Create(MediaElement owner, Uri uri, object user) { return new GEMediaPlayer(owner, uri); } diff --git a/Src/NoesisApp/MediaPlayers/GE/runtimes/linux-arm64/native/mp b/Src/NoesisApp/MediaPlayers/GE/runtimes/linux-arm64/native/mp new file mode 100644 index 0000000000000000000000000000000000000000..6d774bda82a2306fb0ec560d0544deb1819de899 GIT binary patch literal 25632 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 O>Vus4s|h0SEdSq_lKJ8Q literal 0 HcmV?d00001