2014년 4월 17일 목요일

Tizen BasicApp sample

아래 내용은 Tizen 2.2 기반이라 상위 버전에서는 별 의미 없는 내용입니다.
--------------------------------------------------------------------------- : https://developer.tizen.org/dev-guide/2.2.1/org.tizen.native.appprogramming/html/sample_descriptions/basicapp.htm

https://developer.tizen.org/dev-guide/2.2.1/org.tizen.native.appprogramming/html/tutorials/ui_tutorial/task_basicapp_panels.htm

Tizen sample 중 가장 기본 앱인 basic app을 대충 훑어봄...
간단하게 Tab header를 통해 Button, Orientation, Image panel에 있는
 button, image, orientation 변경을 확인할 수 있음.


Button  Image

이것저것 다 생략하고 발로 그린 class diagram.


[BasicAppEntry.cpp]

Tizen에서는 memory에 필요 library들과 application executable을 load하고
application executable의 OspMain() 함수를 호출하여 실행.
OspMain()함수에서는 BasicApp의 instance 생성을 함

int
OspMain(int argc, char* pArgv[])
{
...
result r = Tizen::App::Application::Execute(BasicApp::CreateInstance, &args);
...
}


[BasicApp.cpp]

BasicApp에서는 app을 system에 등록하고 app UI 표시를 위해 BasicAppFram을 생성하여 등록함.
BasicApp은 Application(UiApp)을 상속 받고 Back key 처리를 위해서 IScreenEventListener를 구현함.


Tizen::App::Application(UiApp), Tizen::App::ServiceApp
: https://developer.tizen.org/dev-guide/2.2.1/org.tizen.native.appprogramming/html/guide/app/service_app_fundamentals.htm
문서에서 나와 있듯이 일반적인 application은 Application을 상속받아 구현하면 되며
UI를 가지지 않고 background로 동작하는 app을 ServiceApp을 상속받아서 만들 수 있음.


AppRegistry
: https://developer.tizen.org/dev-guide/2.2.1/org.tizen.native.apireference/classTizen_1_1App_1_1AppRegistry.html
: 설명에서는 app의 preference들을 저장하고 사용하기 위해 사용하는 class라고 하는데 아무래도 system에서 app 관리를 위해서도 사용되는 class일 것 같다... (tizen 소스를 보면 알겠지만...귀찮음)


bool
BasicApp::OnAppInitializing(AppRegistry& appRegistry)
{
int lastPanelId = 0;
String lastPanelName(L"");
String panelIDkey(L"AppLastPanelId");
String panelNamekey(L"AppLastPanelName");

result r = appRegistry.Get(panelIDkey, lastPanelId);
if (r == E_KEY_NOT_FOUND)
{
lastPanelId = 0;
appRegistry.Add(panelIDkey, lastPanelId);
}

r = appRegistry.Get(panelNamekey, lastPanelName);
if (r == E_KEY_NOT_FOUND)
{
appRegistry.Add(panelNamekey, L"Panel1");
}

// Create a Frame
BasicAppFrame* pBasicAppFrame = new (std::nothrow) BasicAppFrame();
pBasicAppFrame->Initialize(lastPanelId);
pBasicAppFrame->SetName(L"BasicApp");
AddFrame(*pBasicAppFrame);

return true;
}


[BasicAppFrame]

Tizen GUI 구성에 기본이 되는 Frame class을 상속 받은 class로 실제 App에서 사용될 MainForm을 생성&등록하는 역할을 한다.



Tizen User Interface
: https://developer.tizen.org/dev-guide/2.2.0/org.tizen.native.appprogramming/html/guide/ui/ui_namespace.htm


result
BasicAppFrame::OnInitializing(void)
{
// Create a form
MainForm* pMainForm = new (std::nothrow) MainForm();
result r = pMainForm->Initialize(__panelId);

// Add the form to the frame
AddControl(pMainForm);

// Set the current form
SetCurrentForm(pMainForm);

// Draw the form
pMainForm->Invalidate(true);

return r;
}


[MainForm]

BasicApp의 기본 GUI를 구성하는 class
기본으로 Tizen::Ui::Controls::Form을 상속 받고 Action event handling을 위해 IActionEventListener와
Back key 처리를 위해 IFormBackEventListener를 구현 한다.


class MainForm 
: public Tizen::Ui::Controls::Form
, public Tizen::Ui::IActionEventListener
, public Tizen::Ui::Controls::IFormBackEventListener
{
...

private:

Tizen::Ui::Controls::Panel* __pPanel[3];
Tizen::Ui::Controls::Button* __pButtonOrientation;
Tizen::Ui::Orientation __status;

int __panelId;
};


초기화 시점에서 GUI를 구성하는 위쪽 Tab들, ButtonPannel을 구성하고
tab들의 상태를 초기화 하기 위한 코드가 있음.
이전 실행 종료 시점에 저장해 둔 tab 위치(__panelId)에 따라서 보여지게 하기 위한 코드

좀 다른 얘기이지만 SceneManager를 사용하지 않지만 SceneManager에는 FormFactory와 PanelFactory를 등록하여 id를 사용해서 생성하게 하는 부분이 있음.. 좀 이대로 해보려고 했으나 Form 생성은 되지만 Panel 생성은 안되는 것 같다.. 나중에 좀 더 봐야 할듯.
https://developer.tizen.org/dev-guide/2.2.1/org.tizen.native.appprogramming/html/tutorials/ui_tutorial/registering_scenes.htm

result
MainForm::OnInitializing(void)
{
result r = E_SUCCESS;

Rectangle clientRect = GetClientAreaBounds();
Rectangle rect(0, 0, clientRect.width, clientRect.height);

// Create header
Header* pHeader = GetHeader();
if (pHeader != null)
{
pHeader->SetStyle(HEADER_STYLE_TAB);

HeaderItem headerItem1;
headerItem1.Construct(ID_HEADER_ITEM1);
headerItem1.SetText(L"Button");
pHeader->AddItem(headerItem1);

...

pHeader->AddActionEventListener(*this);
}

SetFormBackEventListener(this);

// Create the Button panel
ButtonPanel* pButtonPanel = new (std::nothrow) ButtonPanel();
pButtonPanel->Initialize(rect);
AddControl(pButtonPanel);
__pPanel[0] = pButtonPanel;

// Orientation panel was created with UI Builder,
// so only its button events must be defined here
__pPanel[1] = static_cast<Panel *>(GetControl(IDC_ORIENTATIONPANEL));
if (__pPanel[1] != null)
{
__pButtonOrientation = static_cast<Button *>(GetControl(IDC_BUTTON_ORIENTATION, true));

if (__pButtonOrientation != null)
{
__pButtonOrientation->SetActionId(ID_ORIENTATION);
__pButtonOrientation->AddActionEventListener(*this);
}
}

// Set the current panel as selected in the header and display it on the form
if (pHeader)
{
pHeader->SetItemSelected(__panelId);

if(__panelId == 2)
{
if (__pPanel[2] == null)
{
CreateImagePanel();
}
SetOrientation(ORIENTATION_AUTOMATIC);
}

if (__pPanel[0] != null)
{
__pPanel[0]->SetShowState(false);
}
if (__pPanel[1] != null)
{
__pPanel[1]->SetShowState(false);
}

__pPanel[__panelId]->SetShowState(true);
}

Invalidate(true);
return r;
}


Action event 처리를 위한 IActionEventListener 구현 부
Tab 처리를 위한 코드는 좀 노가다 같다..
사실 tab widget을 system에서 제공해 주면 이런 코드는 안봐도 될것 같은데..


void
MainForm::OnActionPerformed(const Tizen::Ui::Control& source, int actionId)
{
switch(actionId)
{
case ID_HEADER_ITEM1:
{
if (__pPanel[0] != null)
{
__pPanel[0]->SetShowState(true);
}
if (__pPanel[1] != null)
{
__pPanel[1]->SetShowState(false);
}
if (__pPanel[2] != null)
{
__pPanel[2]->SetShowState(false);
}
SetOrientation(ORIENTATION_PORTRAIT);
}
break;

case ID_HEADER_ITEM2:
...
case ID_HEADER_ITEM3:
...
case ID_ORIENTATION:
{
if (__pPanel[1]->GetShowState())
{
OrientationStatus status = GetOrientationStatus();
if (status == ORIENTATION_STATUS_PORTRAIT)
{
__status = ORIENTATION_LANDSCAPE;
}
else if (status == ORIENTATION_STATUS_LANDSCAPE)
{
__status = ORIENTATION_PORTRAIT;
}
SetOrientation(__status);
}
}
break;

default:
break;
}

Invalidate(true);
}

종료 시점에는 AppRegistry를 통해 선택된 tab index를 저장해 둔다..
근데 왜 panelIDkey와 panelNamekey 두개로 저장하는 걸까?

result
MainForm::OnTerminating(void)
{
AppRegistry *appRegistry = Application::GetInstance()->GetAppRegistry();
String panelIDkey(L"AppLastPanelId");
String panelNamekey(L"AppLastPanelName");

Header* pHeader = GetHeader();
result r = appRegistry->Set(panelIDkey,pHeader->GetSelectedItemIndex());
if (IsFailed(r))
{
//error condition
}

String panel;
panel.Format(50, L"Panel%d", pHeader->GetSelectedItemIndex());
r = appRegistry->Set(panelNamekey, panel);
if (IsFailed(r))
{
//error condition
}

r = appRegistry->Save();
if (IsFailed(r))
{
//failed to save data to registry.
}

return r;
}


그리고 아래 Tutorial 괜찮음
: http://tizenschools.com/?p=557


댓글 없음:

댓글 쓰기