using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
+using System.Reflection;
using System.Xml;
using Tizen.NUI.BaseComponents;
using Tizen.NUI.Binding;
{
/// <summary></summary>
[EditorBrowsable(EditorBrowsableState.Never)]
- public class Theme : BindableObject
+ public class Theme : BindableObject, IResourcesProvider
{
private readonly Dictionary<string, ViewStyle> map;
private string baseTheme;
+ private string resource;
+ private string xamlFile;
+
+ /// <summary>
+ /// The resource file path that is used in the theme.
+ /// </summary>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public string Resource
+ {
+ get => resource;
+ set
+ {
+ if (resource == value) return;
+ resource = value;
+
+ Reload();
+ }
+ }
/// <summary>Create an empty theme.</summary>
[EditorBrowsable(EditorBrowsableState.Never)]
throw new ArgumentNullException("The xaml file path cannot be null or empty string", nameof(xamlFile));
}
- try
- {
- using(var reader = XmlReader.Create(xamlFile))
- {
- XamlLoader.Load(this, reader);
- }
- }
- catch (global::System.IO.IOException e)
- {
- Tizen.Log.Info("NUI", $"Could not load \"{xamlFile}\".\n");
- throw e;
- }
- catch (Exception e)
- {
- Tizen.Log.Info("NUI", $"Could not parse \"{xamlFile}\".\n");
- Tizen.Log.Info("NUI", "Make sure the all used assemblies (e.g. Tizen.NUI.Components) are included in the application project.\n");
- Tizen.Log.Info("NUI", "Make sure the type and namespace are correct.\n");
- throw e;
- }
+ LoadFromXaml(xamlFile);
+ this.xamlFile = xamlFile;
+ }
+
+ /// <summary>
+ /// Create a new theme from the xaml file with theme resource.
+ /// </summary>
+ /// <param name="xamlFile">An absolute path to the xaml file.</param>
+ /// <param name="themeResource">An absolute path to the theme resource file.</param>
+ /// <exception cref="ArgumentNullException">Thrown when the given xamlFile is null or empty string.</exception>
+ /// <exception cref="System.IO.IOException">Thrown when there are file IO problems.</exception>
+ /// <exception cref="Exception">Thrown when the content of the xaml file is not valid xaml form.</exception>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public Theme(string xamlFile, string themeResource) : this()
+ {
+ if (string.IsNullOrEmpty(xamlFile))
+ throw new ArgumentNullException(nameof(xamlFile), "The xaml file path cannot be null or empty string");
+ if (string.IsNullOrEmpty(themeResource))
+ throw new ArgumentNullException(nameof(themeResource), "The theme resource file path cannot be null or empty string");
+
+ resource = themeResource;
+ XamlResources.SetAndLoadSource(new Uri(themeResource), themeResource, Assembly.GetAssembly(GetType()), null);
+
+ LoadFromXaml(xamlFile);
+ this.xamlFile = xamlFile;
}
/// <summary></summary>
}
}
+ /// <inheritdoc/>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public bool IsResourcesCreated { get; } = true;
+
+ /// <inheritdoc/>
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public ResourceDictionary XamlResources { get; set; } = new ResourceDictionary();
+
/// <summary>
/// For Xaml use only.
/// Note that it is not a normal indexer.
{
if (theme == null)
throw new ArgumentNullException(nameof(theme));
-
+
+ this.xamlFile = theme.xamlFile;
+
foreach (var item in theme)
{
if (item.Value == null)
/// Internal use only.
/// </summary>
internal void AddStyleWithoutClone(string styleName, ViewStyle value) => map[styleName] = value;
+
+ internal void Reload()
+ {
+ if (xamlFile == null)
+ throw new InvalidOperationException("Cannot reload without xaml file.");
+
+ map.Clear();
+ if (Resource != null)
+ {
+ XamlResources.Clear();
+ XamlResources.SetAndLoadSource(new Uri(Resource), Resource, Assembly.GetAssembly(GetType()), null);
+ }
+
+ LoadFromXaml(xamlFile);
+ }
+
+ private void LoadFromXaml(string xamlFile)
+ {
+ try
+ {
+ using (var reader = XmlReader.Create(xamlFile))
+ {
+ XamlLoader.Load(this, reader);
+ }
+ }
+ catch (System.IO.IOException)
+ {
+ Tizen.Log.Error("NUI", $"Could not load \"{xamlFile}\".\n");
+ throw;
+ }
+ catch (Exception)
+ {
+ Tizen.Log.Error("NUI", $"Could not parse \"{xamlFile}\".\n");
+ Tizen.Log.Error("NUI", "Make sure the all used assemblies (e.g. Tizen.NUI.Components) are included in the application project.\n");
+ Tizen.Log.Error("NUI", "Make sure the type and namespace are correct.\n");
+ throw;
+ }
+ }
}
}
--- /dev/null
+using Tizen.NUI;
+using Tizen.NUI.BaseComponents;
+using Tizen.NUI.Components;
+
+namespace Tizen.NUI.Samples
+{
+ public class ThemeResourceSample : IExample
+ {
+ public void Activate()
+ {
+ string resourceDefault = System.IO.Path.Combine("res", "resSampleThemeResourceDefault.xaml");
+ string resourceDark = System.IO.Path.Combine("res", "SampleThemeResourceDark.xaml");
+ Theme sampleTheme = new Theme(System.IO.Path.Combine("res", "SampleTheme.xaml"), resourceDefault);
+ ThemeManager.ApplyTheme(sampleTheme);
+
+ View root = new View();
+ root.WidthSpecification = LayoutParamPolicies.MatchParent;
+ root.HeightSpecification = LayoutParamPolicies.MatchParent;
+ Window.Instance.GetDefaultLayer().Add(root);
+
+ Button button = new Button();
+ button.ThemeChangeSensitive = true;
+ button.Size = new Size2D(200, 200);
+ button.Clicked += (object sender, ClickedEventArgs e) =>
+ {
+ if (sampleTheme.Resource == resourceDefault)
+ {
+ sampleTheme.Resource = resourceDark;
+ ThemeManager.ApplyTheme(sampleTheme);
+
+ }
+ else
+ {
+ sampleTheme.Resource = resourceDefault;
+ ThemeManager.ApplyTheme(sampleTheme);
+ }
+ };
+ root.Add(button);
+ }
+
+ public void Deactivate() {}
+ }
+}