Documentation for wearable native circular Ambient analog watch sample.
authorRadek Kintop <r.kintop@samsung.com>
Fri, 23 Oct 2015 08:25:21 +0000 (10:25 +0200)
committerRadek Kintop <r.kintop@samsung.com>
Fri, 23 Oct 2015 08:25:21 +0000 (10:25 +0200)
Change-Id: I22629dd0139f6f2b4d342224cb45283038da2a0e
Signed-off-by: Radek Kintop <r.kintop@samsung.com>
org.tizen.sampledescriptions/html/images/circleambientanalogwatch_wn0.png [new file with mode: 0644]
org.tizen.sampledescriptions/html/images/circleambientanalogwatch_wn1.png [new file with mode: 0644]
org.tizen.sampledescriptions/html/images/circleambientanalogwatch_wn2.png [new file with mode: 0644]
org.tizen.sampledescriptions/html/images/circleambientanalogwatch_wn4.png [new file with mode: 0644]
org.tizen.sampledescriptions/html/images/circleambientanalogwatch_wn5.png [new file with mode: 0644]
org.tizen.sampledescriptions/html/images/circleambientanalogwatch_wn6.png [new file with mode: 0644]
org.tizen.sampledescriptions/html/wearable_n/circleambientanalogwatch_wn.htm [new file with mode: 0644]
org.tizen.sampledescriptions/html/wearable_n/sd_wn.htm

diff --git a/org.tizen.sampledescriptions/html/images/circleambientanalogwatch_wn0.png b/org.tizen.sampledescriptions/html/images/circleambientanalogwatch_wn0.png
new file mode 100644 (file)
index 0000000..cd02356
Binary files /dev/null and b/org.tizen.sampledescriptions/html/images/circleambientanalogwatch_wn0.png differ
diff --git a/org.tizen.sampledescriptions/html/images/circleambientanalogwatch_wn1.png b/org.tizen.sampledescriptions/html/images/circleambientanalogwatch_wn1.png
new file mode 100644 (file)
index 0000000..39d3ebb
Binary files /dev/null and b/org.tizen.sampledescriptions/html/images/circleambientanalogwatch_wn1.png differ
diff --git a/org.tizen.sampledescriptions/html/images/circleambientanalogwatch_wn2.png b/org.tizen.sampledescriptions/html/images/circleambientanalogwatch_wn2.png
new file mode 100644 (file)
index 0000000..626ba45
Binary files /dev/null and b/org.tizen.sampledescriptions/html/images/circleambientanalogwatch_wn2.png differ
diff --git a/org.tizen.sampledescriptions/html/images/circleambientanalogwatch_wn4.png b/org.tizen.sampledescriptions/html/images/circleambientanalogwatch_wn4.png
new file mode 100644 (file)
index 0000000..1a9b70a
Binary files /dev/null and b/org.tizen.sampledescriptions/html/images/circleambientanalogwatch_wn4.png differ
diff --git a/org.tizen.sampledescriptions/html/images/circleambientanalogwatch_wn5.png b/org.tizen.sampledescriptions/html/images/circleambientanalogwatch_wn5.png
new file mode 100644 (file)
index 0000000..7f571ca
Binary files /dev/null and b/org.tizen.sampledescriptions/html/images/circleambientanalogwatch_wn5.png differ
diff --git a/org.tizen.sampledescriptions/html/images/circleambientanalogwatch_wn6.png b/org.tizen.sampledescriptions/html/images/circleambientanalogwatch_wn6.png
new file mode 100644 (file)
index 0000000..7cc9993
Binary files /dev/null and b/org.tizen.sampledescriptions/html/images/circleambientanalogwatch_wn6.png differ
diff --git a/org.tizen.sampledescriptions/html/wearable_n/circleambientanalogwatch_wn.htm b/org.tizen.sampledescriptions/html/wearable_n/circleambientanalogwatch_wn.htm
new file mode 100644 (file)
index 0000000..ab3b01a
--- /dev/null
@@ -0,0 +1,434 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
+<head>
+       <meta http-equiv="content-type" content="text/html; charset=utf-8" />
+       <meta http-equiv="X-UA-Compatible" content="IE=9" />
+       <link rel="stylesheet" type="text/css" href="../css/styles.css" />
+       <link rel="stylesheet" type="text/css" href="../css/snippet.css" />
+       <script type="text/javascript" src="../scripts/snippet.js"></script>
+       <script type="text/javascript" src="../scripts/jquery.util.js" charset="utf-8"></script>
+       <script type="text/javascript" src="../scripts/common.js" charset="utf-8"></script>
+       <script type="text/javascript" src="../scripts/core.js" charset="utf-8"></script>
+       <script type="text/javascript" src="../scripts/search.js" charset="utf-8"></script>
+
+       <title>The (Circle) Ambient Analog Watch Sample Overview</title>
+</head>
+
+<body class="no-toc" onload="prettyPrint()" style="overflow: auto;">
+
+<div id="toc-navigation">
+</div>
+
+<div id="container"><div id="contents"><div class="content">
+       <div id="profile">
+               <p><img alt="Wearable native" src="../images/wearable_s_n.png"/></p>
+       </div>
+
+  <h1>(Circle) Ambient Analog Watch Sample Overview</h1>
+
+<p>The (Circle) Ambient Analog Watch sample application demonstrates how to implement a simple watch application with ambient mode support.</p>
+
+<p>The following figure illustrates two screens of the (Circle) Ambient Analog Watch sample application: the normal mode watch view, the ambient mode watch view and the cipher disc selection view.</p>
+
+<p class="figure">Figure 1: (Circle) Ambient Analog Watch views</p>
+  <p align="center">
+         <img alt="(Circle) Ambient Analog Watch views" src="../images/circleambientanalogwatch_wn0.png" height="240" width="240"/>
+         <img alt="(Circle) Ambient Analog Watch views" src="../images/circleambientanalogwatch_wn6.png" height="240" width="240"/>
+         <img alt="(Circle) Ambient Analog Watch views" src="../images/circleambientanalogwatch_wn1.png" height="240" width="240"/>
+  </p>
+
+<p>The current time is displayed as follows:</p>
+ <ul>
+  <li>red dot indicates seconds,</li>
+  <li>small blue dot indicates hours,</li>
+  <li>large blue dot indicates minutes.</li>
+ </ul>
+<p>Above the current date there are indicators for battery level and WiFi RSSI.</p>
+<p>To enter cipher disc selection view, you have to click the gear wheel button. From there you can select which cipher disc style you want to use.</p>
+
+<p class="figure">Figure 2: (Circle) Ambient Analog Watch widgets structure</p>
+<p align="center">
+ <img alt="(Circle) Sensors widgets structure" src="../images/circleambientanalogwatch_wn2.png" height="263" width="747"/>
+</p>
+<h2>Prerequisites</h2>
+<p>To ensure proper application execution, the
+<span style="font-family: Courier New,Courier,monospace">http://tizen.org/privilege/network.get</span> privilege must be set.</p>
+
+<h2>Implementation</h2>
+
+<h3>Main module</h3>
+<p>The <span style="font-family: Courier New,Courier,monospace">main()</span> function of the sample application is show below. The application loop
+is started when the <span style="font-family: Courier New,Courier,monospace">watch_app_main()</span>
+function is invoked. An object of <span style="font-family: Courier New,Courier,monospace">watch_app_lifecycle_callback_s</span> type can be passed to it.
+Notice how it differs from <span style="font-family: Courier New,Courier,monospace">ui_app_lifecycle_callback_s</span> typed used in the standard application type.
+The <span style="font-family: Courier New,Courier,monospace">watch_app_lifecycle_callback_s</span> structure introduces three new callback pointers to:
+</p>
+<ul>
+ <li><span style="font-family: Courier New,Courier,monospace">watch_app_time_tick_cb</span> - called every second when the application is in normal mode, giving the application a chance to refresh the time indicator,</li>
+ <li><span style="font-family: Courier New,Courier,monospace">watch_app_ambient_tick_cb</span> - called every minute when the application is in ambient, giving the application a chance to refresh the time indicator,</li>
+ <li><span style="font-family: Courier New,Courier,monospace">watch_app_ambient_changed_cb</span> - called whenever the application enters normal or ambient mode.</li>
+</ul>
+
+<pre class="prettyprint">
+int main(int argc, char *argv[])
+{
+&nbsp;&nbsp;int ret = 0;
+
+&nbsp;&nbsp;watch_app_lifecycle_callback_s event_callback = {0,};
+
+&nbsp;&nbsp;event_callback.create = app_create;
+&nbsp;&nbsp;event_callback.resume = app_resume;
+&nbsp;&nbsp;event_callback.pause = app_pause;
+&nbsp;&nbsp;event_callback.terminate = app_terminate;
+&nbsp;&nbsp;event_callback.time_tick = app_time_tick;
+&nbsp;&nbsp;event_callback.ambient_tick = app_time_tick;
+&nbsp;&nbsp;event_callback.ambient_changed = app_ambient_changed;
+
+&nbsp;&nbsp;ret = watch_app_main(argc, argv, &event_callback, NULL);
+       // Error handling ...
+
+&nbsp;&nbsp;return ret;
+}
+</pre>
+
+<pre class="prettyprint">
+static void app_time_tick(watch_time_h watch_time, void *data)
+{
+       // Variable definitions and error handling ...
+&nbsp;&nbsp;__get_date_from_watch_time(watch_time,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&year, &month, &day, &day_of_week,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&hours, &minutes, &seconds);
+
+&nbsp;&nbsp;controller_tick(hours, minutes, seconds, year, month, day, day_of_week);
+}
+</pre>
+
+<pre class="prettyprint">
+static void app_ambient_changed(bool ambient_mode, void *data)
+{
+&nbsp;&nbsp;controller_set_ambient_mode(ambient_mode);
+}
+</pre>
+
+<pre class="prettyprint">
+static void __get_date_from_watch_time(const watch_time_h watch_time,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int *year, int *month, int *day, int *day_of_week,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int *hours, int *minutes, int *seconds)
+{
+&nbsp;&nbsp;watch_time_get_hour24(watch_time, hours);
+&nbsp;&nbsp;watch_time_get_minute(watch_time, minutes);
+&nbsp;&nbsp;watch_time_get_second(watch_time, seconds);
+&nbsp;&nbsp;watch_time_get_year(watch_time, year);
+&nbsp;&nbsp;watch_time_get_month(watch_time, month);
+&nbsp;&nbsp;watch_time_get_day(watch_time, day);
+&nbsp;&nbsp;watch_time_get_day_of_week(watch_time, day_of_week);
+}
+</pre>
+
+<h3>Controller module</h3>
+<p>Three important functions of this module are presented below. The <span style="font-family: Courier New,Courier,monospace">controller_start_application()</span>
+is called at the application's startup. It sets up the view and adds the
+<span style="font-family: Courier New,Courier,monospace">__wifi_rssi_level_changed_cb()</span>
+callback to monitor WiFi signal strength's changes. It also sets the current time on the watch view.</p>
+
+<pre class="prettyprint">
+bool controller_start_application(int width, int height,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int hour, int min, int sec,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int year, int month, int day, int week_day)
+{
+&nbsp;&nbsp;if (!view_create_gui(width, height))
+&nbsp;&nbsp;&nbsp;&nbsp;return false;
+
+&nbsp;&nbsp;if (wifi_monitor_init())
+&nbsp;&nbsp;&nbsp;&nbsp;wifi_monitor_start_measure(__wifi_rssi_level_changed_cb);
+
+&nbsp;&nbsp;view_set_time(hour, min, sec, year, month, day, week_day);
+
+&nbsp;&nbsp;return true;
+}
+</pre>
+
+<p>The <span style="font-family: Courier New,Courier,monospace">controller_set_ambient_mode()</span> function is called from
+<span style="font-family: Courier New,Courier,monospace">app_ambient_changed()</span>
+callback, defined in the main module. This way, the application can track whether it is in ambient or normal mode.
+It is recommended to stop any power consuming operations in the ambient mode. For example, you can change the display state to one that has most of its pixels dark.</p>
+
+<pre class="prettyprint">
+void controller_set_ambient_mode(bool ambient_mode)
+{
+&nbsp;&nbsp;cdata.ambient_mode = ambient_mode;
+&nbsp;&nbsp;view_set_ambient(cdata.ambient_mode);
+&nbsp;&nbsp;if (cdata.ambient_mode) {
+&nbsp;&nbsp;&nbsp;&nbsp;wifi_monitor_stop_measure();
+&nbsp;&nbsp;} else {
+&nbsp;&nbsp;&nbsp;&nbsp;wifi_monitor_start_measure(__wifi_rssi_level_changed_cb);
+&nbsp;&nbsp;}
+}
+</pre>
+<p>Aside from updating the time and date indicators, the <span style="font-family: Courier New,Courier,monospace">controller_tick()</span>
+function reads the battery level and sets up the battery display accordingly. It happens only in ambient mode.
+The <span style="font-family: Courier New,Courier,monospace">controller_tick()</span>
+is called with one second interval when the application is in normal mode
+and with one minute interval when it is in ambient mode.</p>
+
+<pre class="prettyprint">
+void controller_tick(int hour, int min, int sec,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int year, int month, int day, int week_day)
+{
+&nbsp;&nbsp;int batt_percent = 0;
+&nbsp;&nbsp;view_set_time(hour, min, sec, year, month, day, week_day);
+&nbsp;&nbsp;if (!cdata.ambient_mode) {
+&nbsp;&nbsp;&nbsp;&nbsp;device_battery_get_percent(&batt_percent);
+&nbsp;&nbsp;&nbsp;&nbsp;view_set_batt(batt_percent);
+&nbsp;&nbsp;}
+}
+</pre>
+
+<h3>Main view module</h3>
+
+<p>The <span style="font-family: Courier New,Courier,monospace">watch_app_get_elm_win()</span>
+function is used to obtain a special watch type window. This way the application can receive ambient/normal mode switch events properly.</p>
+<p>The next step is creating two circular indicators. In order to do it, first it is neccesary to create an elementary widget and associate it with
+the circular surface.</p>
+<p>The <span style="font-family: Courier New,Courier,monospace">elm_layout</span> widget has been chosen for this operation.
+Once the <span style="font-family: Courier New,Courier,monospace">indicators_layout</span> pointer is obtained, it is possible to
+call <span style="font-family: Courier New,Courier,monospace">eext_circle_surface_layout_add()</span> function and obtain a pointer
+(<span style="font-family: Courier New,Courier,monospace">indicators_layout_surface</span>) to a
+<span style="font-family: Courier New,Courier,monospace">Eext_Circle_Surface</span> object associated with this layout.</p>
+<p>These two pointers can now be used to create circle objects - time indicators. The pointers are passed to the
+<span style="font-family: Courier New,Courier,monospace">__create_time_indicator()</span>
+function and from there to the <span style="font-family: Courier New,Courier,monospace">circle_indicator_create()</span>
+function from circle indicator module.</p>
+<p>Up to this point in <span style="font-family: Courier New,Courier,monospace">view_create_gui()</span>
+function, this application would look like in Figure 3 (left).</p>
+<p>Next, the main layout is created. It consists, among others, of circular black background with two transparent rings as in Figure 3 (right).
+The main layout object is stacked above circular objects and the effect can be seen in Figure 1.</p>
+<p>Finally, the ambient digital clock layout is created. It is hidden until the application enters the ambient mode. It is shown in Figure 1 (middle).</p>
+
+<p class="figure">Figure 3: Two circle indicators and the background</p>
+<p align="center">
+ <img alt="Two circle indicators and the background" src="../images/circleambientanalogwatch_wn4.png" height="240" width="240"/>
+ <img alt="Two circle indicators and the background" src="../images/circleambientanalogwatch_wn5.png" height="240" width="240"/>
+</p>
+
+
+<pre class="prettyprint">
+bool view_create_gui(int width, int height)
+{
+&nbsp;&nbsp;Evas_Object *indicators_layout = NULL;
+&nbsp;&nbsp;Eext_Circle_Surface *indicators_layout_surface = NULL;
+
+&nbsp;&nbsp;watch_app_get_elm_win(&vd.win);
+
+       // Error handling ...
+
+&nbsp;&nbsp;evas_object_resize(vd.win, width, height);
+
+&nbsp;&nbsp;indicators_layout = elm_layout_add(vd.win);
+
+       // Error handling ...
+
+&nbsp;&nbsp;evas_object_resize(indicators_layout, width, height);
+&nbsp;&nbsp;evas_object_show(indicators_layout);
+&nbsp;&nbsp;indicators_layout_surface = eext_circle_surface_layout_add(indicators_layout);
+
+       // Error handling ...
+
+&nbsp;&nbsp;__create_time_indicator(&vd.hours_minutes_indicator, indicators_layout_surface, indicators_layout,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(HOURS_INDICATOR_REL_SIZE * (float)width/2.0),
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TIME_INDICATOR_THICKNESS,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TIME_INDICATOR_R_COLOR,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TIME_INDICATOR_G_COLOR,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TIME_INDICATOR_B_COLOR);
+
+&nbsp;&nbsp;__create_time_indicator(&vd.seconds_indicator, indicators_layout_surface, indicators_layout,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;(MINUTES_INDICATOR_REL_SIZE * (float)width/2.0),
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TIME_INDICATOR_THICKNESS,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TIME_INDICATOR_R_COLOR,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TIME_INDICATOR_G_COLOR,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TIME_INDICATOR_B_COLOR);
+
+&nbsp;&nbsp;vd.main_layout = __create_layout(MAIN_LAYOUT_EDJE_FILE, MAIN_GRP, width, height);
+&nbsp;&nbsp;evas_object_show(vd.main_layout);
+
+       // Other UI elements creation code ...
+
+&nbsp;&nbsp;vd.ambient_clock = ambient_clock_create(vd.main_layout);
+&nbsp;&nbsp;elm_layout_content_set(vd.main_layout, AMBIENT_SWALLOW_PART, vd.ambient_clock);
+
+       // Common code ...
+}
+</pre>
+
+<pre class="prettyprint">
+static const Circle_Indicator *__create_time_indicator(const Circle_Indicator **indicator,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Eext_Circle_Surface *indicators_layout_surface,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Evas_Object *indicators_layout,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int radius, int thickness, int r, int g, int b)
+{
+&nbsp;&nbsp;*indicator = circle_indicator_create(indicators_layout, indicators_layout_surface);
+
+&nbsp;&nbsp;if (!*indicator)
+&nbsp;&nbsp;&nbsp;&nbsp;return NULL;
+
+&nbsp;&nbsp;circle_indicator_set_radius(*indicator, radius);
+&nbsp;&nbsp;circle_indicator_set_thickness(*indicator, thickness);
+&nbsp;&nbsp;circle_indicator_set_color(*indicator, r, g, b,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TIME_INDICATOR_R_COLOR_2,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TIME_INDICATOR_G_COLOR_2,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;TIME_INDICATOR_B_COLOR_2);
+&nbsp;&nbsp;circle_indicator_show(*indicator, true);
+
+&nbsp;&nbsp;return *indicator;
+}
+</pre>
+
+<p>Each time a time tick occurs, the controller module calls <span style="font-family: Courier New,Courier,monospace">view_set_time()</span>
+function. One of its roles is to set the proper positions of dot indicators. This is calculated when a message is sent to the main layout object
+using <span style="font-family: Courier New,Courier,monospace">edje_object_message_send()</span> function.
+</p>
+
+<pre class="prettyprint">
+void view_set_time(int hours, int minutes, int seconds,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;int year, int month, int day, int week_day)
+{
+       // Other variable definitions ...
+
+       Edje_Message_Int_Set *msg = NULL;
+
+&nbsp;&nbsp;if (!vd.ambient) {
+
+       // Calculations ...
+
+&nbsp;&nbsp;&nbsp;&nbsp;circle_indicator_set(vd.seconds_indicator, 0.0, ((float)seconds) / 60.0);
+&nbsp;&nbsp;&nbsp;&nbsp;circle_indicator_set(vd.hours_minutes_indicator,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;((float)hours_12) / 12.0 + ((float)minutes) / 60.0 / 12.0,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;((float)minutes) / 60.0);
+
+       // Date string setting ...
+
+&nbsp;&nbsp;&nbsp;&nbsp;msg = alloca(sizeof(Edje_Message_Int_Set) + 2 * sizeof(int));
+
+       // Error handling ...
+
+&nbsp;&nbsp;&nbsp;&nbsp;msg->count = 3;
+&nbsp;&nbsp;&nbsp;&nbsp;msg->val[0] = hours_12;
+&nbsp;&nbsp;&nbsp;&nbsp;msg->val[1] = minutes;
+&nbsp;&nbsp;&nbsp;&nbsp;msg->val[2] = seconds;
+
+&nbsp;&nbsp;&nbsp;&nbsp;edje_object_message_send(elm_layout_edje_get(vd.main_layout), EDJE_MESSAGE_INT_SET, SET_TIME_MSG_ID, msg);
+&nbsp;&nbsp;}
+
+&nbsp;&nbsp;ambient_clock_set_time(vd.ambient_clock, hours, minutes);
+}
+</pre>
+
+<p>Once the message is received, it is processed by edje layout object's script function:</p>
+
+<pre class="prettyprint">
+script
+{
+&nbsp;&nbsp;public bool:ambient_mode = false;
+
+&nbsp;&nbsp;public message(Msg_Type:type, id, ...)
+&nbsp;&nbsp;{
+&nbsp;&nbsp;&nbsp;&nbsp;static Float:h = 0.0;
+&nbsp;&nbsp;&nbsp;&nbsp;static Float:m = 0.0;
+&nbsp;&nbsp;&nbsp;&nbsp;static Float:s = 0.0;
+&nbsp;&nbsp;&nbsp;&nbsp;static Float:rx = 0.0;
+&nbsp;&nbsp;&nbsp;&nbsp;static Float:ry = 0.0;
+
+&nbsp;&nbsp;&nbsp;&nbsp;if (type == MSG_INT_SET && id == SET_TIME_MSG_ID)
+&nbsp;&nbsp;&nbsp;&nbsp;{
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;h = getarg(2);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;m = getarg(3);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;s = getarg(4);
+
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rx = sin( 360.0 * (h / 12.0 + m / 60.0 / 12.0), DEGREES);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ry = cos( 360.0 * (h / 12.0 + m / 60.0 / 12.0), DEGREES);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;custom_state(PART:HOURS_DOT_PART, "default", 0.0);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;set_state_val(PART:HOURS_DOT_PART, STATE_REL1,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0.5 + HOURS_MINS_DOT_RADIUS*rx - HOURS_DOT_SIZE / 2.0,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0.5 - HOURS_MINS_DOT_RADIUS*ry - HOURS_DOT_SIZE / 2.0);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;set_state_val(PART:HOURS_DOT_PART, STATE_REL2,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0.5 + HOURS_MINS_DOT_RADIUS*rx + HOURS_DOT_SIZE / 2.0,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0.5 - HOURS_MINS_DOT_RADIUS*ry + HOURS_DOT_SIZE / 2.0);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;set_state(PART:HOURS_DOT_PART, "custom", 0.0);
+
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rx = sin( 360.0 * m / 60.0, DEGREES);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ry = cos( 360.0 * m / 60.0, DEGREES);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;custom_state(PART:MINUTES_DOT_PART, "default", 0.0);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;set_state_val(PART:MINUTES_DOT_PART, STATE_REL1,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0.5 + HOURS_MINS_DOT_RADIUS*rx - MINUTES_DOT_SIZE / 2.0,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0.5 - HOURS_MINS_DOT_RADIUS*ry - MINUTES_DOT_SIZE / 2.0);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;set_state_val(PART:MINUTES_DOT_PART, STATE_REL2,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0.5 + HOURS_MINS_DOT_RADIUS*rx + MINUTES_DOT_SIZE / 2.0,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0.5 - HOURS_MINS_DOT_RADIUS*ry + MINUTES_DOT_SIZE / 2.0);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;set_state(PART:MINUTES_DOT_PART, "custom", 0.0);
+
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;rx = sin( 360.0 * s / 60.0, DEGREES);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;ry = cos( 360.0 * s / 60.0, DEGREES);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;custom_state(PART:SECONDS_DOT_PART, "default", 0.0);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;set_state_val(PART:SECONDS_DOT_PART, STATE_REL1,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0.5 + SECONDS_DOT_RADIUS*rx - SECONDS_DOT_SIZE / 2.0,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0.5 - SECONDS_DOT_RADIUS*ry - SECONDS_DOT_SIZE / 2.0);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;set_state_val(PART:SECONDS_DOT_PART, STATE_REL2,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0.5 + SECONDS_DOT_RADIUS*rx + SECONDS_DOT_SIZE / 2.0,
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;0.5 - SECONDS_DOT_RADIUS*ry + SECONDS_DOT_SIZE / 2.0);
+&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;set_state(PART:SECONDS_DOT_PART, "custom", 0.0);
+&nbsp;&nbsp;&nbsp;&nbsp;}
+&nbsp;&nbsp;}
+}
+</pre>
+
+<h3>Circle indicator view module</h3>
+
+<p>The circle indicator is a complex object, as shown in Figure 2. It holds pointers to two circle objects. One circle object is used to display an arc
+to indicate current time value progress. The second one shows the arc of progress yet to come. The creation code is shown below.</p>
+
+<pre class="prettyprint">
+const Circle_Indicator *circle_indicator_create(Evas_Object *parent, Eext_Circle_Surface *indicators_layout_surface)
+{
+&nbsp;&nbsp;Circle_Indicator *indicator = NULL;
+
+&nbsp;&nbsp;indicator = calloc(1, sizeof(Circle_Indicator));
+
+&nbsp;&nbsp;if (!indicator)
+&nbsp;&nbsp;&nbsp;&nbsp;return NULL;
+
+&nbsp;&nbsp;indicator->indicating_indicator = eext_circle_object_add(parent, indicators_layout_surface);
+&nbsp;&nbsp;eext_circle_object_angle_min_max_set(indicator->indicating_indicator, 0, 360);
+
+&nbsp;&nbsp;indicator->bg_indicator = eext_circle_object_add(parent, indicators_layout_surface);
+&nbsp;&nbsp;eext_circle_object_angle_min_max_set(indicator->bg_indicator, 0, 360);
+
+&nbsp;&nbsp;evas_object_data_set(indicator->bg_indicator, CI_DATA_KEY, indicator);
+&nbsp;&nbsp;evas_object_event_callback_add(indicator->bg_indicator, EVAS_CALLBACK_DEL, __evas_object_before_delete_cb, NULL);
+
+&nbsp;&nbsp;return indicator;
+}
+</pre>
+
+<script type="text/javascript" src="../scripts/jquery.zclip.min.js"></script>
+<script type="text/javascript" src="../scripts/showhide.js"></script>
+</div></div></div>
+
+<a class="top sms" href="#"><img src="../images/btn_top.gif" alt="Go to top" /></a>
+
+<div id="footer">
+<p class="footer">Except as noted, this content - excluding the Code Examples - is licensed under <a href="http://creativecommons.org/licenses/by/3.0/legalcode" target="_blank">Creative Commons Attribution 3.0</a> and all of the Code Examples contained herein are licensed under <a href="https://www.tizen.org/bsd-3-clause-license" target="_blank">BSD-3-Clause</a>.<br/>For details, see the <a href="https://www.tizen.org/content-license" target="_blank">Content License</a>.</p>
+</div>
+
+<script type="text/javascript">
+var _gaq = _gaq || [];
+_gaq.push(['_setAccount', 'UA-25976949-1']);
+_gaq.push(['_trackPageview']);
+(function() {
+var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
+ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
+var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
+})();
+</script>
+
+</body>
+</html>
index 3736242..3ea839e 100644 (file)
        <tr> 
      <td><a href="cairo_evasgl_sd_wn.htm">(Circle) Cairo EvasGL</a></td> 
      <td>Demonstrates how you can implement the Cairo GL backend with the Evas_GL surface.</td>
-    </tr>              
+    </tr>
+    <tr>
+     <td><a href="circleambientanalogwatch_wn.htm">(Circle) Ambient Analog Watch</a></td>
+     <td>Demonstrates how you can implement a simple watch application with ambient mode support.</td>
+    </tr>
     <tr>
      <td><a href="circleemail_sd_wn.htm">(Circle) Email</a></td> 
      <td>Demonstrates how you can implement a complex circular email view using EFL UI components and containers.</td>