チズンとは何で、何が食べられるかは、おそらくグーグルや他のビンビンに伝えることができるでしょう。 そして、できるだけ少ないネイティブコードを記述して、ネイティブアプリケーションを作成する方法を見ていきます。
それで、エジェについて知りましょう。 Edjeは、qt quickの類似物であるeflでインターフェイスとアクションを記述する方法ですが、以前に登場したもので、ライブラリの機能の一部を引き継ぐものではありません。
edjeファイル構造の例を見てみましょう。
- コレクション -ファイルごとに1つのルート要素。
- group-要素のグループ。このコンテキストでは、コレクション内にいくつかの要素が存在する場合があります。たとえば、フォームの個別のコンポーネントとして、またはウィジェットを配置するためのレイアウトとして使用できる通常のダイヤルおよび省エネプログラムです。
- スクリプト -胚でコードを書くためのブロック。 これは、Small言語に基づいた非常に単純な言語であり、その助けにより、オンザフライで何らかのアルゴリズムに従ってedje要素を変更できます(たとえば、マウスカーソルからボタンを走らせる)。
- image-使用された画像の説明ブロック。
- パーツ -何らかの方法でメインユニット その中に、後でプログラムウィンドウで使用できる部分が配置されます。
それでは、顔を作り始めましょう。 まず、画像ブロックで使用する画像を発表しました。
images { image: "aod_h.png" COMP; image: "aod_m1.png" COMP; image: "aod_m2.png" COMP; image: "aod_m3.png" COMP; image: "aod_m4.png" COMP; image: "aod_m5.png" COMP; }
次に、表示されるアイテムとそのデフォルトのステータスを説明し、AM / PMを示すテキストボックスを配置します。 何をどのように行うかは、以下で少し検討します。
parts { part{ name:"aod/h"; scale: 1; type: IMAGE; description{ state: "default"; max: 360 360; visible: 1; image.normal: "aod_h.png"; aspect: 1 1; align: 0.5 0.5; rel1.relative: 0.00 0.00; rel2.relative: 1.00 1.00; map.on: 1; map.rotation.z: 210.0; } } part { name:"aod/m1"; scale: 1; type: IMAGE; description { state: "default"; max: 360 360; visible: 1; image.normal: "aod_m1.png"; aspect: 1 1; align: 0.5 0.5; rel1.relative: 0.00 0.00; rel2.relative: 1.00 1.00; map.on: 1; map.rotation.z:0; } } part { name:"aod/m2"; scale: 1; type: IMAGE; description { state:"default"; max: 360 360; visible: 1; image.normal: "aod_m2.png"; aspect: 1 1; align: 0.5 0.5; rel1.relative: 0.00 0.00; rel2.relative: 1.00 1.00; map.on: 1; map.rotation.z:0; } } part { name:"aod/m3"; scale: 1; type: IMAGE; description { state:"default"; max: 360 360; visible: 1; image.normal: "aod_m3.png"; aspect: 1 1; align: 0.5 0.5; rel1.relative: 0.00 0.00; rel2.relative: 1.00 1.00; map.on: 1; map.rotation.z:0; } } part { name:"aod/m4"; scale: 1; type: IMAGE; description { state:"default"; max: 360 360; visible: 1; image.normal: "aod_m4.png"; aspect: 1 1; align: 0.5 0.5; rel1.relative: 0.00 0.00; rel2.relative: 1.00 1.00; map.on: 1; map.rotation.z:0; } } part { name:"aod/m5"; scale: 1; type: IMAGE; description { state:"default"; max: 360 360; visible: 1; image.normal: "aod_m5.png"; aspect: 1 1; align: 0.5 0.5; rel1.relative: 0.00 0.00; rel2.relative: 1.00 1.00; map.on: 1; map.rotation.z:0; } } part{ name:"aod/act"; scale: 1; type: RECT; description { state:"default"; color: 0 136 170 55; visible: 1; max: 360 360; align: 0.5 0.5; rel1.relative: 0.00 0.00; rel2.relative: 1.00 1.00; } } part { name:"ampm"; type: TEXT; scale: 1; effect: SOFT_OUTLINE; description { state:"default"; color: 255 255 255 255; color2: 0 136 170 100; max: 360 360; visible: 1; text { size: 35; font: "Sans"; text: "AM"; align: 0.5 0.5; min: 0 0; } align: 0.5 0.5; rel1.relative: 0.2505 0.3598; rel2.relative: 0.7505 0.6398; } } }
部品の詳細なドキュメント。
そして今、楽しい部分が始まります。次に、少なくともCコードを使用できる部分について説明します。
script { public minutes; public hour; public hideMinutes(val) { new i; new j; new pid; new buf[24]; j = val; for(i = 5; i > j; i--) { snprintf(buf, 23, "aod/m%d", i); pid = get_part_id(buf); custom_state(pid, "default", 0.0); set_state_val(pid, STATE_VISIBLE, 0); set_state(pid, "custom", 0.0); } } public showMinutes(val) { new i; new j; new Float:angle; new pid; new x; new buf[24]; j = val; x = (val / 5); angle = x * 30.0; for(i = 0; i < j; i++) { snprintf(buf, 23, "aod/m%d", i); pid = get_part_id(buf); custom_state(pid, "default", 0.0); set_state_val(pid, STATE_VISIBLE, 1); set_state_val(pid, STATE_MAP_ON, 1); set_state_val(pid, STATE_MAP_ROT_Z, angle); set_state(pid, "custom", 0.0); } } public setHour(val) { new Float:h; h = (val > 12 ? val - 12 : val)*30.0; if(val > 12) { set_text(PART:"ampm", "PM"); } else { set_text(PART:"ampm", "AM"); } custom_state(PART:"aod/h", "default", 0.0); set_state_val(PART:"aod/h", STATE_MAP_ON, 1); set_state_val(PART:"aod/h", STATE_MAP_ROT_Z, h); set_state(PART:"aod/h", "custom", 0.0); } public setMinutes(val) { new y; new x; if((val == 0)||(val == 60)) { hideMinutes(0); return; } x = val - ((val / 5)*5); y = val%5; showMinutes(val); if(y != 0) { hideMinutes(x); } } public setTime() { new y; new m; new d; new yd; new wd; new hr; new mn; new Float:sec; date(y, m, d, yd, wd, hr, mn, sec); setHour(hr); setMinutes(mn); } public message(Msg_Type:type, id, ...) { if(id == 0) { setTime(); } } }
ここと今、私たちは胚の最も重要な要素のみを考慮し、いくつかの点をスキップしますが、質問を引き起こすか、今は考慮されないものは今分析します。
set_text(PART:"ampm", "PM");
-テキストで要素の値を設定します。
custom_state(PART:"aod/h", "default", 0.0);
-デフォルトの状態に基づいて新しい要素の状態を作成します。
set_state_val(PART:"aod/h", STATE_MAP_ON, 1);
set_state_val(PART:"aod/h", STATE_MAP_ROT_Z, h);
-要素をh度回転します。
set_state(PART:"aod/h", "custom", 0.0);
-デフォルトの状態から新しい状態に移行します。移行期間は0.0秒です。
パーツには、part_idからもアクセスできます。
new buf[24];
snprintf(buf, 23, "aod/m%d", i);
-私はここで何を言うべきかさえ知りません
pid = get_part_id(buf);
-パーツの名前でpart_idを取得します。
custom_state(pid, "default", 0.0);
public message(Msg_Type:type, id, ...)
-ネイティブコードから信号を受信する関数。
胚の構文は通常のCに非常に似ています。もちろん、いくつかの違いがあります。
ローカル整数要素の新しい宣言
new <var>;
-変数
new <var>[<size>];
-8つの要素の配列
浮動小数点数はより扱いにくいと宣言されています:
new Float:<var name>;
関数とグローバル変数は、publicキーワードを使用して宣言されます。
public message()
-Cの場合のように、関数は結果を返すことができるか、 return
で中断されます。
public <varName>
は整数変数で、ローカル変数の場合と本質的に同じです。newの代わりにpublicのみが使用され、組み込み関数set_int()、get_int()、set_float()などが=の代わりに値を設定するために使用されます
これについては、Cの部分に進みます。ここでは、すべてが非常に単純で、ウォッチフェイスプロジェクトを作成します。 Tizen Studioメニューで利用可能な例では、いくつかの機能を変更しています。
ダウンロードしたファイルへのポインタを常に取得しないように、appdataを構造化する新しいedjeフィールドを追加します。
typedef struct appdata { Evas_Object *win; Evas_Object *conform; Evas_Object *layout; Evas_Object *edje; } appdata_s;
ダウンロードは以下の2つの関数で説明します。すべてが非常に単純です。elm_layout_file_setには、edjeファイルのベースとなるレイアウト、ファイルへのパス、および要素グループの名前を渡します
void data_get_resource_path(const char *file_in, char *file_path_out, int file_path_max) { char *res_path = app_get_resource_path(); if (res_path) { snprintf(file_path_out, file_path_max, "%s%s", res_path, file_in); free(res_path); } } void setup_layout(Evas_Object *layout) { char edje_path[PATH_MAX]; data_get_resource_path(EDJE_FILE_PATH, edje_path, sizeof(edje_path)-1); elm_layout_file_set(layout, edje_path, "layout/watchface"); evas_object_size_hint_weight_set(layout, 360, 360); evas_object_show(layout); }
ここでは、setup_layout以外のすべてのUIの作成は変更されませんでした。
static void create_base_gui(appdata_s *ad, int width, int height) { int ret; watch_time_h watch_time = NULL; /* Window */ ret = watch_app_get_elm_win(&ad->win); if (ret != APP_ERROR_NONE) { dlog_print(DLOG_ERROR, LOG_TAG, "failed to get window. err = %d", ret); return; } evas_object_resize(ad->win, width, height); /* Conformant */ ad->conform = elm_conformant_add(ad->win); evas_object_size_hint_weight_set(ad->conform, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND); elm_win_resize_object_add(ad->win, ad->conform); evas_object_show(ad->conform); /*Layout*/ ad->layout = elm_layout_add(ad->conform); elm_object_content_set(ad->conform, ad->layout); setup_layout(ad->layout); ad->edje = elm_layout_edje_get(ad->layout); ret = watch_time_get_current_time(&watch_time); if (ret != APP_ERROR_NONE) dlog_print(DLOG_ERROR, LOG_TAG, "failed to get current time. err = %d", ret); update_watch(ad, watch_time, 0); watch_time_delete(watch_time); /* Show window after base gui is set up */ evas_object_show(ad->win); }
最後の仕上げは、関数を追加することです。
static void update_watch(appdata_s *ad, watch_time_h watch_time, int ambient) { Edje_Message_Int *msg; if (watch_time == NULL) return; msg = alloca(sizeof(Edje_Message_Int)); msg->val = 1; dlog_print(DLOG_VERBOSE, __PRETTY_FUNCTION__, "EDJE NOT NULL"); edje_object_message_send(ad->edje, EDJE_MESSAGE_INT_SET, 0, msg); }
これらをすべて収集し、時計またはシミュレータで実行することは残っています。
→ 例付きのリポジトリ
→ Edjeドキュメント