--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+internal static partial class Interop
+{
+ internal static partial class Libraries
+ {
+ public const string AppCommon = "libcapi-appfw-app-common.so.0";
+ public const string AppcoreWidget = "libcapi-appfw-widget-application.so.1";
+ public const string WidgetService = "libwidget_service.so.1";
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Runtime.InteropServices;
+
+using Tizen.Applications;
+
+internal static partial class Interop
+{
+ internal static partial class Widget
+ {
+ internal enum WidgetAppDestroyType
+ {
+ Permanent = 0,
+ Temporary
+ }
+
+ internal enum AppEventType
+ {
+ LowMemory = 0,
+ LowBattery,
+ LanguageChanged,
+ DeviceOrientationChanged,
+ RegionFormatChanged,
+ SuspendedStateChanged
+ }
+
+ internal enum ErrorCode : int
+ {
+ None = Tizen.Internals.Errors.ErrorCode.None,
+ InvalidParameter = Tizen.Internals.Errors.ErrorCode.InvalidParameter,
+ OutOfMemory = Tizen.Internals.Errors.ErrorCode.OutOfMemory,
+ ResourceBusy = Tizen.Internals.Errors.ErrorCode.ResourceBusy,
+ PermissionDenied = Tizen.Internals.Errors.ErrorCode.PermissionDenied,
+ Canceled = Tizen.Internals.Errors.ErrorCode.Canceled,
+ IoError = Tizen.Internals.Errors.ErrorCode.IoError,
+ TimedOut = Tizen.Internals.Errors.ErrorCode.TimedOut,
+ NotSupported = Tizen.Internals.Errors.ErrorCode.NotSupported,
+ FileNoSpaceOnDevice = Tizen.Internals.Errors.ErrorCode.FileNoSpaceOnDevice,
+ Fault = -0x02F40000 | 0x0001,
+ AlreadyExist = -0x02F40000 | 0x0002,
+ AlreadyStarted = -0x02F40000 | 0x0004,
+ NotExist = -0x02F40000 | 0x0008,
+ Disabled = -0x02F40000 | 0x0010,
+ MaxExceeded = -0x02F40000 | 0x0011,
+ }
+
+ internal delegate void AppEventCallback(IntPtr handle, IntPtr data);
+
+ internal delegate IntPtr WidgetAppCreateCallback(IntPtr userData);
+
+ internal delegate void WidgetAppTerminateCallback(IntPtr userData);
+
+ internal delegate int WidgetInstanceCreateCallback(IntPtr context, IntPtr content, int w, int h, IntPtr userData);
+
+ internal delegate int WidgetInstanceDestroyCallback(IntPtr context, WidgetAppDestroyType reason, IntPtr content, IntPtr userData);
+
+ internal delegate int WidgetInstancePauseCallback(IntPtr context, IntPtr userData);
+
+ internal delegate int WidgetInstanceResumeCallback(IntPtr context, IntPtr userData);
+
+ internal delegate int WidgetInstanceResizeCallback(IntPtr context, int w, int h, IntPtr userData);
+
+ internal delegate int WidgetInstanceUpdateCallback(IntPtr context, IntPtr content, int force, IntPtr userData);
+
+ [DllImport(Libraries.AppcoreWidget, EntryPoint = "widget_app_main")]
+ internal static extern ErrorCode Main(int argc, string[] argv, ref WidgetAppLifecycleCallbacks callback, IntPtr userData);
+
+ [DllImport(Libraries.AppcoreWidget, EntryPoint = "widget_app_exit")]
+ internal static extern void Exit();
+
+ [DllImport(Libraries.AppcoreWidget, EntryPoint = "widget_app_add_event_handler")]
+ internal static extern ErrorCode AddEventHandler(out IntPtr handle, AppEventType eventType, AppEventCallback callback, IntPtr data);
+
+ [DllImport(Libraries.AppcoreWidget, EntryPoint = "widget_app_remove_event_handler")]
+ internal static extern ErrorCode RemoveEventHandler(IntPtr handle);
+
+ [DllImport(Libraries.AppcoreWidget, EntryPoint = "widget_app_class_create")]
+ internal static extern IntPtr CreateClass(WidgetiInstanceLifecycleCallbacks callback, IntPtr userData);
+
+ [DllImport(Libraries.AppcoreWidget, EntryPoint = "widget_app_class_add")]
+ internal static extern IntPtr AddClass(IntPtr handle, string classId, WidgetiInstanceLifecycleCallbacks callback, IntPtr userData);
+
+ [DllImport(Libraries.AppcoreWidget, EntryPoint = "widget_app_terminate_context")]
+ internal static extern ErrorCode TerminateContext(IntPtr handle);
+
+ [DllImport(Libraries.AppcoreWidget, EntryPoint = "widget_app_context_set_content_info")]
+ internal static extern ErrorCode SetContent(IntPtr handle, SafeBundleHandle content);
+
+ [DllImport(Libraries.AppcoreWidget, EntryPoint = "widget_app_context_set_title")]
+ internal static extern ErrorCode SetTitle(IntPtr handle, string title);
+
+ [DllImport(Libraries.AppcoreWidget, EntryPoint = "widget_app_get_elm_win")]
+ internal static extern ErrorCode GetWin(IntPtr handle, out IntPtr win);
+
+ [DllImport(Libraries.AppCommon, EntryPoint = "app_event_get_low_memory_status")]
+ internal static extern Tizen.Internals.Errors.ErrorCode AppEventGetLowMemoryStatus(IntPtr handle, out LowMemoryStatus status);
+
+ [DllImport(Libraries.AppCommon, EntryPoint = "app_event_get_low_battery_status")]
+ internal static extern Tizen.Internals.Errors.ErrorCode AppEventGetLowBatteryStatus(IntPtr handle, out LowBatteryStatus status);
+
+ [DllImport(Libraries.AppCommon, EntryPoint = "app_event_get_language")]
+ internal static extern Tizen.Internals.Errors.ErrorCode AppEventGetLanguage(IntPtr handle, out string lang);
+
+ [DllImport(Libraries.AppCommon, EntryPoint = "app_event_get_region_format")]
+ internal static extern Tizen.Internals.Errors.ErrorCode AppEventGetRegionFormat(IntPtr handle, out string region);
+
+ [StructLayoutAttribute(LayoutKind.Sequential)]
+ internal struct WidgetAppLifecycleCallbacks
+ {
+ public WidgetAppCreateCallback OnCreate;
+ public WidgetAppTerminateCallback OnTerminate;
+ }
+
+ [StructLayoutAttribute(LayoutKind.Sequential)]
+ internal struct WidgetiInstanceLifecycleCallbacks
+ {
+ public WidgetInstanceCreateCallback OnCreate;
+ public WidgetInstanceDestroyCallback OnDestroy;
+ public WidgetInstancePauseCallback OnPause;
+ public WidgetInstanceResumeCallback OnResume;
+ public WidgetInstanceResizeCallback OnResize;
+ public WidgetInstanceUpdateCallback OnUpdate;
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using Tizen.Internals.Errors;
+
+namespace Tizen.Applications.CoreBackend
+{
+ internal class WidgetCoreBackend : ICoreBackend
+ {
+ protected static readonly string LogTag = typeof(WidgetCoreBackend).Namespace;
+
+ private Dictionary<EventType, object> _handlers = new Dictionary<EventType, object>();
+
+ private bool _disposedValue = false;
+
+ private Interop.Widget.AppEventCallback _lowMemoryCallback;
+ private Interop.Widget.AppEventCallback _lowBatteryCallback;
+ private Interop.Widget.AppEventCallback _localeChangedCallback;
+ private Interop.Widget.AppEventCallback _regionChangedCallback;
+
+ private IntPtr _lowMemoryEventHandle = IntPtr.Zero;
+ private IntPtr _lowBatteryEventHandle = IntPtr.Zero;
+ private IntPtr _localeChangedEventHandle = IntPtr.Zero;
+ private IntPtr _regionChangedEventHandle = IntPtr.Zero;
+
+ private Interop.Widget.WidgetAppLifecycleCallbacks _callbacks;
+
+ internal IList<WidgetType> WidgetTypes = new List<WidgetType>();
+
+ public WidgetCoreBackend()
+ {
+ _lowMemoryCallback = new Interop.Widget.AppEventCallback(OnLowMemoryNative);
+ _lowBatteryCallback = new Interop.Widget.AppEventCallback(OnLowBatteryNative);
+ _localeChangedCallback = new Interop.Widget.AppEventCallback(OnLocaleChangedNative);
+ _regionChangedCallback = new Interop.Widget.AppEventCallback(OnRegionChangedNative);
+
+ _callbacks.OnCreate = new Interop.Widget.WidgetAppCreateCallback(OnCreateNative);
+ _callbacks.OnTerminate = new Interop.Widget.WidgetAppTerminateCallback(OnTerminateNative);
+ }
+
+ ~WidgetCoreBackend()
+ {
+ Dispose(false);
+ }
+
+ internal void CreateWidgetTypes(IDictionary<Type, string> typeInfo)
+ {
+ foreach (Type w in typeInfo.Keys)
+ {
+ WidgetTypes.Add(new WidgetType(w, typeInfo[w]));
+ }
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ protected virtual void Dispose(bool disposing)
+ {
+ if (!_disposedValue)
+ {
+ if (disposing)
+ {
+ // Release disposable objects
+ }
+
+ if (_lowMemoryEventHandle != IntPtr.Zero)
+ {
+ Interop.Widget.RemoveEventHandler(_lowMemoryEventHandle);
+ }
+ if (_lowBatteryEventHandle != IntPtr.Zero)
+ {
+ Interop.Widget.RemoveEventHandler(_lowBatteryEventHandle);
+ }
+ if (_localeChangedEventHandle != IntPtr.Zero)
+ {
+ Interop.Widget.RemoveEventHandler(_localeChangedEventHandle);
+ }
+ if (_regionChangedEventHandle != IntPtr.Zero)
+ {
+ Interop.Widget.RemoveEventHandler(_regionChangedEventHandle);
+ }
+
+ _disposedValue = true;
+ }
+ }
+
+ public void Exit()
+ {
+ Interop.Widget.Exit();
+ }
+
+ public void Run(string[] args)
+ {
+ Interop.Widget.ErrorCode err = Interop.Widget.ErrorCode.None;
+ err = Interop.Widget.AddEventHandler(out _lowMemoryEventHandle, Interop.Widget.AppEventType.LowMemory, _lowMemoryCallback, IntPtr.Zero);
+ if (err != Interop.Widget.ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to add event handler for LowMemory event. Err = " + err);
+ }
+ err = Interop.Widget.AddEventHandler(out _lowBatteryEventHandle, Interop.Widget.AppEventType.LowBattery, _lowBatteryCallback, IntPtr.Zero);
+ if (err != Interop.Widget.ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to add event handler for LowBattery event. Err = " + err);
+ }
+
+ err = Interop.Widget.AddEventHandler(out _localeChangedEventHandle, Interop.Widget.AppEventType.LanguageChanged, _localeChangedCallback, IntPtr.Zero);
+ if (err != Interop.Widget.ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to add event handler for LocaleChanged event. Err = " + err);
+ }
+
+ err = Interop.Widget.AddEventHandler(out _regionChangedEventHandle, Interop.Widget.AppEventType.RegionFormatChanged, _regionChangedCallback, IntPtr.Zero);
+ if (err != Interop.Widget.ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to add event handler for RegionFormatChanged event. Err = " + err);
+ }
+
+ err = Interop.Widget.Main(args.Length, args, ref _callbacks, IntPtr.Zero);
+ if (err != Interop.Widget.ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to run the application. Err = " + err);
+ }
+ }
+
+ private IntPtr OnCreateNative(IntPtr data)
+ {
+ if (_handlers.ContainsKey(EventType.Created))
+ {
+ var handler = _handlers[EventType.Created] as Action;
+ handler?.Invoke();
+ }
+
+ IntPtr h = IntPtr.Zero;
+ foreach (WidgetType type in WidgetTypes)
+ h = type.Bind(h);
+
+ return h;
+ }
+
+ private void OnTerminateNative(IntPtr data)
+ {
+ if (_handlers.ContainsKey(EventType.Terminated))
+ {
+ var handler = _handlers[EventType.Terminated] as Action;
+ handler?.Invoke();
+ }
+ }
+
+ public void AddEventHandler(EventType evType, Action handler)
+ {
+ _handlers.Add(evType, handler);
+ }
+
+ public void AddEventHandler<TEventArgs>(EventType evType, Action<TEventArgs> handler) where TEventArgs : EventArgs
+ {
+ _handlers.Add(evType, handler);
+ }
+
+ private void OnLowMemoryNative(IntPtr infoHandle, IntPtr data)
+ {
+ LowMemoryStatus status = LowMemoryStatus.None;
+ ErrorCode err = Interop.Widget.AppEventGetLowMemoryStatus(infoHandle, out status);
+ if (err != ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to get memory status. Err = " + err);
+ }
+ if (_handlers.ContainsKey(EventType.LowMemory))
+ {
+ var handler = _handlers[EventType.LowMemory] as Action<LowMemoryEventArgs>;
+ handler?.Invoke(new LowMemoryEventArgs(status));
+ }
+ }
+
+ private void OnLowBatteryNative(IntPtr infoHandle, IntPtr data)
+ {
+ LowBatteryStatus status = LowBatteryStatus.None;
+ ErrorCode err = Interop.Widget.AppEventGetLowBatteryStatus(infoHandle, out status);
+ if (err != ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to get battery status. Err = " + err);
+ }
+ if (_handlers.ContainsKey(EventType.LowBattery))
+ {
+ var handler = _handlers[EventType.LowBattery] as Action<LowBatteryEventArgs>;
+ handler?.Invoke(new LowBatteryEventArgs(status));
+ }
+ }
+
+ private void OnLocaleChangedNative(IntPtr infoHandle, IntPtr data)
+ {
+ string lang;
+ ErrorCode err = Interop.Widget.AppEventGetLanguage(infoHandle, out lang);
+ if (err != ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to get changed language. Err = " + err);
+ }
+ if (_handlers.ContainsKey(EventType.LocaleChanged))
+ {
+ var handler = _handlers[EventType.LocaleChanged] as Action<LocaleChangedEventArgs>;
+ handler?.Invoke(new LocaleChangedEventArgs(lang));
+ }
+ }
+
+ private void OnRegionChangedNative(IntPtr infoHandle, IntPtr data)
+ {
+ string region;
+ ErrorCode err = Interop.Widget.AppEventGetRegionFormat(infoHandle, out region);
+ if (err != ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to get changed region format. Err = " + err);
+ }
+ if (_handlers.ContainsKey(EventType.RegionFormatChanged))
+ {
+ var handler = _handlers[EventType.RegionFormatChanged] as Action<RegionFormatChangedEventArgs>;
+ handler?.Invoke(new RegionFormatChangedEventArgs(region));
+ }
+ }
+
+ }
+}
--- /dev/null
+<Project Sdk="Microsoft.NET.Sdk">
+
+ <PropertyGroup>
+ <Version>1.0.8</Version>
+ <Authors>Samsung Electronics</Authors>
+ <Copyright>© Samsung Electronics Co., Ltd All Rights Reserved</Copyright>
+ <Description>Provides the Widget Application API for Tizen .NET</Description>
+ <PackageProjectUrl>https://www.tizen.org/</PackageProjectUrl>
+ <PackageLicenseUrl>https://www.apache.org/licenses/LICENSE-2.0</PackageLicenseUrl>
+ <PackageIconUrl>https://developer.tizen.org/sites/default/files/images/tizen-pinwheel-on-light-rgb_64_64.png</PackageIconUrl>
+ </PropertyGroup>
+
+ <PropertyGroup>
+ <TargetFramework>netstandard1.3</TargetFramework>
+ <AllowUnsafeBlocks>True</AllowUnsafeBlocks>
+ <SignAssembly>True</SignAssembly>
+ <AssemblyOriginatorKeyFile>Tizen.Applications.WidgetApplication.snk</AssemblyOriginatorKeyFile>
+ <PublicSign Condition="'$(OS)' != 'Windows_NT'">true</PublicSign>
+ <GenerateReferenceAssembly>True</GenerateReferenceAssembly>
+ </PropertyGroup>
+
+ <ItemGroup>
+ <PackageReference Include="Tizen" Version="1.0.5" />
+ <PackageReference Include="Tizen.Applications.Common" Version="1.5.8" />
+ <PackageReference Include="ElmSharp" Version="1.2.1" />
+ </ItemGroup>
+
+</Project>
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+using Tizen.Applications.CoreBackend;
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// Represents a widget application.
+ /// </summary>
+ public class WidgetApplication : CoreApplication
+ {
+ /// <summary>
+ /// Initializes the WidgetApplication class with the type and application ID.
+ /// </summary>
+ /// <param name="typeInfo">Map structure for the derived class type and widget ID.</param>
+ public WidgetApplication(IDictionary<Type, string> typeInfo) : base(new WidgetCoreBackend())
+ {
+ WidgetCoreBackend core = Backend as WidgetCoreBackend;
+
+ core?.CreateWidgetTypes(typeInfo);
+ }
+
+ /// <summary>
+ /// Initializes the WidgetApplication class with the type.
+ /// </summary>
+ /// <remarks>Widget ID will be replaced as the application ID.</remarks>
+ /// <param name="type">Derived class type.</param>
+ public WidgetApplication(Type type) : base(new WidgetCoreBackend())
+ {
+ WidgetCoreBackend core = Backend as WidgetCoreBackend;
+
+ core?.CreateWidgetTypes(new Dictionary<Type, string>() { {type, ApplicationInfo.ApplicationId } });
+ }
+
+ /// <summary>
+ /// Gets all instances of the widget associated with the type.
+ /// </summary>
+ /// <param name="type">Class type for the widget.</param>
+ public IEnumerable<WidgetBase> GetInstances(Type type)
+ {
+ WidgetCoreBackend core = Backend as WidgetCoreBackend;
+
+ if (core == null)
+ return null;
+
+ foreach (WidgetType w in core.WidgetTypes)
+ {
+ if (w.ClassType == type)
+ {
+ return w.WidgetInstances;
+ }
+ }
+
+ return null;
+ }
+
+ /// <summary>
+ /// Runs the widget application's main loop.
+ /// </summary>
+ /// <param name="args">Arguments from the commandline.</param>
+ public override void Run(string[] args)
+ {
+ base.Run(args);
+ }
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using ElmSharp;
+using System;
+
+namespace Tizen.Applications
+{
+ /// <summary>
+ /// The abstract class for widget instances.
+ /// </summary>
+ public abstract class WidgetBase
+ {
+ internal IntPtr Handle;
+ internal string Id;
+ protected static readonly string LogTag = typeof(WidgetBase).Namespace;
+
+ /// <summary>
+ /// Window object for this widget instance.
+ /// It will be created after OnCreate method is invoked.
+ /// </summary>
+ protected Window Window;
+
+ /// <summary>
+ /// Delete type.
+ /// </summary>
+ public enum WidgetDestroyType
+ {
+ /// <summary>
+ /// User deleted this widget from the viewer.
+ /// </summary>
+ Permanent = 0,
+
+ /// <summary>
+ /// Widget is deleted because of other reasons. (For e.g., widget process is terminated temporarily by the system)
+ /// </summary>
+ Temporary
+ }
+
+ /// <summary>
+ /// Constructor.
+ /// </summary>
+ public WidgetBase()
+ {
+ }
+
+ /// <summary>
+ /// Sets the content information to the widget.
+ /// </summary>
+ /// <param name="info">The data set to save.</param>
+ /// <exception cref="ArgumentException">Thrown when failed because of an invalid argument.</exception>
+ /// <exception cref="NotSupportedException">Thrown when the API is not supported in this device.</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of an unrecoverable error.</exception>
+ public void SetContent(Bundle info)
+ {
+ Interop.Widget.ErrorCode err = Interop.Widget.SetContent(Handle, info.SafeBundleHandle);
+
+ if (err != Interop.Widget.ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to set content. Err = " + err);
+
+ switch(err)
+ {
+ case Interop.Widget.ErrorCode.InvalidParameter:
+ throw new ArgumentException("Invalid parameter of SetContent()");
+
+ case Interop.Widget.ErrorCode.NotSupported:
+ throw new NotSupportedException();
+
+ case Interop.Widget.ErrorCode.OutOfMemory:
+ case Interop.Widget.ErrorCode.Fault:
+ throw new InvalidOperationException();
+ }
+
+ }
+ }
+
+ /// <summary>
+ /// Sends the title to the widget.
+ /// </summary>
+ /// <param name="title">When an accessibility mode is turned on, this string will be read.</param>
+ /// <exception cref="ArgumentException">Thrown when failed because of an invalid argument.</exception>
+ /// <exception cref="NotSupportedException">Thrown when the API is not supported in this device.</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of an unrecoverable error.</exception>
+ public void SetTitle(string title)
+ {
+ Interop.Widget.ErrorCode err = Interop.Widget.SetTitle(Handle, title);
+
+ if (err != Interop.Widget.ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to set title. Err = " + err);
+
+ switch (err)
+ {
+ case Interop.Widget.ErrorCode.InvalidParameter:
+ throw new ArgumentException("Invalid parameter of SetContent()");
+
+ case Interop.Widget.ErrorCode.NotSupported:
+ throw new NotSupportedException();
+
+ case Interop.Widget.ErrorCode.OutOfMemory:
+ case Interop.Widget.ErrorCode.Fault:
+ throw new InvalidOperationException();
+ }
+ }
+ }
+
+ /// <summary>
+ /// Finishes the context for the widget instance.
+ /// </summary>
+ /// <exception cref="NotSupportedException">Thrown when the API is not supported in this device.</exception>
+ /// <exception cref="InvalidOperationException">Thrown in case of an unrecoverable error.</exception>
+ public void Exit()
+ {
+ Interop.Widget.ErrorCode err = Interop.Widget.TerminateContext(Handle);
+
+ if (err != Interop.Widget.ErrorCode.None)
+ {
+ Log.Error(LogTag, "Failed to terminate context. Err = " + err);
+
+ switch (err)
+ {
+ case Interop.Widget.ErrorCode.NotSupported:
+ throw new NotSupportedException();
+
+ case Interop.Widget.ErrorCode.InvalidParameter:
+ case Interop.Widget.ErrorCode.Fault:
+ throw new InvalidOperationException();
+ }
+ }
+ }
+
+ internal void Bind(IntPtr handle, string id)
+ {
+ Handle = handle;
+ Id = id;
+ }
+
+ /// <summary>
+ /// Overrides this method if want to handle the behavior when the widget instance is started.
+ /// </summary>
+ /// <param name="content">The data set for the previous status.</param>
+ /// <param name="w">The pixel value for the widget width.</param>
+ /// <param name="h">The pixel value for the widget height.</param>
+ public virtual void OnCreate(Bundle content, int w, int h)
+ {
+ IntPtr win;
+
+ Interop.Widget.GetWin(Handle, out win);
+ Window = new WidgetWindow(win);
+ Window.Resize(w, h);
+ Window.Show();
+ }
+
+ /// <summary>
+ /// Overrides this method if want to handle the behavior when the widget instance is destroyed.
+ /// </summary>
+ /// <param name="reason">The reason for destruction.</param>
+ /// <param name="content">The data set to save.</param>
+ public virtual void OnDestroy(WidgetDestroyType reason, Bundle content)
+ {
+ }
+
+ /// <summary>
+ /// Overrides this method if want to handle the behavior when the widget instance is paused.
+ /// </summary>
+ public virtual void OnPause()
+ {
+ }
+
+ /// <summary>
+ /// Overrides this method if want to handle the behavior when the widget instance is resumed.
+ /// </summary>
+ public virtual void OnResume()
+ {
+ }
+
+ /// <summary>
+ /// Overrides this method if want to handle the behavior when the widget instance is resized.
+ /// </summary>
+ /// <param name="w">Widget width.</param>
+ /// <param name="h">Widget height.</param>
+ public virtual void OnResize(int w, int h)
+ {
+ }
+
+ /// <summary>
+ /// Overrides this method if want to handle the behavior when the widget instance is updated.
+ /// </summary>
+ /// <param name="content">The data set for updating this widget will be provided by the requester.</param>
+ /// <param name="isForce">Although the widget is paused, if it is true, the widget can be updated.</param>
+ public virtual void OnUpdate(Bundle content, bool isForce)
+ {
+ }
+
+ }
+}
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using System;
+using System.Collections.Generic;
+
+namespace Tizen.Applications
+{
+ internal class WidgetType
+ {
+ internal readonly Type ClassType;
+ internal readonly string Id;
+ internal IList<WidgetBase> WidgetInstances = new List<WidgetBase>();
+
+ private Interop.Widget.WidgetiInstanceLifecycleCallbacks _callbacks;
+
+ internal WidgetType(Type ctype, string id)
+ {
+ ClassType = ctype;
+ Id = id;
+ _callbacks.OnCreate = new Interop.Widget.WidgetInstanceCreateCallback(OnCreate);
+ _callbacks.OnDestroy = new Interop.Widget.WidgetInstanceDestroyCallback(OnDestroy);
+ _callbacks.OnPause = new Interop.Widget.WidgetInstancePauseCallback(OnPause);
+ _callbacks.OnResume = new Interop.Widget.WidgetInstanceResumeCallback(OnResume);
+ _callbacks.OnResize = new Interop.Widget.WidgetInstanceResizeCallback(OnResize);
+ _callbacks.OnUpdate = new Interop.Widget.WidgetInstanceUpdateCallback(OnUpdate);
+ }
+
+ internal IntPtr Bind(IntPtr h)
+ {
+ return Interop.Widget.AddClass(h, Id, _callbacks, IntPtr.Zero);
+ }
+
+ private int OnCreate(IntPtr context, IntPtr content, int w, int h, IntPtr userData)
+ {
+ WidgetBase b = Activator.CreateInstance(ClassType) as WidgetBase;
+ Bundle bundle = null;
+
+ if (b == null)
+ return 0;
+
+ b.Bind(context, Id);
+ WidgetInstances.Add(b);
+ if (content != IntPtr.Zero)
+ bundle = new Bundle(new SafeBundleHandle(content, false));
+ b.OnCreate(bundle, w, h);
+
+ return 0;
+ }
+
+ private int OnDestroy(IntPtr context, Interop.Widget.WidgetAppDestroyType reason, IntPtr content, IntPtr userData)
+ {
+ foreach (WidgetBase w in WidgetInstances)
+ {
+ if(w.Handle == context)
+ {
+ Bundle bundle = null;
+
+ if (content != IntPtr.Zero)
+ bundle = new Bundle(new SafeBundleHandle(content, false));
+
+ w.OnDestroy(reason == Interop.Widget.WidgetAppDestroyType.Permanent ?
+ WidgetBase.WidgetDestroyType.Permanent :
+ WidgetBase.WidgetDestroyType.Temporary, bundle);
+ WidgetInstances.Remove(w);
+ break;
+ }
+ }
+
+ return 0;
+ }
+
+ private int OnPause(IntPtr context, IntPtr userData)
+ {
+ foreach (WidgetBase w in WidgetInstances)
+ {
+ if (w.Handle == context)
+ {
+ w.OnPause();
+ break;
+ }
+ }
+ return 0;
+ }
+
+ private int OnResume(IntPtr context, IntPtr userData)
+ {
+ foreach (WidgetBase w in WidgetInstances)
+ {
+ if (w.Handle == context)
+ {
+ w.OnResume();
+ break;
+ }
+ }
+ return 0;
+ }
+
+ private int OnResize(IntPtr context, int w, int h, IntPtr userData)
+ {
+ foreach (WidgetBase o in WidgetInstances)
+ {
+ if (o.Handle == context)
+ {
+ o.OnResize(w, h);
+ break;
+ }
+ }
+ return 0;
+ }
+
+ private int OnUpdate(IntPtr context, IntPtr content, int force, IntPtr userData)
+ {
+ foreach (WidgetBase o in WidgetInstances)
+ {
+ if (o.Handle == context)
+ {
+ Bundle bundle = null;
+
+ if (content != IntPtr.Zero)
+ bundle = new Bundle(new SafeBundleHandle(content, false));
+ o.OnUpdate(bundle, force != 0 ? true : false);
+ break;
+ }
+ }
+ return 0;
+ }
+ }
+}
+
--- /dev/null
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+using ElmSharp;
+using System;
+using System.Collections.Generic;
+
+namespace Tizen.Applications
+{
+ internal class WidgetWindow : Window
+ {
+ private IntPtr _handle;
+
+ internal WidgetWindow(IntPtr handle) : base()
+ {
+ _handle = handle;
+ Realize(null);
+ }
+
+ protected override IntPtr CreateHandle(EvasObject parent)
+ {
+ return _handle;
+ }
+ }
+}
+