[NUI] Add LoadFromXamlFile() (#892)
authordongsug-song <35130733+dongsug-song@users.noreply.github.com>
Wed, 19 Jun 2019 07:45:38 +0000 (16:45 +0900)
committerGitHub <noreply@github.com>
Wed, 19 Jun 2019 07:45:38 +0000 (16:45 +0900)
src/Tizen.NUI/src/internal/Xaml/XamlLoader.cs
src/Tizen.NUI/src/public/Xaml/ViewExtensions.cs
src/Tizen.NUI/src/public/XamlBinding/NameScopeExtensions.cs

index e486e97..601ef7d 100755 (executable)
@@ -39,17 +39,19 @@ using Tizen.NUI.Binding.Internals;
 
 namespace Tizen.NUI.Xaml.Internals
 {
-    [Obsolete ("Replaced by ResourceLoader")]
+    [Obsolete("Replaced by ResourceLoader")]
     internal static class XamlLoader
     {
         static Func<Type, string> xamlFileProvider;
 
-        public static Func<Type, string> XamlFileProvider {
+        public static Func<Type, string> XamlFileProvider
+        {
             get { return xamlFileProvider; }
-            internal set {
+            internal set
+            {
                 xamlFileProvider = value;
                 Tizen.NUI.Xaml.DesignMode.IsDesignModeEnabled = true;
-                //¯\_(ツ)_/¯ the previewer forgot to set that bool
+                //¯\_(??_/¯ the previewer forgot to set that bool
                 DoNotThrowOnExceptions = value != null;
             }
         }
@@ -133,7 +135,8 @@ namespace Tizen.NUI.Xaml
                         continue;
                     if (reader.NodeType == XmlNodeType.XmlDeclaration)
                         continue;
-                    if (reader.NodeType != XmlNodeType.Element) {
+                    if (reader.NodeType != XmlNodeType.Element)
+                    {
                         Debug.WriteLine("Unhandled node {0} {1} {2}", reader.NodeType, reader.Name, reader.Value);
                         continue;
                     }
@@ -143,12 +146,13 @@ namespace Tizen.NUI.Xaml
                         (view as Element).IsCreateByXaml = true;
                     }
 
-                    var rootnode = new RuntimeRootNode (new XmlType (reader.NamespaceURI, reader.Name, null), view, (IXmlNamespaceResolver)reader);
-                    XamlParser.ParseXaml (rootnode, reader);
-                    Visit (rootnode, new HydrationContext {
+                    var rootnode = new RuntimeRootNode(new XmlType(reader.NamespaceURI, reader.Name, null), view, (IXmlNamespaceResolver)reader);
+                    XamlParser.ParseXaml(rootnode, reader);
+                    Visit(rootnode, new HydrationContext
+                    {
                         RootElement = view,
 #pragma warning disable 0618
-                        ExceptionHandler = ResourceLoader.ExceptionHandler ?? (Internals.XamlLoader.DoNotThrowOnExceptions ? e => { }: (Action<Exception>)null)
+                        ExceptionHandler = ResourceLoader.ExceptionHandler ?? (Internals.XamlLoader.DoNotThrowOnExceptions ? e => { } : (Action<Exception>)null)
 #pragma warning restore 0618
                     });
                     break;
@@ -156,50 +160,54 @@ namespace Tizen.NUI.Xaml
             }
         }
 
-        [Obsolete ("Use the XamlFileProvider to provide xaml files. We will remove this when Cycle 8 hits Stable.")]
-        public static object Create (string xaml, bool doNotThrow = false)
+        [Obsolete("Use the XamlFileProvider to provide xaml files. We will remove this when Cycle 8 hits Stable.")]
+        public static object Create(string xaml, bool doNotThrow = false)
         {
             object inflatedView = null;
             using (var textreader = new StringReader(xaml))
-            using (var reader = XmlReader.Create (textreader)) {
-                while (reader.Read ()) {
+            using (var reader = XmlReader.Create(textreader))
+            {
+                while (reader.Read())
+                {
                     //Skip until element
                     if (reader.NodeType == XmlNodeType.Whitespace)
                         continue;
                     if (reader.NodeType == XmlNodeType.XmlDeclaration)
                         continue;
-                    if (reader.NodeType != XmlNodeType.Element) {
+                    if (reader.NodeType != XmlNodeType.Element)
+                    {
                         Debug.WriteLine("Unhandled node {0} {1} {2}", reader.NodeType, reader.Name, reader.Value);
                         continue;
                     }
 
-                    var rootnode = new RuntimeRootNode (new XmlType (reader.NamespaceURI, reader.Name, null), null, (IXmlNamespaceResolver)reader);
-                    XamlParser.ParseXaml (rootnode, reader);
-                    var visitorContext = new HydrationContext {
+                    var rootnode = new RuntimeRootNode(new XmlType(reader.NamespaceURI, reader.Name, null), null, (IXmlNamespaceResolver)reader);
+                    XamlParser.ParseXaml(rootnode, reader);
+                    var visitorContext = new HydrationContext
+                    {
                         ExceptionHandler = doNotThrow ? e => { } : (Action<Exception>)null,
                     };
-                    var cvv = new CreateValuesVisitor (visitorContext);
-                    cvv.Visit ((ElementNode)rootnode, null);
-                    inflatedView = rootnode.Root = visitorContext.Values [rootnode];
+                    var cvv = new CreateValuesVisitor(visitorContext);
+                    cvv.Visit((ElementNode)rootnode, null);
+                    inflatedView = rootnode.Root = visitorContext.Values[rootnode];
                     visitorContext.RootElement = inflatedView as BindableObject;
 
-                    Visit (rootnode, visitorContext);
+                    Visit(rootnode, visitorContext);
                     break;
                 }
             }
             return inflatedView;
         }
 
-        static void Visit (RootNode rootnode, HydrationContext visitorContext)
+        static void Visit(RootNode rootnode, HydrationContext visitorContext)
         {
-            rootnode.Accept (new XamlNodeVisitor ((node, parent) => node.Parent = parent), null); //set parents for {StaticResource}
-            rootnode.Accept (new ExpandMarkupsVisitor (visitorContext), null);
-            rootnode.Accept (new PruneIgnoredNodesVisitor(), null);
-            rootnode.Accept (new NamescopingVisitor (visitorContext), null); //set namescopes for {x:Reference}
-            rootnode.Accept (new CreateValuesVisitor (visitorContext), null);
-            rootnode.Accept (new RegisterXNamesVisitor (visitorContext), null);
-            rootnode.Accept (new FillResourceDictionariesVisitor (visitorContext), null);
-            rootnode.Accept (new ApplyPropertiesVisitor (visitorContext, true), null);
+            rootnode.Accept(new XamlNodeVisitor((node, parent) => node.Parent = parent), null); //set parents for {StaticResource}
+            rootnode.Accept(new ExpandMarkupsVisitor(visitorContext), null);
+            rootnode.Accept(new PruneIgnoredNodesVisitor(), null);
+            rootnode.Accept(new NamescopingVisitor(visitorContext), null); //set namescopes for {x:Reference}
+            rootnode.Accept(new CreateValuesVisitor(visitorContext), null);
+            rootnode.Accept(new RegisterXNamesVisitor(visitorContext), null);
+            rootnode.Accept(new FillResourceDictionariesVisitor(visitorContext), null);
+            rootnode.Accept(new ApplyPropertiesVisitor(visitorContext, true), null);
         }
 
         static string GetAnimationXaml(string animationXamlPath)
@@ -268,7 +276,8 @@ namespace Tizen.NUI.Xaml
             var assembly = type.GetTypeInfo().Assembly;
 
             string resourceId;
-            if (XamlResources.TryGetValue(type, out resourceId)) {
+            if (XamlResources.TryGetValue(type, out resourceId))
+            {
                 var result = ReadResourceAsXaml(type, assembly, resourceId);
                 if (result != null)
                     return result;
@@ -280,8 +289,10 @@ namespace Tizen.NUI.Xaml
 
             // first pass, pray to find it because the user named it correctly
 
-            foreach (var resource in resourceNames) {
-                if (ResourceMatchesFilename(assembly, resource, likelyResourceName)) {
+            foreach (var resource in resourceNames)
+            {
+                if (ResourceMatchesFilename(assembly, resource, likelyResourceName))
+                {
                     resourceName = resource;
                     var xaml = ReadResourceAsXaml(type, assembly, resource);
                     if (xaml != null)
@@ -291,7 +302,8 @@ namespace Tizen.NUI.Xaml
 
             // okay maybe they at least named it .xaml
 
-            foreach (var resource in resourceNames) {
+            foreach (var resource in resourceNames)
+            {
                 if (!resource.EndsWith(".xaml", StringComparison.OrdinalIgnoreCase))
                     continue;
 
@@ -301,7 +313,8 @@ namespace Tizen.NUI.Xaml
                     return xaml;
             }
 
-            foreach (var resource in resourceNames) {
+            foreach (var resource in resourceNames)
+            {
                 if (resource.EndsWith(".xaml", StringComparison.OrdinalIgnoreCase))
                     continue;
 
@@ -317,14 +330,16 @@ namespace Tizen.NUI.Xaml
         //legacy...
         static bool ResourceMatchesFilename(Assembly assembly, string resource, string filename)
         {
-            try {
+            try
+            {
                 var info = assembly.GetManifestResourceInfo(resource);
 
                 if (!string.IsNullOrEmpty(info.FileName) &&
                     string.Compare(info.FileName, filename, StringComparison.OrdinalIgnoreCase) == 0)
                     return true;
             }
-            catch (PlatformNotSupportedException) {
+            catch (PlatformNotSupportedException)
+            {
                 // Because Win10 + .NET Native
             }
 
@@ -339,8 +354,10 @@ namespace Tizen.NUI.Xaml
         static string ReadResourceAsXaml(Type type, Assembly assembly, string likelyTargetName, bool validate = false)
         {
             using (var stream = assembly.GetManifestResourceStream(likelyTargetName))
-            using (var reader = new StreamReader(stream)) {
-                if (validate) {
+            using (var reader = new StreamReader(stream))
+            {
+                if (validate)
+                {
                     // terrible validation of XML. Unfortunately it will probably work most of the time since comments
                     // also start with a <. We can't bring in any real deps.
 
@@ -366,12 +383,62 @@ namespace Tizen.NUI.Xaml
 
         public class RuntimeRootNode : RootNode
         {
-            public RuntimeRootNode(XmlType xmlType, object root, IXmlNamespaceResolver resolver) : base (xmlType, resolver)
+            public RuntimeRootNode(XmlType xmlType, object root, IXmlNamespaceResolver resolver) : base(xmlType, resolver)
             {
                 Root = root;
             }
 
             public object Root { get; internal set; }
         }
+
+        internal static string GetXamlForName(string nameOfXamlFile)
+        {
+            string xaml;
+            string resourceName = nameOfXamlFile + ".xaml";
+            string resource = Tizen.Applications.Application.Current.DirectoryInfo.Resource;
+
+            NUILog.Debug($"resource=({resource})");
+
+            int windowWidth = Window.Instance.Size.Width;
+            int windowHeight = Window.Instance.Size.Height;
+
+            string likelyResourcePath = resource + "layout/" + windowWidth.ToString() + "x" + windowHeight.ToString() + "/" + resourceName;
+
+            NUILog.Debug($"likelyResourcePath=({likelyResourcePath})");
+
+
+            if (!File.Exists(likelyResourcePath))
+            {
+                likelyResourcePath = resource + "layout/" + resourceName;
+            }
+
+            //Find the xaml file in the layout folder
+            if (File.Exists(likelyResourcePath))
+            {
+                StreamReader reader = new StreamReader(likelyResourcePath);
+                xaml = reader.ReadToEnd();
+
+                NUILog.Debug($"File is exist!, try with xaml: {xaml}");
+
+                // Layer
+                var pattern = String.Format("x:Class *= *\"{0}\"", "Tizen.NUI.Layer");
+                var regex = new Regex(pattern, RegexOptions.ECMAScript);
+                if (regex.IsMatch(xaml) || xaml.Contains(String.Format("x:Class=\"{0}\"", "Tizen.NUI.Layer")))
+                {
+                    return xaml;
+                }
+                // View
+                pattern = String.Format("x:Class *= *\"{0}\"", "Tizen.NUI.BaseComponents.View");
+                regex = new Regex(pattern, RegexOptions.ECMAScript);
+                if (regex.IsMatch(xaml) || xaml.Contains(String.Format("x:Class=\"{0}\"", "Tizen.NUI.BaseComponents.View")))
+                {
+                    return xaml;
+                }
+
+                throw new XamlParseException(string.Format("Can't find type {0}", "Tizen.NUI.XamlMainPage nor View nor Layer"), new XmlLineInfo());
+            }
+            return null;
+        }
+
     }
 }
index 2197921..4749b65 100755 (executable)
@@ -74,5 +74,16 @@ namespace Tizen.NUI.Xaml
         {
             return XamlLoader.LoadObject<T>(path);
         }
+
+        [EditorBrowsable(EditorBrowsableState.Never)]
+        public static TXaml LoadFromXamlFile<TXaml>(this TXaml view, string nameOfXamlFile)
+        {
+            NUILog.Debug($"LoadFromXamlFile(nameOfXamlFile={nameOfXamlFile})");
+
+            string xamlScript = XamlLoader.GetXamlForName(nameOfXamlFile);
+            XamlLoader.Load(view, xamlScript);
+            return view;
+        }
+
     }
 }
\ No newline at end of file
index b1c047f..fd9eb90 100755 (executable)
@@ -17,7 +17,7 @@ namespace Tizen.NUI.Binding
 
         internal static T FindByName<T>(this INameScope namescope, string name)
         {
-            return (T)namescope.FindByName(name);
+            return (T)namescope?.FindByName(name);
         }
 
         private static Stack<Element> elementStack = new Stack<Element>();