Software Development/Tizen

[TIZEN]3. 타이젠 Basic UI Application 코드 설명

huiyu 2015. 12. 19. 18:01

이전 페이지에서 Basic UI Application을 통해 Native 프로젝트를 생성해 보았습니다.

2. 타이젠 네이티브 프로젝트 생성/에뮬레이터 생성

이제 생성된 프로젝트에서 각 코드를 살펴보도록 하겠습니다.

1. Project Explorer 

 -  먼저 생성된 프로젝트를 보시면, 좌측 Project Explorer에 기본적으로 생성되는 폴더와 파일을 볼 수 있습니다.
   기본적으로 아래 정도를 알고 있으면 됩니다.
    - inc : Header Files(.h)
    - res : Resource Files
    - src : C Files(.c)

 

   -tizen-manifest.xml
    : 타이젠에서 각종 정보를 기술한 어플리케이션 명세서, 모든 어플리케이션은 루트 디렉토리에 manifest를 갖고 있어야 합니다.
      어플리케이션에 대한 필수 정보를 플랫폼에 알려주는 역할을 합니다. 기본적으로 아래와 같은 사항을 설정할 수 있습니다.

 

 

2. EFL Native App 기본 코드 설명

 -  생성된 프로젝트의 src>[프로젝트명].c 파일이 기본적으로 생성된 것을 볼 수 있습니다.
    파일을 보시면 자동으로 필요한 코드가 생성되어 있습니다.


    프로그램은 가장 먼저 코드의 최하단에 위치한 main()함수를 호출하며 기본 설정을 진행합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
int
main(int argc, char *argv[])
{
    appdata_s ad = {0,};
    int ret = 0;
 
    ui_app_lifecycle_callback_s event_callback = {0,};
    app_event_handler_h handlers[5= {NULL, };
 
    event_callback.create = app_create;
    event_callback.terminate = app_terminate;
    event_callback.pause = app_pause;
    event_callback.resume = app_resume;
    event_callback.app_control = app_control;
 
    ui_app_add_event_handler(&handlers[APP_EVENT_LOW_BATTERY], APP_EVENT_LOW_BATTERY, ui_app_low_battery, &ad);
    ui_app_add_event_handler(&handlers[APP_EVENT_LOW_MEMORY], APP_EVENT_LOW_MEMORY, ui_app_low_memory, &ad);
    ui_app_add_event_handler(&handlers[APP_EVENT_DEVICE_ORIENTATION_CHANGED], APP_EVENT_DEVICE_ORIENTATION_CHANGED, ui_app_orient_changed, &ad);
    ui_app_add_event_handler(&handlers[APP_EVENT_LANGUAGE_CHANGED], APP_EVENT_LANGUAGE_CHANGED, ui_app_lang_changed, &ad);
    ui_app_add_event_handler(&handlers[APP_EVENT_REGION_FORMAT_CHANGED], APP_EVENT_REGION_FORMAT_CHANGED, ui_app_region_changed, &ad);
 
    ret = ui_app_main(argc, argv, &event_callback, &ad);
    if (ret != APP_ERROR_NONE) {
        dlog_print(DLOG_ERROR, LOG_TAG, "app_main() is failed. err = %d", ret);
    }
 
    return ret;
}
 
cs

 

 (1) appdata_s 생성 및 초기화

- 먼저 appdata_s ad = {0,};을 통해 앱 실행을 위한 기본 자료구조를 생성하고 초기화하고 있습니다. 
appdata_s는 EFL에서 아래와 같이 초기화되어 있으며, 기본적으로 필요한 객체에 대한 정보를 갖고 있습니다.

1
2
3
4
5
typedef struct appdata {
    Evas_Object *win;
    Evas_Object *conform;
    Evas_Object *label;
} appdata_s;
cs

 

GUI를 초기화 할 때 각 객체를 생성하며, 각 객체는 아래와 같은 역할을 하고 있습니다

   - win : 화면에 보여지는 모든 것을 그려주는 기본 윈도우 창, 기본적으로 가장 먼저 생성하여 윈도우에 그려줘야 합니다.
   - conform : conformant, 타이젠에서 필수적으로 gui구현시 사용하여야 한다고 합니다. 키패드가 보여지게 될때 화면에 나타나는 gui를 적당한 크기로 맞춰주는 역할을 합니다.
   - label: 화면에 text를 나타낼 때 사용

 

(2) lifecycle callback 함수 등록

  - 콜백함수란 일반적으로 특정한 사건이나 메시지가 발생했을 때 호출되도록 등록하고 사용하는 것을 말합니다.
  타이젠에선 기본적으로 코드 생성시 아래와 같이 Application의 lifecyle이 변할 때 (앱의 상태가 변할 때) 함수가 호출 될 수 있도록 자동으로 생성되어집니다.
  특정 상태로 변할 때 특정 기능을 실행시키고자 할 때 미리 만들어진 콜백함수를 이용하면 됩니다.

 

1
2
3
4
5
    event_callback.create = app_create;
    event_callback.terminate = app_terminate;
    event_callback.pause = app_pause;
    event_callback.resume = app_resume;
    event_callback.app_control = app_control;
cs

 

   - create : app이 생성되었을 때
   - terminate : app이 종료되었을 때
   - pause : app이 화면에서 가려졌을 때(화면이 꺼지거나 home키눌렀을 때, 또는 다른 앱이 화면을 가렸을 때 등)
   - resume : 안보였던 app이 다시 나타났을 때
   - app_control : 다른 app을 통해 불러졌을 때

 

(3) System callback 함수 등록

- 다음으로, 시스템 상에 변화가 생겼을 때 실행시킬 콜백함수를 등록합니다.

1
2
3
4
5
6
    ui_app_add_event_handler(&handlers[APP_EVENT_LOW_BATTERY], APP_EVENT_LOW_BATTERY, ui_app_low_battery, &ad);
    ui_app_add_event_handler(&handlers[APP_EVENT_LOW_MEMORY], APP_EVENT_LOW_MEMORY, ui_app_low_memory, &ad);
    ui_app_add_event_handler(&handlers[APP_EVENT_DEVICE_ORIENTATION_CHANGED], APP_EVENT_DEVICE_ORIENTATION_CHANGED, ui_app_orient_changed, &ad);
    ui_app_add_event_handler(&handlers[APP_EVENT_LANGUAGE_CHANGED], APP_EVENT_LANGUAGE_CHANGED, ui_app_lang_changed, &ad);
    ui_app_add_event_handler(&handlers[APP_EVENT_REGION_FORMAT_CHANGED], APP_EVENT_REGION_FORMAT_CHANGED, ui_app_region_changed, &ad);
 
cs

    - ui_app_low_battery : 배터리가 부족할 때
    - ui_app_low_memory: 메모리가 부족할 때
    - ui_app_orient_changed : 핸드폰 방향을 바꾸었을때(가로->세로, 세로->가로)
    - ui_app_lang_changed: : 언어를 바꾸엇을 때
    - ui_app_region_changed : 국가를 변경하였을 때

 

(4) GUI 설정

 - 먼저 작성된 콜백함수 코드를 통해, 앱이 생성될 때 app_create 함수를 실행된다는 것을 알수 있습니다.
 - app_create함수는 메인루프가 실행되기 전, App에 필요한 UI와 데이터를 설정합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
static bool
app_create(void *data)
{
    /* Hook to take necessary actions before main event loop starts
        Initialize UI resources and application's data
        If this function returns true, the main loop of application starts
        If this function returns false, the application is terminated */
    appdata_s *ad = data;
 
    create_base_gui(ad);
 
    return true;
}
 
 
cs

 

- 내부적으로 create_base_gui(ad)함수를 실행하여 메인화면을 초기화 하고 있습니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
 
static void
create_base_gui(appdata_s *ad)
{
    /* Window */
    /* Create and initialize elm_win.
       elm_win is mandatory to manipulate window. */
    ad->win = elm_win_util_standard_add(PACKAGE, PACKAGE);
    elm_win_autodel_set(ad->win, EINA_TRUE);
 
    if (elm_win_wm_rotation_supported_get(ad->win)) {
        int rots[4= { 090180270 };
        elm_win_wm_rotation_available_rotations_set(ad->win, (const int *)(&rots), 4);
    }
 
    evas_object_smart_callback_add(ad->win, "delete,request", win_delete_request_cb, NULL);
    eext_object_event_callback_add(ad->win, EEXT_CALLBACK_BACK, win_back_cb, ad);
 
    /* Conformant */
    /* Create and initialize elm_conformant.
       elm_conformant is mandatory for base gui to have proper size
       when indicator or virtual keypad is visible. */
    ad->conform = elm_conformant_add(ad->win);
    elm_win_indicator_mode_set(ad->win, ELM_WIN_INDICATOR_SHOW);
    elm_win_indicator_opacity_set(ad->win, ELM_WIN_INDICATOR_OPAQUE);
    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);
 
    /* Label */
    /* Create an actual view of the base gui.
       Modify this part to change the view. */
    ad->label = elm_label_add(ad->conform);
    elm_object_text_set(ad->label, "<align=center>Hello Tizen</align>");
    evas_object_size_hint_weight_set(ad->label, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
    elm_object_content_set(ad->conform, ad->label);
 
    /* Show window after base gui is set up */
    evas_object_show(ad->win);
}
 
cs

 

이제 위에서부터 생성된 오브젝트를 하나씩 살펴보도록 하겠습니다.

먼저 윈도우를 생성합니다. 아래 API는 일반적으로 app에 기본이 되는 윈도우를 생성하는 역할을 합니다.

첫번째 인자로 윈도우의 이름, 두번째 인자로 윈도우 타이틀을 전달합니다.

1
ad->win = elm_win_util_standard_add(PACKAGE, PACKAGE);
cs

 

다음으로 윈도우를 종료하였을 때, 윈도우 오브젝트를 자동으로 삭제해준다.

만약 EINA_FALSE값을 주게 되면 윈도우를 종료하여도 윈도우 오브젝트가 메모리에 남아있게 됩니다.

1
elm_win_autodel_set(ad->win, EINA_TRUE);
cs

 

elm_win_wm_rotation_available_rotatins_set()함수를 통해 사용가능한 회전 배열을 설정합니다.

생성된 코드에서는 0, 90, 180, 270도의 회전이 가능하게 설정하고 있습니다.

1
2
3
4
if (elm_win_wm_rotation_supported_get(ad->win)) {
        int rots[4= { 090180270 };
        elm_win_wm_rotation_available_rotations_set(ad->win, (const int *)(&rots), 4);
    }
cs

 

다음으로 윈도우 관련된 콜백함수를 등록하고 있습니다. 첫번째 콜백은 "delete,request" 이벤트가 발생할 때 발생할 콜백으로. 윈도우를 끝낼 때 호출됩니다.

1
evas_object_smart_callback_add(ad->win, "delete,request", win_delete_request_cb, NULL);
cs

win_delete_request_cb함수를 콜백함수로 등록하였으며, ui_app_exit()를 통해 앱을 종료시킵니다.

1
2
3
4
5
static void
win_delete_request_cb(void *data, Evas_Object *obj, void *event_info)
{
    ui_app_exit();
}
cs

 

두번째 콜백은 백버튼을 눌렀을 때의 콜백함수로 백버튼을 눌렀을 때 현재 윈도우가 안보이게 설정을 하고 있습니다.

1
eext_object_event_callback_add(ad->win, EEXT_CALLBACK_BACK, win_back_cb, ad);
cs
1
2
3
4
5
6
7
static void
win_back_cb(void *data, Evas_Object *obj, void *event_info)
{
    appdata_s *ad = data;
    /* Let window go to hide state. */
    elm_win_lower(ad->win);
}
cs

 

다음으로 conformnat 생성입니다. conformant는 윈도우 크기가 변경이 될 상황에서 자동으로 사이즈를 맞춰주는 역할을 한다고 합니다.

EFL에서는 기본적으로 오브젝트 생성시 elm_오브젝트명_add(부모) 함수를 통해 오브젝트를 생성하고 반환합니다.
아래 샘플코드에서는 ad-win을 부모객체로 전달을 하여, ad->conform을 생성하고 있습니다.

생성된 윈도우의 상단에 표시될 status bar를 elm_win_indicator_함수를 통해 설정하고 있습니다.

evas_object_size_hint_weight_set()함수의 EVAS_HINT_EXPAND를 설정하여 사용 가능한 최대로 확장할 수 있도록 설정합니다.

elm_win_resize_object_add() 함수를 통해 ad->conform을 ad->win에 추가한 후
evas_object_show()를 통해 실제 화면에 ad->conform이 보이게 설정을 합니다.

1
2
3
4
5
6
7
8
9
10
    /* Conformant */
    /* Create and initialize elm_conformant.
       elm_conformant is mandatory for base gui to have proper size
       when indicator or virtual keypad is visible. */
    ad->conform = elm_conformant_add(ad->win);
    elm_win_indicator_mode_set(ad->win, ELM_WIN_INDICATOR_SHOW);
    elm_win_indicator_opacity_set(ad->win, ELM_WIN_INDICATOR_OPAQUE);
    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);        
cs

 

마찬가지 방법으로 Label을 추가합니다.

elm_label_add()함수를 통해 label을 생성하고 elm_object_text_set을 통해 label의 텍스트 설정한 후 화면에 그려줍니다.

1
2
3
4
5
6
7
8
9
10
    /* Label */
    /* Create an actual view of the base gui.
       Modify this part to change the view. */
    ad->label = elm_label_add(ad->conform);
    elm_object_text_set(ad->label, "<align=center>Hello Tizen</align>");
    evas_object_size_hint_weight_set(ad->label, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
    elm_object_content_set(ad->conform, ad->label);
 
    /* Show window after base gui is set up */
    evas_object_show(ad->win);
cs

 

이러한 과정을 거쳐 아래의 화면을 생성하게 됩니다.

 

 

 

 

 

참고사이트

https://developer.tizen.org/ko/development/getting-started/native-application/creating-your-first-tizen-application

 

 

 

 

 

 

728x90