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");
54 private void OnThemeChanged(IntPtr handle, IntPtr userData)
56 Interop.ThemeManager.ThemeClone(handle, out IntPtr cloned);
57 _changedEventHandler?.Invoke(this, new ThemeEventArgs(new Theme(cloned)));
61 /// Adds or removes events for theme changed.
63 /// <since_tizen> 8 </since_tizen>
64 /// <exception cref="ArgumentException">Thrown when failed because of an invalid argument.</exception>
65 /// <exception cref="OutOfMemoryException">Thrown when failed because of out of memory.</exception>
66 [EditorBrowsable(EditorBrowsableState.Never)]
67 public event EventHandler<ThemeEventArgs> ThemeChanged
71 if (_changedEventHandler == null)
73 if (_callback == null)
74 _callback = new Interop.ThemeManager.ThemeLoaderChangedCallback(OnThemeChanged);
75 Interop.ThemeManager.ErrorCode err = Interop.ThemeManager.LoaderAddEvent(_loaderHandle, _callback, IntPtr.Zero, out _eventId);
77 if (err != Interop.ThemeManager.ErrorCode.None)
79 throw Interop.ThemeManager.ThemeManagerErrorFactory.GetException(err, "Failed to add event");
83 _changedEventHandler += value;
88 _changedEventHandler -= value;
89 if (_changedEventHandler == null)
91 Interop.ThemeManager.ErrorCode err = Interop.ThemeManager.LoaderRemoveEvent(_loaderHandle, _eventId);
93 if (err != Interop.ThemeManager.ErrorCode.None)
95 throw Interop.ThemeManager.ThemeManagerErrorFactory.GetException(err, "Failed to remove event");
103 /// Sets current theme.
105 /// <since_tizen> 8 </since_tizen>
106 /// <exception cref="ArgumentException">Thrown when failed because of an invalid argument.</exception>
107 [EditorBrowsable(EditorBrowsableState.Never)]
108 public Theme CurrentTheme
112 if (_currentTheme != null && _currentTheme.Id.Length > 0)
113 return _currentTheme;
115 Interop.ThemeManager.ErrorCode err = Interop.ThemeManager.LoaderLoadCurrentTheme(_loaderHandle, out IntPtr _themeHandle);
116 if (err != Interop.ThemeManager.ErrorCode.None)
118 throw Interop.ThemeManager.ThemeManagerErrorFactory.GetException(err, "Failed to load current theme");
121 _currentTheme = new Theme(_themeHandle);
122 return _currentTheme;
127 throw new ArgumentException("value is null");
129 Interop.ThemeManager.ErrorCode err = Interop.ThemeManager.LoaderSetCurrentTheme(_loaderHandle, value.Id);
130 if (err != Interop.ThemeManager.ErrorCode.None)
132 Log.Warn(LogTag, "Failed to set current. Err = " + err);
133 throw Interop.ThemeManager.ThemeManagerErrorFactory.GetException(err, "Failed to set current theme");
136 if(_currentTheme != value)
137 _currentTheme = value;
144 /// <since_tizen> 8 </since_tizen>
145 /// <exception cref="ArgumentException">Thrown when failed because of an invalid argument.</exception>
146 [EditorBrowsable(EditorBrowsableState.Never)]
147 public Theme LoadTheme(string id)
151 Interop.ThemeManager.ErrorCode err = Interop.ThemeManager.LoaderLoadTheme(_loaderHandle, id, out _themeHandle);
152 if (err != Interop.ThemeManager.ErrorCode.None)
154 throw Interop.ThemeManager.ThemeManagerErrorFactory.GetException(err, "Failed to load theme");
157 return new Theme(_themeHandle);
161 /// Gets bundle of theme IDs.
163 /// <since_tizen> 8 </since_tizen>
164 /// <exception cref="ArgumentException">Thrown when failed because of an invalid argument.</exception>
165 /// <exception cref="OutOfMemoryException">Thrown when failed because of out of memory.</exception>
166 [EditorBrowsable(EditorBrowsableState.Never)]
167 public IEnumerable<string> QueryIds()
170 string[] stringArray;
173 Interop.ThemeManager.ErrorCode err = Interop.ThemeManager.LoaderQueryId(_loaderHandle, out ids, out count);
174 if (err != Interop.ThemeManager.ErrorCode.None)
176 throw Interop.ThemeManager.ThemeManagerErrorFactory.GetException(err, "Failed to query ids");
179 IntPtrToStringArray(ids, count, out stringArray);
183 static void IntPtrToStringArray(IntPtr unmanagedArray, int size, out string[] managedArray)
185 managedArray = new string[size];
186 IntPtr[] IntPtrArray = new IntPtr[size];
187 Marshal.Copy(unmanagedArray, IntPtrArray, 0, size);
188 for (int iterator = 0; iterator < size; iterator++)
190 managedArray[iterator] = Marshal.PtrToStringAnsi(IntPtrArray[iterator]);
195 /// Releases all resources used by the ThemeLoader class.
197 /// <since_tizen> 8 </since_tizen>
198 [EditorBrowsable(EditorBrowsableState.Never)]
199 public void Dispose()
202 GC.SuppressFinalize(this);
206 /// Releases the unmanaged resources used by the ThemeLoader class specifying whether to perform a normal dispose operation.
208 /// <param name="disposing">true for a normal dispose operation; false to finalize the handle.</param>
209 protected virtual void Dispose(bool disposing)
214 if (_loaderHandle != IntPtr.Zero)
216 Interop.ThemeManager.LoaderDestroy(_loaderHandle);
217 _loaderHandle = IntPtr.Zero;
220 if (disposing && _currentTheme != null)
221 _currentTheme.Dispose();