Tizen

Project 1 : Hello World

학습 목표 : 프로젝트 생성, 실행, main함수,main 윈도우,comformant ,label

프로젝트 생성법

File -> New -> Project...

Template를 선택하고, Mobile-2.3 하위의 UI Application 을 선택하도록 한다.

helloworld로 프로젝트를 생성하도록 한다.

이 때, EDC를 사용한 버전으로도 만들수 있고 사용하지 않은 버전으로도 만들 수 있는데, 나중에도 EDC 추가가 가능하기 때문에, EDC를 사용하지 않은 버전으로 만들어보도록 한다.

helloworld 프로젝트가 위와 같이 생성되면 helloworld.c의 main 함수가 위와같이 만들어져있는 것이 보일 것이다.

Tizen 프로젝트를 만들 때, 위와 같이 Template을 통해 만들면 기본 뼈대 코드가 자동으로 작성되어지기 때문에, 매우 편하다.

기본 생성된 코드를 Project->Build All을 통해 빌드하고, 실행해보도록 한다.

앗.. 근데 와 같이 에러가 발생한다면, 디바이스또는 가상 디바이스를 설정하지 않았기 때문이다.

Connection Exploerer에서 Emulator Manager를 통해 가상 머신을 만들도록 하자.

mobile-2.3 탭을 선택하도록 하고 Resoultion을 개발하고자하는 해상도로 설정하고 Confirm을 눌러 만들어보자

아래와 같이 만들어졌다면 만들어진 기기의 재생 버튼을 눌러보자.

조금 시간이 흐른 후, 아래와 같이 에뮬레이터가 켜진 것을 확인할 수 있다.

에뮬레이터가 대기모드로 들어가면 화면이 “still running”이라는 화면으로 바뀌게 되는데 이 때 Home 버튼을 클릭하여 에뮬레이터 기기를 켜줄 수 있다.

이제 에뮬레이터 설정이 끝났으므로,
helloworld로 가서, 재빌드하고, 실행해보도록 하자.

중간에 security 팝업이 뜨면, 개발자 sign 을 생성하지 않은 것으로 add를 눌러 생성하도록 한다.

이런 개발자 서명은, 개발할 때는 불편하지만, 나중에 스토어에 업로드 하였을 때, 여러가지로 유용하게 쓰일 수 있다.

혹시 Target(핸드폰, 테블릿 또는 TV)에서 개발하고 있다면, 에뮬레이터 빌드 대신 Target 빌드가 되도록 설정해야한다.

프로젝트의 Properties를 띄워서 C/C++ Build의 Tizen Settings 에 들어가면, Platform 탭에 Architecture를 ARM으로 바꿔주도록 하자.

ToolChain은 LLVM이 GCC보다 Optimize가 잘 되므로 큰 문제가 없다면 그대로 쓰도록 하자.

이제 hellotizen Template 코드를 helloworld로 바꾸어보자

create_base_gui

함수 안에를 보면

elm_object_text_set(ad->label, "Hello EFL");

와 같은 부분을 볼 수 있다.

label에 text를 설정하는 함수로서, “Hello EFL”이라고 써진 것이 보일 것이다.

이 것을 “Hello world”로 바꾸고 실행해보도록 하자.

자, 이제 “Hello world” 프로젝트를 완성하였다.

이제 Hello world의 코드를 살펴보도록 하자.

int
main(int argc, char *argv[])
{

프로세스가 생성되고 나서 main 함수로 들어오게 된다. 이 부분은 c언어의 기초중의 기초.

appdata_s ad = {0,};

와 같이 appdata 구조체 변수를 만들고 있는데, 이 부분은 편하다면 전역으로 빼서 사용해도 상관 없다.
주로 app의 주요 데이터 구조를 담는 용도로 사용한다고 보면 된다.
당연히 굳이 appdata_s 를 사용하기 싫다면 쓰지 않아도 된다.
이렇게 appdata_s를 만들어서 함수에서 들고다니는 것은 전역변수를 지양한다는데에도 의미가 있을 수 있고, 멀티쓰레드로 작성될 때 각자의 context를 들고다닐 수 있어 좋을 것으로 보인다.

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;

위코드는 라이프 사이클 코드이다. app_create, app_terminate 는 각각 앱의 실행과 종료 때에 불리게 된다. app_create때에, 초기 윈도우를 만들고 Main 화면을 띄우는 코드가 들어가면 적당하겠다. app_terminate는 프로그램 종료되기 전에 호출되는데, 자원의 정리 또는, app로직의 마무리 코드가 들어가면 적당하겠다. app_pause, app_resume 은 각각 background(배꼽키(Home key)를 눌러서)로 숨었을 때와 foreground로 다시 나타났을 때 불리게 된다. app_pause에서는 사용자가 더이상 화면의 UI를 보고있지 않게 되므로, 자원과 동작을 최소화하여, 배터리 소모를 줄이도록 할 수 도 있다. app_resume에서는 다시 떴을 때, 화면을 갱신하거나 app_pause로 중단한 job을 처리할 수 있도록 할 수 있다. app_control은 tizen의 IPC 방법중 하나로, 특히 어떤 앱이나 서비스의 도움이 필요할 때에 사용하거나 사용되어질 수 있다. 예를 들면, 앱 시작시에 네트워크 wifi picker를 띄우고 싶다면 wifi picker app을 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);

부분은, 기기가 배터리가 간당간당할때와, 기기의 화면이 세로또는 가로가 바뀌엇을때와, 기기의 기본 언어 설정이 바뀌었을때와 같은 이벤트를 받아 처리하기 위함이다.
여기서 화면의 방향 전환에 따른 이벤트 부분은 많이 써야할 것이다. 만약, 세로 또는 가로로만 UI가 제공된다면 이마저도 필요없다.
언어 바뀜에 대한 이벤트는, 다국어를 지원하는 앱에서는 필수적이다.

ui_app_main(argc, argv, &event_callback, &ad);

Event-Driven 프로그램의 main함수로서, 여기서 loop를 돌며, 시스템 이벤트 또는 사용자 이벤트를 처리한다.
예를 들면, 사용자가 화면을 터치하면 이벤트가 발생되는데 그 이벤트가 왔는지 확인하고, 왔다면 해당 이벤트 핸들러를 불러주는 while문으로된 loop이다.
Event-Driven 프로그래밍을 하지 않고자 한다면, 이 루프를 부르지 않기 바란다.

create_base_gui

함수는 프로그램 시작시 불려지게 되는데, 이때에 UI를 그리면 적당하다. UI를 그리려면, 도화지 즉 Window한개는 필요하다.

ad->win = elm_win_util_standard_add(PACKAGE, PACKAGE);
elm_win_autodel_set(ad->win, EINA_TRUE);

와 같이 윈도우를 생성하고 프로그램 종료 이벤트와 같은 상황이 발생했을 때, 자동으로 윈도우 자원을 삭제및 해제하여 화면에서 정상 삭제될 수 있도록 셋팅하도록 한다.

/* Conformant */
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);

와 같이 conformant를 윈도우 위에 붙이도록 한다. conformanat는 UI프로그래밍시, 영역별로 쉽게 프로그래밍 할 수 있도록 미리 만들어놓은 레이아웃이다. 물론, 이것 없이도 프로그래밍이 당연히 가능하다. conformant는 모델마다 다를 수 있는데(예를 들면 indicator가 없는 모델 TV?), 스마트폰 conformant 레이아웃은 아래와 같으며 conform.edc파일로 기술되어있다.

정도는 가지고 있다.
Hello world는 content쪽에 배치되면 되겟다.

/* Label*/
ad->label = elm_label_add(ad->conform);
elm_object_text_set(ad->label, "Hello world");
evas_object_size_hint_weight_set(ad->label, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
elm_object_content_set(ad->conform, ad->label);
evas_object_show(ad->label);

와 같이 Hello world text를 가진 레이블을 conform의 content영역에 붙이도록 하자.

elm_object_content_set(ad->conform, ad->label);

은 아래 의 API 콜의 결과와 같다. 일종의 편의적인 API인 셈이다.

elm_object_part_content_set(ad->conform, "elm.swallow.content", ad->label);

indicator 영역에도 label을 달고싶다면

ad->label = elm_label_add(ad->conform);
elm_object_text_set(ad->label, "<color=#FFFFFF>Hello indicator world </color>");
evas_object_size_hint_weight_set(ad->label, EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
elm_object_part_content_set(ad->conform, "elm.swallow.indicator", ad->label);
evas_object_show(ad->label);

코드를 추가 해보자.
indicator_bg 의 색깔에 따라 글자가 안보일 수 있으므로 color의 RGB HEX값(여기서는 whilte인 FFFFFF)은 글자가 보이는 색으로 셋팅해보도록 한다.

여기서 추가로 배울 수 있는 것은 Label안에 셋팅되는 텍스트가 html 의 기본적인 tag들을 지원한다는 것이다. <align>, </br>, <font>, <color> 등 ...
이 부분은 Tizen의 우수한 기능이라고 생각한다. label에 들어가는 텍스트를 다음과 같이 넣어보자

"Hello world</br>oh my god</br><font_size=55><align=center><color=#FF0000><b>look!!!</b></color></align></font_size>"

결과는 다음과 같다.