Widget application

The widget applications are commonly used in applications like home screen or lock screen. The .NET Tizen API provides two class that allows you to implement widget applications:

  1. NUIWidgetApplication
  2. WidgetApplication

An instance of the widget is managed by a Widget Viewer application. Widget process is created when a widget application is added to the widget viewer.

Figure: Widget application

NUI widget application

Widget features

The main features of widget application include:

  • Creating widget applications

You can create a widget application that usually has single process for maintaining the main loop. Within the process, the framework can create multiple widget instances that can share the same resources. The widget application can also share data with other applications. The widget application can also share data with other applications. Multiple instances of the same widget app could be used to create different UI for different size of the widget instance.

  • Managing multiple widget instances

    Whenever a widget instance is requested, the framework creates one. You can manage the widget instances by updating or destroying them, or by retrieving information about them.

  • Managing the life-cycle

    You can manage the widget instance life-cycle through callback methods that are triggered as the instance state changes.

  • Creating the widget UI

The widget application can create a user interface that appears on the home screen or other widget viewer application. The UI of the widget application limits scroll actions to provide a better user experience. It is recommended that you design UI layout within the given screen size.

Note

To draw the layout, you have to use the Window instance received from the OnCreate callback. If you create additional windows, the stack of widget application windows gets corrupted. This is because the platform handles the widget application window in a particular way.

You can scroll this table.

Note

To draw the UI, use a single window as a protected property of the Tizen.Applications.WidgetBase class. Do not create additional windows. A stack of widget application windows gets corrupted, because the platform handles the widget application window in a special way.

You can scroll this table.

Widget instances

NUIWidgetApplication makes diverse class instances whenever WidgetView requests for a widget instance.

The widget instance has its own life-cycle similar to that of the widget application. However, the widget instance is an object created by the widget viewer application. Many widget instances can be running on a widget application process.

Note

The case to use many widget instances in one widget application is known as multi-instance. In some devices, the multi-instance may not be supported. If a device does not support multi-instance, an error message is displayed.

WidgetView shows the contents drawn by Widget on the screen.

To summarize, you create a NUI WidgetApplication, create a NUI WidgetView, and use Widget to view layout on the screen.

You can scroll this table.

The WidgetApplication class provides the WidgetApplication(IDictionary< Type, string > typeInfo) constructor, that allows a widget application to have multiple widget classes. The widget applications with multiple classes can make diverse class instances whenever widget viewer applications, such as the home screen and the lock screen, request for a widget instance.

The widget instance has its own life-cycle similar to the widget application. However, the widget instance is only an object shown by the widget viewer applications. Many widget instances can be running on the same widget application process.

You can scroll this table.

Figure: Widget instances

Each widget application has 1 or more widget instances

Widget instance states and events

The following figure illustrates the widget instance states during the instance life-cycle:

  • When the application is in the Ready state, the instance does not exist.
  • When the instance is created, it is in the Created state.
  • When the instance is visible, it is in the Running state.
  • When the instance is invisible, it is in the Paused state.
  • When the instance is destroyed, it is in the Destroyed state.

Figure: Widget instance life-cycle

Widget instance life-cycle

The following table lists the callbacks you can use as the instance state changes.

Table: Instance state change callbacks

You can scroll this table.
You can scroll this table.
Callback Description
OnCreate() Called after the widget instance is created.
OnTerminate() Called before the widget instance is destroyed.
OnPause() Called when the widget is invisible.
OnResume() Called when the widget is visible.
OnResize() Called before the widget size is changed.
OnUpdate() Called when an event for updating the widget is received.

You can declare a widget class by inheriting the Tizen.NUI.Widget class. For example:

C#
Copy
class MyWidget : Tizen.NUI.Widget { public override void OnCreate(string contentInfo, Window window) {} public override void OnTerminate(string contentInfo, Widget.TerminationType type) {} public override void OnPause() {} public override void OnResume() {} public override void OnResize(Window window) {} public override void OnUpdate(string contentInfo, int isForce) {} }

The following table lists the callbacks you can use as the instance state changes.

Table: Instance state change callbacks

You can scroll this table.
You can scroll this table.
Callback Description
OnCreate() Called after the widget instance is created.
OnDestroy() Called before the widget instance is destroyed.
OnPause() Called when the widget is invisible.
OnResume() Called when the widget is visible.
OnResize() Called before the widget size is changed.
OnUpdate() Called when an event for updating the widget is received.

You can declare a widget class by inheriting the Tizen.Applications.WidgetBase class. For example:

C#
Copy
class MyWidget : WidgetBase { public override void OnCreate(Bundle content, int w, int h) {} public override void OnPause() {} public override void OnResume() {} public override void OnResize(int w, int h) {} public override void OnUpdate(Bundle content, bool isForce) {} public override void OnDestroy(WidgetBase.WidgetDestroyType reason, Bundle content) {} }

Prerequisites

To enable your application to use the widget functionality, you have to modify application manifest file by adding proper privileges:

XML
Copy
<privileges> <privilege>http://tizen.org/privilege/widget.viewer</privilege> <privilege>http://tizen.org/privilege/appmanager.launch</privilege> </privileges>

Create a widget application

  1. To use the methods and properties of Tizen.NUI namespace, include it in your application:

    C#
    Copy
    using Tizen.NUI;
  2. Define your widget application class, which is inherited from NUIWidgetApplication class:

    C#
    Copy
    class Program : NUIWidgetApplication
  3. The widget application starts with Main(), which creates and initializes the application. Run() method of NUIWidgetApplication class is used to start the application event-loop. NUIWidgetApplication class provides two kinds of constructors:

    • For using the NUIWidgetApplication(Type type) constructor, in case the widget application’s ID is the same as the application ID:
    C#
    Copy
    static void Main(string[] args) { var app = new Program(typeof(MyWidget)); app.Run(args); }
    • For using the NUIWidgetApplication(Dictionary< Type, string > typeInfo) constructor, in case your widget applications have multiple widget classes. For multiple instances, add <widget-class> in XML as follows:
    XML
    Copy
    <widget-class classid="second" update-period="0"> <support-size preview="Widget.png">2x2</support-size> </widget-class>

    You can then modify the code as follows:

    C#
    Copy
    static void Main(string[] args) { Dictionary<System.Type, string> widgetSet = new Dictionary<Type, string>(); widgetSet.Add(typeof(MyWidget), "second@org.tizen.example.WidgetTemplate"); var app = new Program(widgetSet); app.Run(args); }
  4. Define your widget class, which is inherited from Widget:

    C#
    Copy
    class MyWidget : Widget
  5. Override event callback methods of your new class:

    C#
    Copy
    class MyWidget : Tizen.NUI.Widget { protected override void OnCreate(string contentInfo, Window window) { /// Create the UI /// .... base.OnCreate(contentInfo, window); } }
  6. Drawing the widget UI in OnCreate():

    Initialize resources for this widget instance and draw the content on the screen.

    The widget UI is drawn in the OnCreate() callback of your widget class:

    C#
    Copy
    protected override void OnCreate(string contentInfo, Window window) { View rootView = new View(); rootView.BackgroundColor = Color.White; rootView.Size2D = window.Size; rootView.PivotPoint = PivotPoint.Center; window.GetDefaultLayer().Add(rootView); TextLabel sampleLabel = new TextLabel("Hello World!"); sampleLabel.FontFamily = "SamsungOneUI 500"; sampleLabel.PointSize = 71; sampleLabel.TextColor = Color.Black; sampleLabel.SizeWidth = 200; sampleLabel.PivotPoint = PivotPoint.Center; rootView.Add(sampleLabel); }
You can scroll this table.

The widget application starts with the Main() function, which creates and initializes the application. The Run() method of the Tizen.Applications.WidgetApplication class is used to start the application event loop. The Tizen.Applications.WidgetApplication class provides 2 kinds of constructors:

  • If you create the widget application with the WidgetApplication(Type type) constructor, that widget application’s ID is the same as the application ID.
  • Using the WidgetApplication(IDictionary<Type, string> typeInfo) constructor, you can make widget applications with multiple widget classes.
  1. To use the methods and properties of the Tizen.Applications namespace, include it in your application:

    C#
    Copy
    using Tizen.Applications;
  2. Define your widget class, which is inherited from the Tizen.Applications.WidgetBase class:

    C#
    Copy
    class MyWidget : WidgetBase {}
  3. Override the event callback methods of your new class:

    • The OnCreate() callback is triggered when the widget instance is created.

      Initialize resources for this widget instance and draw the UI. If bundle content is not NULL, restore the previous status:

      C#
      Copy
      public override void OnCreate(Bundle content, int w, int h) { try { base.OnCreate(content, w, h); /// Recover the previous status with the bundle object /// Create the UI } catch (Exception e) { Log.Warn(_logTag, "exception " + e); } }
    • The OnDestroy() callback is triggered when the widget instance is destroyed.

      Release all widget resources. If the reason for the termination is not WidgetBase.WidgetDestroyType.Permanent, store the current status with the incoming bundle.

      C#
      Copy
      public override void OnDestroy(WidgetBase.WidgetDestroyType reason, Bundle content) { if (reason != WidgetBase.WidgetDestroyType.Permanent) /// Save the current status at the bundle object }
    • The OnPause() callback is triggered when the widget instance is paused.

      Take the necessary actions when the widget instance becomes invisible. The framework can destroy a paused widget instance.

      C#
      Copy
      public override void OnPause() {}
    • The OnResume() callback is triggered when the widget instance is resumed.

      Take the necessary actions when the widget instance becomes visible.

      C#
      Copy
      public override void OnResume() {}
    • The OnResize() callback is triggered before the widget instance is resized.

      Take the necessary actions to accommodate the new size.

      C#
      Copy
      public override void OnResize(int w, int h) {}
    • The OnUpdate() callback is triggered when a widget update event is received.

      Take the necessary actions for the widget update. If the isForce parameter is true, the widget can be updated even in the pause state.

      C#
      Copy
      public override void OnUpdate(Bundle content, bool isForce) {}
  4. The widget UI is drawn in the OnCreate() callback of your widget class:

C#
Copy
public override void OnCreate(Bundle content, int w, int h) { try { base.OnCreate(content, w, h); Conformant conformant = new Conformant(Window); conformant.Show(); Scroller scroller = new Scroller(Window) { AlignmentX = -1, AlignmentY = -1, WeightX = 1, WeightY = 1, ScrollBlock = ScrollBlock.None, }; scroller.Show(); Box box = new Box(Window) { AlignmentX = -1, AlignmentY = -1, WeightX = 1, WeightY = 1, }; box.Show(); scroller.SetContent(box); conformant.SetContent(scroller); Button exitButton = new Button(Window) { Text = "Exit Test", AlignmentX = -1, AlignmentY = -1, WeightX = 1, WeightY = 1 }; box.PackEnd(exitButton); exitButton.Show(); } catch (Exception e) { Log.Warn(_logTag, "exception " + e); } }
You can scroll this table.

Data sharing between the widget application and other applications

You can share data between widget applications and UI (or service) applications. However, you must understand that this kind of data sharing is dependent on the file system. The reason is that the system (home screen) controls the widget application life-cycle, while the UI application life-cycle is mostly explicitly controlled by the user.

For example, consider the differences between a Weather application and a Weather widget:

  • The Weather application is launched when the user selects it from the application list.
  • The widget is launched when the home screen is on screen and is terminated when the home screen is hidden.

Although the widget wants to share some data from the Weather application (such as the user’s favorite city), it is ineffective for the widget to launch the Weather application every time to retrieve such data. This inefficiency makes it difficult to use typical IPC mechanisms, such as sockets and message ports, for which both the receiver and sender processes must be alive. To overcome this limitation, the widget application must use a communication method that stores data permanently somewhere in the system.

In the Tizen platform, applications in the same package (including widget applications) can access files in the data directory of the package installation path. This means that the UI (or service) application can first write files to the data directory, and the widget can later read them, or vice versa.

Figure: Sharing through the data directory

Sharing through the data directory

To manage data through the data directory, you can use the methods and properties of the Tizen.Applications.Preference class to store and retrieve key-value pairs.

If an application requires complex control over a widget, such as Music Player, it must implement a service application in the middle and use a data control with the classes and methods of the Tizen.Applications.DataControl namespace.

For example, a music-player-service service application is needed to control the audio device, process audio files, and handle play and stop signals. The music-player-ui and music-player-widget applications display the UI controls, title, album art, and other content retrieved from the music-player-service service application. The service application can export its data using the data control to provide data to the other applications (widget and UI) simultaneously. The following figure illustrates the typical data control flows between the set of UI, service, and widget applications.

Figure: Sharing through data control

Sharing through data control

  • Dependencies
    • Tizen 4.0 and Higher
Watch Application
Next Exchange Data Between Applications
Submit your feedback to GitHub