2 * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
18 using System.Collections.Generic;
19 using System.ComponentModel;
20 using System.Runtime.InteropServices;
22 namespace Tizen.Applications.ThemeManager
27 /// <since_tizen> 8 </since_tizen>
28 [EditorBrowsable(EditorBrowsableState.Never)]
29 public class ThemeLoader : IDisposable
31 private const string LogTag = "Tizen.Applications.ThemeManager";
32 private bool _disposed = false;
33 private event EventHandler<ThemeEventArgs> _changedEventHandler;
34 private Interop.ThemeManager.ThemeLoaderChangedCallback _callback;
35 private string _eventId;
36 private Theme _currentTheme = null;
37 internal IntPtr _loaderHandle = IntPtr.Zero;
40 /// Creates ThemeLoader.
42 /// <since_tizen> 8 </since_tizen>
43 /// <exception cref="OutOfMemoryException">Failed to create handle.</exception>
44 [EditorBrowsable(EditorBrowsableState.Never)]
47 Interop.ThemeManager.ErrorCode err = Interop.ThemeManager.LoaderCreate(out _loaderHandle);
48 if (err != Interop.ThemeManager.ErrorCode.None)
50 throw Interop.ThemeManager.ThemeManagerErrorFactory.GetException(err, "Failed to create themeloader");
53 _callback = new Interop.ThemeManager.ThemeLoaderChangedCallback(OnThemeChanged);
54 err = Interop.ThemeManager.LoaderAddEvent(_loaderHandle, _callback, IntPtr.Zero, out _eventId);
55 if (err != Interop.ThemeManager.ErrorCode.None)
57 throw Interop.ThemeManager.ThemeManagerErrorFactory.GetException(err, "Failed to add event");
61 private int OnThemeChanged(IntPtr handle, IntPtr userData)
65 Interop.ThemeManager.ErrorCode err = Interop.ThemeManager.ThemeClone(handle, out IntPtr cloned);
66 if (err != Interop.ThemeManager.ErrorCode.None)
69 _changedEventHandler?.Invoke(this, new ThemeEventArgs(new Theme(cloned)));
74 /// Adds or removes events for theme changed.
76 /// <since_tizen> 8 </since_tizen>
77 /// <exception cref="ArgumentException">Thrown when failed because of an invalid argument.</exception>
78 /// <exception cref="OutOfMemoryException">Thrown when failed because of out of memory.</exception>
79 [EditorBrowsable(EditorBrowsableState.Never)]
80 public event EventHandler<ThemeEventArgs> ThemeChanged
84 _changedEventHandler += value;
89 _changedEventHandler -= value;
94 /// Sets current theme.
96 /// <since_tizen> 8 </since_tizen>
97 /// <exception cref="ArgumentException">Thrown when failed because of an invalid argument.</exception>
98 [EditorBrowsable(EditorBrowsableState.Never)]
99 public Theme CurrentTheme
103 if (_currentTheme != null && _currentTheme.Id.Length > 0)
104 return _currentTheme;
106 Interop.ThemeManager.ErrorCode err = Interop.ThemeManager.LoaderLoadCurrentTheme(_loaderHandle, out IntPtr _themeHandle);
107 if (err != Interop.ThemeManager.ErrorCode.None)
109 throw Interop.ThemeManager.ThemeManagerErrorFactory.GetException(err, "Failed to load current theme");
112 _currentTheme = new Theme(_themeHandle);
113 return _currentTheme;
118 throw new ArgumentException("value is null");
120 Interop.ThemeManager.ErrorCode err = Interop.ThemeManager.LoaderSetCurrentTheme(_loaderHandle, value.Id);
121 if (err != Interop.ThemeManager.ErrorCode.None)
123 Log.Warn(LogTag, "Failed to set current. Err = " + err);
124 throw Interop.ThemeManager.ThemeManagerErrorFactory.GetException(err, "Failed to set current theme");
127 if(_currentTheme != value)
128 _currentTheme = value;
135 /// <since_tizen> 8 </since_tizen>
136 /// <exception cref="ArgumentException">Thrown when failed because of an invalid argument.</exception>
137 [EditorBrowsable(EditorBrowsableState.Never)]
138 public Theme LoadTheme(string id)
142 Interop.ThemeManager.ErrorCode err = Interop.ThemeManager.LoaderLoadTheme(_loaderHandle, id, out _themeHandle);
143 if (err != Interop.ThemeManager.ErrorCode.None)
145 throw Interop.ThemeManager.ThemeManagerErrorFactory.GetException(err, "Failed to load theme");
148 return new Theme(_themeHandle);
152 /// Gets bundle of theme IDs.
154 /// <since_tizen> 8 </since_tizen>
155 /// <exception cref="ArgumentException">Thrown when failed because of an invalid argument.</exception>
156 /// <exception cref="OutOfMemoryException">Thrown when failed because of out of memory.</exception>
157 [EditorBrowsable(EditorBrowsableState.Never)]
158 public IEnumerable<string> QueryIds()
161 string[] stringArray;
164 Interop.ThemeManager.ErrorCode err = Interop.ThemeManager.LoaderQueryId(_loaderHandle, out ids, out count);
165 if (err != Interop.ThemeManager.ErrorCode.None)
167 throw Interop.ThemeManager.ThemeManagerErrorFactory.GetException(err, "Failed to query ids");
170 IntPtrToStringArray(ids, count, out stringArray);
174 static void IntPtrToStringArray(IntPtr unmanagedArray, int size, out string[] managedArray)
176 managedArray = new string[size];
177 IntPtr[] IntPtrArray = new IntPtr[size];
178 Marshal.Copy(unmanagedArray, IntPtrArray, 0, size);
179 for (int iterator = 0; iterator < size; iterator++)
181 managedArray[iterator] = Marshal.PtrToStringAnsi(IntPtrArray[iterator]);
186 /// Releases all resources used by the ThemeLoader class.
188 /// <since_tizen> 8 </since_tizen>
189 [EditorBrowsable(EditorBrowsableState.Never)]
190 public void Dispose()
193 GC.SuppressFinalize(this);
197 /// Releases the unmanaged resources used by the ThemeLoader class specifying whether to perform a normal dispose operation.
199 /// <param name="disposing">true for a normal dispose operation; false to finalize the handle.</param>
200 protected virtual void Dispose(bool disposing)
205 if (_loaderHandle != IntPtr.Zero)
207 Interop.ThemeManager.ErrorCode err = Interop.ThemeManager.LoaderRemoveEvent(_loaderHandle, _eventId);
208 if (err != Interop.ThemeManager.ErrorCode.None)
210 Log.Error(LogTag, "Failed to remove event");
213 Interop.ThemeManager.LoaderDestroy(_loaderHandle);
214 _loaderHandle = IntPtr.Zero;
217 if (disposing && _currentTheme != null)
218 _currentTheme.Dispose();