안녕하세요, 윤진입니다.


어제는 소스콘 튜토리얼 트랙으로 타이젠 데브랩 행사에 대해 소개했었는데요,

오늘은 소스콘 컨퍼런스 트랙 중 하나인 EFL 포럼을 소개해볼까 합니다.



EFL 포럼은 소스콘 마지막 날인 10월 28일(수)에 열립니다.

오전 10시 30분부터 오후 5시 50분까지 총 10개 세션이 준비되어 있습니다.

처음 두 개 세션만 40분이고 나머지 세션은 30분 단위로 되어 있습니다.

다양한 주제가 모두 다뤄지는 만큼 30분 내지는 40분이 길게 느껴지지 않을겁니다.



EFL 한국커뮤니티에 올라와 있는 포스터입니다.

그동안 EFL은 독자적으로 세미나를 진행해왔고 올해로 3년이 되었습니다.

올해는 소스콘과 함께 개최되는 만큼 여느때보다 더 북적될 거라 기대하고 있습니다.


타이젠 플랫폼은 UIFW으로 EFL을 사용하고 있기 때문에,

타이젠 플랫폼 개발 혹은 타이젠 네이티브앱 개발에 관심있는 분들은,

EFL 트랙 하나하나를 놓쳐선 안됩니다. :)


첫 세션을 맡은 박춘언 책임 연구원께서는,

곧 배포될 Tizen 2.4 SDK에 올라간 EFL의 신규기능을 전체적으로 짚어주실 겁니다.

신규기능이란 것이 결국 더 편리하고 더 유려한 기능일테니,

잘 들어두면 개발에 직접적인 도움이 될 겁니다.


박진솔 연구원께서는,

Enventor를 '주'로 사용하여 만든 게임개발방법을 소개해주실 예정입니다.

Enventor의 업그레이드된 모습을 기대해주세요.


서현수 연구원께서는,

타이젠 SDK에 탑재된 UI Builder를 소개해주실 예정입니다.

UI Builder를 사용하여 WYSIWYG으로 소스코드를 생성할 수 있습니다.


이우찬 연구원께서는,

Elementary 위젯에 대해 포괄적인 정보를 공유해주실 예정입니다.

Elementary의 구성을 알아두면,

위젯의 스타일을 손쉽게 변경할 수 있습니다.

커스터마이징에 관심이 있다면 이 세션이 도움이 될겁니다.


그리고 다음 14:00 세션이 메인이죠(네네, 그러려니 해주세요;).

제 세션에서는 EFL 앱 개발에 사용하고 있는 여러가지 테크닉을 공유해드릴 예정입니다.

총 10개의 팁을 준비해두었고,

5개의 메인팁에 대해 집중적으로 발표할 예정입니다.

대략의 꼭지는 아래와 같습니다.


- Manage Data

- Manage Memory

- Manage Performance

- Manage Object Size with min & relative

- Manage Event


- Use Recalculate

- Use Offset

- Use Border for Nine Patch

- Use Repeat Events

- Use Color Class


위의 10개의 꼭지 중 Manage 항목이 중요하다고 여겨져서,

Manage 항목 5개 위주로 발표할 예정입니다.

정말 만에 하나 시간이 허락한다면,

Use 항목에서도 하나둘 발표할 예정입니다.

네이티브앱을 개발하시려면 꼭 들어주세요(굽신굽신).


점심시간 직후라 자칫 잘못하면 숙면실이 될 수도 있겠네요.

뭔가 재미난 얘기를 많이 넣어야겠어요!


Jean Phillippe Andre 연구원께서는,

이미지 마스킹과 필터에 대해 발표하실 예정입니다.

이전 EFL에서는 Rectangle로만 마스킹을 해야했었는데요,

Gear S2 등이 나오면서 이미지로도 마스킹을 할 필요가 생겼죠.

그래서 이미지 마스킹 기능이 새로 추가되었습니다.


엄지용 연구원께서는,

EFL에 도입된 OOP 개념에 대해 발표해주실 예정입니다.

EO가 아직 개발자단까지 피부로 와닿는 개념은 아닌데요,

Elementary 소스에는 굉장히 광범위하게 사용되고 있습니다.

EFL 소스를 분석하고자 한다면 EO에 대해 필히 알아두어야 합니다.


SubhransuSekhar Mohanty 연구원께서는,

벡터 그래픽에 대해 발표해주실 예정입니다.

보다 동적이고 자유로운 Visual Interaction을 위해 Ector를 사용할 수 있습니다.


서주영 구글러께서는,

EFL 릴리스를 하며 겪은 시행착오를 발표해주실 예정입니다.

오픈소스 배포에 대한 어려움을 직접 들을 수 있습니다.


하이츨러 EFL 창시자께서는,

EFL 신규로 도입된 디버깅 프로파일러에 대해 공유해주신다고 합니다.

디버깅 프로파일러의 부재가 항상 아쉬웠었는데요,

이번 세션을 열심히 듣고 장차 열심히 써먹어야겠습니다.


이상 총 10개 세션에 대한 개인적인 의견을 언급해보았습니다.

여러분이 놓치지 말아야할 세션은,

점심시간 이후 오후 2시에 열리는 세션이란 것만 기억해주세요;


포럼에 참석하시는 분들께,

박춘언 책임 연구원께서 직접 디자인한 티셔츠도 받으실 수 있습니다.


그럼 그 날 뵙겠습니다.

끝_











안녕하세요, 윤진입니다.


며칠 사이 일교차가 커지더니 몸이 항상성 유지에 포기했나봅니다.

두통 + 기침 + 오한의 삼중고에 시달리고 있습니다.


아침 저녁으로 한기가 완연히 느껴지는 10월에,

삼성이 서울에서 대규모 행사를 주관합니다.


SOSCON,

Samsung Open Source Conference

삼성이 주관하는 오픈소스 축제입니다.



소프트웨어 업계에 몸을 담고 있는 개발자이고,

오픈소스에 관심을 가지고 있으면서,

소스콘에 빠지시면 곤란합니다. :)


흥미로운 주제발표를 들으실 수 있고,

굉장한 개발자들과 친교를 맺으실 수 있습니다.

(저... 저랑도 친교를 맺으시지요~ 구걸구걸)

http://www.soscon.net/registration.asp


일시 : 2015. 10. 27(화) ~ 28(수), 단 26(월)은 사전행사!

장소 : 서울 여의도 Conrad 호텔


컨퍼런스는 으레 코엑스에서 개최되었었는데요,

이번에 소스콘은 코엑스 대신 콘라드를 택했습니다.

6성급 호텔에서 개최되는 행사는 어떤 모습일지 기대가 됩니다.



아직 컨퍼런스/튜토리얼 참석 신청 버튼이 열려있습니다.

컨퍼런스를 신청하시면, 키노트 · 세션 · 포럼에 참가하실 수 있습니다!

튜토리얼을 신청하시면, 타이젠 데브랩, IoTivity, S4A 행사에 참가하실 수 있습니다!



여기까지 설명을 드렸으니 이미 눈치를 채셨겠지만요~ 히힛.

그렇습니다,

소스콘 사전행사로 10. 26(월)에 타이젠 데브랩을 개최합니다. :)

이번 데브랩은 정말 재미있을 거예요!


데브랩에 주어진 시간은 총 4시간입니다.

4시간짜리 강의를 할 수는 없으니 크게 두 개의 세션으로 나눠서 진행하려고 합니다.

웹앱 세션 2시간 & 네이티브앱 세션 2시간으로 말이지요.


각각의 세션은 독립적으로 존재하지만 쉬움 vs 정교함을 지속적으로 비교할 수 있게 구성하였습니다.

"누구나 쉽게 만드는 Tizen Web Application"

"정교하게 만드는 Tizen Native Application"


웹앱세션은 웹앱의 대가 강석현 선임께서 발표를 하실 예정입니다.

발표 강석현 선임 연구원 / 시연 손보연 연구원 / 튜터 김용국 연구원, 김수필 연구원


그리고 네이티브세션은 제가 새로운 컨텐츠로 발표할 예정입니다.

발표 윤진 선임 연구원 / 시연 이은영 연구원 / 튜터 이근선 연구원, 박문경 연구원


매일매일 발표를 준비하며,

웹앱세션보다 명료하고 풍부하게 주제를 표현하고자 노력하는데요,

강석현 선임께서 워낙 발표준비를 잘 하셔서 쉽지 않네요. 히힛.


이번에 데브랩에 오시는 분들은,

반드시 개인 노트북에 타이젠 2.3.1 SDK를 설치하고 오셔야 합니다.

데브랩 시간 동안은 실습만으로 빠듯해서, 따로 SDK를 설치할 시간이 없을겁니다.


만약 SDK 설치에 도움을 받으셔야하면,

행사 시작 1시간 전인 오후 1시에 와주세요.

저희가 도와드리겠습니다!


사전에 배포될 예정인,

발표자료와 소스도 함께 챙겨주세요.

예습을 하시면 좋겠지만,

예습없이도 충분히 이해하기 쉽게 '천천히' 진행하려고 합니다.


이번 데브랩에는 소정의 상품이 준비되어 있습니다.

데브랩에 참석하는 모든 분께 상품을 드리도록 준비는 하고 있지만,

웹앱 세션과 네이티브 세션에서 진행하는 실습에 잘 따라오신 분들께(!)

우선적으로 상품을 드리려고 합니다.


데브랩은 스타터를 위한 행사이니만큼,

타이젠과 함께 즐거운 첫 경험을 시작하셨으면 합니다.


발표내용은 이미 오래전에 정해두었는데요,

아직 발표자료가 완비되지 않아 걱정입니다.

우선 감기부터 떨궈내야 할텐데 말이지요.


감기 조심하시고,

좋은 하루 보내세요~


끝_


인류 역사상 두번째 타이젠 모바일 폰이 나옵니다.

올해 1월,

인류 4대 문명 발생지 중 하나인 인도에서 첫번째 타이젠 모바일 폰 Z1이 나왔는데요.

약 9개월이 지난 후 두번째 타이젠 모바일 폰이 나옵니다.


두번째 타이젠 모바일 폰의 네이밍은 Z2가 아닌 Z3인데요,

사실 내부 개발자들 사이에서도 왜 '2'가 아닌 '3'인지에 대한 갑론을박이 많았습니다.

하지만, ZDNET에 그 이유가 명쾌하게 나왔네요.

"Z1 후속 제품임에도 Z2가 아닌 Z3라는 이름이 붙은 이유는 갤럭시S나 갤럭시노트 시리즈처럼 매년 1번 출시되는 플래그십 제품군이 아니라 다양한 성능과 가격대에 라인업이 동시에 출시되는 갤럭시A 시리즈(갤럭시A3·A5·A7)처럼 타이젠폰의 라인업을 다양화한다는 의미다."


이번에도 첫 출시국은 인도입니다.

인도는 세계 2위 인구대국이고 머잖아 중국을 제치고 세계 1위의 인구대국이 될 국가입니다.

최근 출산율을 비교하면 인도가 중국보다 월등히 앞서더군요.

거기에 IT산업도 무섭게 발달하고 있죠.

타이젠 모바일폰의 입장에서는 가장 중요한 시장입니다. :)


Z1이 판매된 서남아 국가, 인도 · 방글라데시 · 오만에서 모두 Z3가 판매되겠지요?

거기에 유럽에도 출시된다는 소문이 돌고 있습니다.

아직은 확정된 이야기는 없습니다만,

개인적으로는 더 많은 국가에서 타이젠폰을 사용할 수 있으면 좋겠습니다.


10월 21일에 인도에서 출시될 예정이라고 하니,

인도 친구들에게 부탁해봐야겠습니다.

아니면, Z1 때처럼 삼성 타이젠 카페에서 공동구매를 해야겠네요.

우리 돈으로 15만원 정도이니 부담없는 가격이네요.


출처 : http://www.gsmarena.com/samsung_z3-7273.php


GSM ARENA에 올라와 있는 Z3 사양입니다.

1.3 GHz 쿼드코어 / HD(720 x 1280) 해상도 / 메모리 1Gb입니다.

개발완료된 시료를 보니 속도가 굉장히 빠르더군요.

어차피 우리나라에선 팔지도 않을테니,

'한글로 된' 쓸모없는 홍보를 하자면,

최적화의 끝을 봤기에 말도 안되게 탁월한 속도를 보이더군요.

이런 사양에 올라간 플랫폼이 이런 성능을 내는 것은 본 적이 없습니다.


타이젠 플랫폼 개발자가 타이젠 홍보를 하니 좀 웃기네요.

왠지 신뢰가 팍 떨어지는 느낌이랄까요;

근데 어차피 우리나라에선 안 파니까요!

팔불출이라고 욕하셔도 됩니다!


근데 위의 GSM ARENA에 나온 기사 부분 중에 정정할 게 있습니다.

Tizen 2.3 기반이라고 되어있는데요,

아닙니다. Tizen 2.4 기반입니다.

현재 타이젠 공식 사이트에 가보시면,

Tizen 2.3.1이 공식 오픈되어있는데요,

그 다음 버전인 Tizen 2.4가 탑재되어 있습니다.

이 내용은 이 기사에서도 확인하실 수 있습니다.


색상은 Z1때보다 고급진 느낌입니다.

일단 아래 사진으로 블랙/골드/실버 세 가지 색상타입을 보시죠.

Black



Gold


Silver


제 Z1은 흰색인데요,

("[Tizen] 타이젠 최초의 모바일 기기, "Z1"의 늦은 개봉기", http://storycompiler.tistory.com/19)

Z3는 실버로 정했습니다. :)


그리고 Z3에는 굉장히 매력적인 기능이 탑재되어 있습니다.

타 플랫폼 대비 편리하고 유용하게 사용할 수 있는 기능인데요.

네네, 맞습니다.

제가 개발한 모듈이라 '지자랑'하려고 얘기를 꺼냈습니다.

(물론 재기발랄한 디자이너와 빠릿한 개발자들도 함께 했습니다)

제 블로그인데 '지자랑'도 하나쯤 해야죠~!

그 기능에 대해서는 나중에 Tizen 2.4 플랫폼을 이야기할 때 다시 꺼낼 기회가 만들겠습니다.

기필코;


기승전 지자랑으로 포스팅을 마칩니다.

용서해주세요.


끝_

  1. 코코콩 2015.10.15 09:13 신고

    오옷 드디어 나왔군요!
    저도 타이젠카페에서 공구할생각입니닷 ㅎㅎ
    개발하신 모듈도 기대가되네요:)

  2. amaze_ 2015.10.28 02:44

    오오! 지자랑. 기대됩니다~ 컬러가 확실히 더 예쁘네요(사진빨일지도 모르지만;;)

    • 안녕하세요~ amaze_님.
      검은색을 주문해놨는데요,
      도착하면 포샵처리안된 검은색은 보여드릴 수 있어요. :)
      우후후.


지난 10월 1일 목요일,

대구 EXCO에서 Global Innovator Festa 2015(이하 GIF 2015)가 개최되었습니다.

부제는 "Start your idea"이고 테마가 "Come Out & Play"입니다.

부제와 테마만으로도 충분히 심장이 떨리는군요 :)


행사 참관을 위해 새벽 5시에 일어나 KTX를 타고 대구로 내려갔습니다.

집을 나설 때에는 제법 날씨가 쌀쌀했는데요,

대구에 도착하니 '대프리카'의 명성에 맞게 아주 더웠습니다.



EXCO에 9시쯤 도착하였는데요,

아직 행사가 준비중인 시간이라 사람이 거의 없었습니다.

행사장 앞에 주차관리하시는 분들만 나와계시더군요.



가로등에 꽂혀진 안내기를 찍으려고 했는데 바람에 나부껴서 제대로 안 찍히더군요.

그걸 보신 주차요원 아저씨께서 심심하신지 안내기 아래를 잡아주셨습니다.



EXCO 전면에서 찍은 사진입니다.

입구 정면과 좌우에 GIF 2015를 알리는 현수막이 걸려있었습니다.



EXCO 안에 들어가니 행사참가자들이 제법 있더군요.

대부분 대학생들로 보였습니다.

아직은 행사장이 열리지 않아 입구 근처에 서서 두런두런 이야기를 하더군요.



행사관계자 신분으로 먼저 행사장으로 들어갔습니다.

잠시 후 시작될 본행사를 위해 몇몇 관계자들이 분주하게 돌아다녔습니다.

그 외에는 전반적으로 한산하였기 때문에 여기저기 여유롭게 구경했습니다.

주제강연과 전시 그리고 아이디어톤이 열리는 홀의 전경을 2층에서 찍어보았습니다.



의무실과 비즈니스&프레스를 위한 공간도 보였습니다.

의무실과 인포메이션 센터에 관계자 분들도 무료해보였습니다.



행사장 한 켠에 대형 드론도 전시되어 있었습니다.

아이드론의 정동일 대표께서 GIF 2015 마지막 강연으로 드론에 대해 이야기 하셨다고 하던데,

드론에 대한 관심은 어디서나 찾아볼 수 있네요.



한 쪽 부스에서는 흥미로운 주제강연들도 다수 준비되어 있었습니다.

"기업가 정신" by 로렌스 앤 필드기업가 센터 Edward G. Rogoff 교수

"과학기술과 창작문화 그리고 미래" by 한국과학창의재단 김승환 이사장

"글로벌 스타트업 열풍" by 스타트업얼라이언스 임정욱 대표

"공공데이터 집단지성을 활용한 커뮤니티 맵핑" by 커뮤니티맵핑센터 임완수 센터장

"소셜앰팩트 토크콘서트" INCH Sociential Izumi Yoshitsugu 대표

그리고 삼성 리크루트 데이도 열렸습니다.



아이디어톤 행사는 이미 열리고 있었습니다.

자리에 두런두런 앉아 이야기를 하고 있는 학생들도 보이고,

한쪽 구석에서 휴식을 취하고 있는 사람들도 보였습니다.

따로 구비된 휴게공간에 누워 자고 있는 참가자도 있더군요.


위의 사진은 헤커톤이 열리는 홀의 전경입니다.

웨어러블 / 헬스케어 / 빅데이타 / IoT를 위해 홀을 4개의 구획으로 나뉘어 있었습니다.

제일 가까이 있는 웨어러블 구획 안에 멘토링을 위한 부쓰 2개가 보이네요.



11시가 되어가자 참가자들이 속속들이 도착하였습니다.

웨어러블 해커톤 구획 뿐만 아니라 다른 해커톤 구획에도 사람들이 북적이더군요.

참가팀이 30팀인데 웨어러블 헤커톤의 경우,

모든 팀이 빠짐없이 출전하였습니다.



웨어러블 해커톤에서는 기어 S2에 올라갈 앱을 1박 2일간 개발해야했습니다.

기어 S2에는 타이젠이 올라가기 때문에,

삼성전자 박영주 수석님께서,

타이젠 SDK로 개발가능한 웹앱과 네이티브앱에 대해 발표를 해주셨습니다.

웹앱과 네이티브앱을 대별하여 각각의 특장점을 언급해주신 부분이 기억에 남네요.



뒤이어 삼성전자 김지수 선임님께서 테크니컬 세션을 열어,

웨어러블 앱 개발 방법론에 대해 여러가지 고려해야할 사항을 언급해주셨습니다.

짧은 시간이지만 많은 내용을 빠짐없이 말씀해주셨습니다.



삼성전자 홍승환 책임님께서 기어 S2의 디자인컨셉을 설명해주셨는데요,

해커톤 참가자들이 UX를 구상할 때 실질적으로 도움이 될만한 유용한 정보를 알려주셨습니다.



어디서도 들을 수 없는 타이젠 관련 발표를 듣고,

참가자들은 1박 2일 동안 멘토들과 함께 앱을 개발해야 합니다.

위에 사진 속에 선남선녀들은 웨어러블 멘토들입니다. :)



해커톤은 전체적으로 위처럼 진행되었습니다.

점심먹고 개발하고 저녁먹고 개발하고 밤새 개발하는 일정입니다.

토요일 오전 9시부터 1차 심사가 있고,

토요일 저녁에 2차 심사가 있습니다.

그리고 저녁에 바로 시상을 합니다.



1등 팀에 15,000,000원 상금이 수여되고,

2등 2팀에게는 200만원의 상금이 수여된다고 합니다.

내년에 참가하고픈 욕심이 생기는군요;



올해의 경우,

참가 신청서 양식도 제법 간단했기 때문에,

프로젝트 아이디어만 있으면 어렵지 않게 참가할 수 있었습니다.


이런 행사를 통해 타이젠 플랫폼이 개발자에게 한걸음 다가가면 좋겠네요.

아직은 여러가지 부족한 면이 보일지는 모르겠지만,

매일매일 조금씩 앞으로 나아가고 있습니다. 



GIF 2016에는 어떤 행사가 열릴지 벌써부터 기대가 되는군요~

그럼 좋은 하루 보내세요~




지난 주 모처에서 타이젠 앱개발을 주제로 발표를 하였습니다.

발표에 참여하는 분들이 여러가지 면에서 흥미로운 요소를 지니고 있어서,

그 동안 한 번도 보여준 적이 없는 형태로 발표를 준비하였습니다.

발표물은 한 번 쓰고 폐기처분해야하는 상황이라 아쉽긴 하지만,

 발표문에서 타이젠 네이티브앱 초보 개발자에게 흥미로운 내용만을 추려서 포스팅 합니다.



1. 앱라이프사이클


타이젠 앱라이프사이클은 앱의 동작방식을 확정지을 수 있다는 것만으로도 의미가 있지만,

라이프사이클을 활용하여 런칭속도를 최적화할 수 있는 포인트가 있기에 매우 중요합니다.


지난 데브랩때도 이 부분을 강조하여 설명을 드렸었죠.

(관련 포스팅 : http://storycompiler.tistory.com/138)


우선 최적화 포인트는 잠시 접어두고 앱사이클을 따져봐야겠지요.

타이젠의 앱 라이프사이클은 아래 5가지 콜백으로 관리됩니다.


- app_create

- app_terminate

위의 두가지는 앱이 각각 생성될때와 종료될때 불립니다.

가장 기본적인 라이프사이클을 관리하는 함수입니다.


- app_resume

- app_pause

위의 두가지는 앱윈도우의 속성과 관련이 있습니다.

윈도우가 1px이라도 화면에 보여지는 순간 resume이 되고,

1px 조차도 보이지 않게 되면 pause가 됩니다.


네이티브앱에서는 ui가 없는 service 앱도 개발할 수 있는데요,

service 앱의 경우는 resume / pause 콜백이 불리지 않습니다.

왜냐하면 위에서 언급했듯,

resume / pause는 윈도우와 함께 동작하는 피쳐이기 때문이지요.


- app_control

control은 앱을 런칭할 때 부가적인 정보를 전달하는 수단으로 사용됩니다.

caller 앱에서 callee 앱에게 정보를 전달할 수도 있고,

service 앱이 ui 앱에게 정보를 전달할 수도 있겠지요.


타이젠 네이티브앱은 최초 런칭시,

앱이 사전에 콜백으로 등록한,

app_create_cb(), app_control_cb(), app_resume_cb()이 순서대로 불립니다.

최초로 불리는 app_create_cb() 함수는,

앱이 mainloop에 진입하기 직전에 수행하는 함수입니다.

앱이 app_create_cb()에서 리턴되면,

바로 mainloop에 진입하여 app_create_cb()에서 요청한 대상에 대해 렌더링을 실시합니다.

이 때 벌어지는 렌더링이 앱 라이프사이클 중에 최초의 렌더링입니다.


그리고 두번째 렌더링은 통상 app_control_cb()을 실행하고 이뤄집니다.

그렇기 때문에 첫번째 렌더링이 빠르게 이뤄질 수 있도록,

app_create_cb()을 간소하게 짤 필요가 있습니다.

바로 이 부분이 최적화 포인트인 셈입니다.


간단하게 라이프사이클을 등록하는 코드를 보면 아래와 같습니다.


int main(int argc, char *argv[])
{
    struct appdata ad;
    ui_app_lifecycle_callback_s event_callback;

    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;
    return ui_app_main(argc, argv, &event_callback, &ad);
}



2. 레이아웃

UI를 가진 앱이라면 앱과 사용자와 교감하는 인터페이스를 우선적으로 고려해야합니다.

네이티브 앱의 경우 레이아웃은 edc를 빼놓고 이야기할 수 없겠지요.


edc로 화면의 레이아웃을 구성하고 C로 edc로 짠 레이아웃에 위젯들을 탑재합니다.

C코드에서 edc를 로딩할 때 사용하는 함수가,

elm_layout_add()입니다.

그리고 로딩된 edc 레이아웃에 C에서 작성한 오브젝트를 탑재할 수 있습니다.

elm_object_part_content_set()

위의 함수를 사용하면 간단하게 탑재가능하지요.


탑재를 했으면 반대로 해제를 하는 함수도 있겠지요.

elm_object_part_content_unset()


위의 함수와 함께 메모리 관리에 대해 고민하는 것도 흥미로울 것 같네요.

이 부분은 SOSCON에서 진행할 Devlab이나 EFL 트랙 발표에서 좀 더 다룰 예정입니다.


edc에서 이뤄지는 레이아웃은 아래와 같은 형태가 되겠네요.

edc에서는 rel1 / rel2를 사용하여 각각의 파트마다 위치와 크기를 지정할 수 있습니다.

이미 사용하고 계시다면 굉장히 간단하게 코딩 가능한 스크립트라는 것을 아시겠죠?



3. 뷰플로우

앱은 다수의 뷰로 구성이 됩니다.

하나의 뷰로만 구성된 간단한 앱도 있습니다만,

보통은 몇 단계의 depth로 앱의 세부항목에 다다르는 구조로 되어 있지요.


각각의 뷰는 기본적으로 stack에 넣어 관리를 하는데요,

그 stacking을 도와주는 객체가 elm_naviframe_xxxx() 함수입니다.


naviframe의 stack에 뷰를 push / pop하며 화면 전환을 할 수 있습니다.

화면 전환간에 default로 동작하는 이펙트는 오른쪽에서 왼쪽으로 기존 뷰를 덮으며 나타나는 이펙트입니다.

이펙트는 customize를 통해 신규로 적용이 가능합니다.



naviframe에서 default로 보여지는 타이틀 영역은,

elm_naviframe_item_title_enabled_set() 함수를 사용하여 없앨 수 있습니다.


그리고 elm_naviframe_items_get() 함수로,

naviframe에 들어간 아이템의 리스트를 얻어올 수 있습니다.


stack은 top에만 넣고 뺄 수 있는 구조기에,

중간에도 넣을 수 있도록 insert 관련 함수도 사용할 수 있습니다.

elm_naviframe_item_insert_before()

elm_naviframe_item_insert_after()



4.  비주얼 인터액션

화면을 구성하고 있는 개별 컴포넌트에 각종 효과를 적용할 수도 있습니다.

C에서는 elm_transit 계열의 함수를 사용하여 효과를 줄 수 있고,

edc에서는 program을 활용하여 효과를 줄 수 있습니다.


여기서는 비교적 직관적으로 사용 가능한 edc를 살펴 보겠습니다.

edc는 화면의 구성요소를 의미하는 part와 part 간의 동작을 정의하는 program으로 나뉩니다.


			part {
				name: "popup";
				type: RECT;
				description {
					state: "default" 0.0;
					rel1 { relative: 1.0 0.0; }
					rel2 { relative: 2.0 1.0; }
					color: 154 187 211 255;
					visible: 1;
				}
				description {
					state: "show" 0.0;
					inherit: "default" 0.0;
					rel1 { relative: 0.0 0.0; }
					rel2 { relative: 1.0 1.0; }
				}


위의 파트는 2가지 description을 가지고 있습니다.

각각의 description은 컴포넌트의 위치를 확정하는 rel1 / rel2 값을 달리 가져가고 있습니다.

위처럼 앱의 각각의 상태에 대한 확정은 part에서 진행합니다.


			program {
				name: "popup_show";
				signal: "popup_show";
				action: STATE_SET "show" 0.0;
				target: "popup";
				transition: DECELERATE 0.3;
			}
			program {
				name: "popup_hide";
				signal: "popup_hide";
				action: STATE_SET "default" 0.0;
				target: "popup";
				transition: DECELERATE 0.3;
			}


그리고 part에 위처럼 program이 붙어서 동작제어를 가능하게 합니다.

위의 program은 popup_show라는 시그널이 C파일로부터 날라오면,

popup 파트의 description을 "show"로 변경해줍니다.

만약 transition이 설정이 되어 있다면,

transition의 값을 참고하여 timer를 돌려 부드러운 이펙트로 보여줍니다.



5. 최적화

앱을 위한 화면구성을 완료했다면, 이제는 최적화에 손을 쓸 차례입니다.

Native 앱에는 최적화를 다양한 방법이 있습니다.


앱단에서 가장 손쉽게 관리할 수 잇는 방법은,

elm_gengrid와 elm_genlist 윈셋을 적극적으로 사용하는 것이겠지요.


elm_gen 시리즈는 화면에 보여지고 있는 영역 위주로 메모리에 로딩하고,

보이지 않는 영역은 메모리에서 언로딩하는 방법을 사용하여 메모리를 절약합니다.



genlist에 아이템을 삽입할때는,

아이템의 레이아웃을 edc로 정의해줄 수 있습니다.

위의 Class의 .item_style 필드가 커스터마이즈한 edc입니다.



위의 edc에서는 레이아웃에 필요한,

icon과 name part를 정의하고 있습니다.



그리고 레이아웃에 채워넣을 icon과 텍스트는,

content_get 필드에 대입되어 있는 함수와 text_get 필드에 정의한 _text_cb의 리턴값으로 결정됩니다.



6. 언어변경

언어는 오픈소스인 gettext를 사용하고 있습니다.

gettext 함수를 사용하려면 국가마다 po 파일이 있어야 하지요.

앱에서 지원하고자 하는 나라수만큼 po 파일을 준비해두어야 합니다.


po 파일을 구성하는 msgid에 모든 언어에서 공통적으로 지칭할 고유아이디를 적어둡니다.

C파일에서 텍스트를 노출해야하면,

msgid에 있는 값을 노출해야하는 곳에 적어두어야 합니다.

msgstr에는 고유아이디와 설정언어의 조합을 통해 gettext()로 번역되어 나옵니다.


시스템 상에서 언어가 바뀌면,

앱라이프사이클과 함께 등록한 language_changed_cb()이 불립니다.

그 함수 안에서 변경된 언어를 설정해두고,

다시 gettext()가 불리도록 update만 시켜주면 됩니다.



이상이 초보개발자들이 궁금해할만한 내용이었습니다.

각각의 내용은 하나의 포스팅으로 완결될 수 있는바,

시간을 마련하여 언젠가 포스팅을 하도록 하겠습니다.


그럼 좋은 하루 보내세요~

끝_

  1. 전광하 2015.11.26 20:53

    " naviframe의 stack에 뷰를 push / pop하며 화면 전환을 할 수 있습니다.
    화면 전환간에 default로 동작하는 이펙트는 오른쪽에서 왼쪽으로 기존 뷰를 덮으며 나타나는 이펙트입니다.
    이펙트는 customize를 통해 신규로 적용이 가능합니다 " 라고 하셨는데.. 어떻게 customize를 하는지 알 수 있을까요? 아무리 검색해도 안나오네요.

    • 안녕하세요, 전광하님.
      커스터마이징을 하기 위해서는 edc 파일을 수정해야하는데요,
      답글로는 그 내용을 담을 수 없고(너무 이야기할게 많습니다),
      빠른 시일내로 전체적으로 정리하는 시간을 마련해보도록 하겠습니다.
      언젠가 문의가 들어올 것으로 예상은 했었는데요,
      문의가 들어오기 전에 준비를 했었어야 했는데...
      아무튼 11월은 벌써 끝나가니 12월 중엔... 기필코 정리하도록 하겠습니다.
      그 전까지는 현재 naviframe을 사용하시고,
      아니면 edc에서 naviframe 역할을 하는 그룹을 만드시면 됩니다(edc를 어느정도 아시는지요?).

      곧, 커밍순 하겠습니다. :)

      감사합니다!

  2. 전광하 2015.12.01 00:48

    답변감사합니다. 열정적으로 글들을 읽고있고, 모든 edc 글들을 읽고 연습중입니다. 네비프레임은 포스팅되면 해볼게요 감사합니다~

    • 안녕하세요, 전광하님. edc가 마의 산맥으로 여겨질 수도 있을텐데요. 어려움이 생기면 언제든지 주저말고 문의주세요. :) 그럼 즐거운 코딩하시길~!


안녕하세요, 윤진입니다.


지난 8월 29일에 열린 타이젠 DEVLAB @SEOUL 행사에서 발표한 자료를 공유합니다.

사내에서 만든 자료는 보안 등 여러가지가 신경 쓰여서,

발표한 내용을 토대로 집에서 재작업하였습니다.


행사에서 발표를 하며 발표자료를 바로 올려드리겠다고 약속 드렸었는데요,

많이 늦어진 점 무척이나 송구스럽습니다.


겨우 45분짜리 발표라서,

준비해갔던 내용 모두를 전달해드리지 못한 부분도 아쉽습니다.


하지만, DEVLAB 행사는 계속해서 열릴 예정입니다.

첫 DEVLAB의 아쉬움은 다음 DEVLAB에서 달랠 수 있겠지요.

다음 DEVLAB은 10월 말 SOSCON과 함께 열릴 예정인데요,

많은 관심 부탁드립니다.


제가 발표한 부분은 타이젠 Native 앱 최적화입니다.

Native 초/중급 개발자를 대상으로 발표를 진행하였습니다.


최적화를 논할때 반드시 필요한 AppFW과 UIFW 내용을 전반부에 다뤘고,

후반부에는 실제 코드를 예시로 들어가며 최적화 방법을 공유하였습니다.


아래 자료에 대해 궁금한 점이 생기시면 댓글 달아주세요.

다음 DEVLAB에서는 보다 다양하고 심도깊은 주제로 찾아뵙겠습니다.


ppt가 필요하신 분은 따로 말씀해주시면 보내드리겠습니다.

그럼 좋은 하루 보내세요~


추신 : '본인이 더 천재인' 천재태지 서주영님의 요청이 있어 slideshare에 업로드하였습니다.

http://www.slideshare.net/theojini/blogging-tizen-devlabseoul-ppt-optimization



































  1. 코코콩 2015.09.18 13:19 신고

    감사합니다. SOSCON이 평일에 열리는군요...
    하핫; 연차를 내고 가야겠네요

  2. 코코콩 2015.09.18 15:17 신고

    가고싶은데 어떤걸 신청하면 되는지 모르겠네요 ... ㅠㅠㅠㅋ

    • http://efl.or.kr/ 여기에 가시면 efl 트랙에 대한 정보를 차차 얻으실 수 있을거예요. 여러 유용한 팁들을 얻으실 수 있을거예요!

  3. 초보개발자 2015.09.25 17:42

    안녕하세요. 항상 매번 앞으로도 많은 도움을 받아가고 있습니다. 감사드리며, ppt 보내주신다하셔서..
    아무한테나 보내주실지 모르겠지만, 보내주실수 있으시다면
    seromicom@gmail.com
    위 주소로 보내주실수 있으신지요??
    저도 현직 몰라도 너무몰라 부끄럽지만 타이젠 개발자라고.. 자리 차지하고 있어서..
    SOSCON 을 가지 않을수가 없을 듯 하네요.. ^^

    • 안녕하세요! 집에 가서 바로 보내드리겠습니다. 근데 타이젠 개발을 하신다면 저랑 가까운 곳에 계시겠네요. 같이 차나 한잔 하시죠~!

  4. 천재태지서주영 2015.10.01 00:23

    slideshare에 올려주세요~

    • 주영이가 올리라면 올려야지.
      좀 늦었지만 slideshare에 올렸사옵니다. :)
      http://www.slideshare.net/theojini/blogging-tizen-devlabseoul-ppt-optimization

TIZEN 개발자들을 위한 행사가 지난 토요일에 열렸습니다.

"TIZEN DEVLAB @SEOUL"(타이젠 데브랩 @서울)

"[Tizen] 타이젠 DEVLAB @SEOUL 행사안내" 포스팅 참고


신사장 외관


행사가 진행된 서초구 신사장의 외관은 위와 같습니다.

건물은 그렇게 크지 않고 연한도 꽤 되어 보입니다.

택시를 타고 갔는데 택시기사 아저씨가 신사장을 몰라서 많이 헤매셨습니다.

도대체 언제 만든 건물이냐고 요즘 새로운 건물들이 많이 올라가서 잘 모르겠다고 하셨는데...

건물 외관을 보고 아저씨도 저도 많이 놀랐습니다.


행사 입간판


만약 건물 오른편에 놓인 타이젠 행사 입간판이 없었다면 더 헤맸겠지요.

오늘처럼 타이젠 마크가 반가운 날이 없었어요. :)


입구천장


건물 내부를 보니 나이든 건물을 무리하게 리노베이션하지 않고,

시멘트 그대로를 노출한 인테리어를 사용했더군요.

IT 행사를 휘황찬란한 컨벤션 센터가 아닌 투박한 곳에서 하니 역설적으로 신선했습니다.


철제계단


행사장은 복층으로 되어 있었습니다.

1층 행사장 중간에는 2층으로 올라갈 수 있는 철제계단이 놓여져 있었습니다.


1층 철제계단 좌측


1층과 2층 모두에 참가자가 노트북을 사용할 수 있도록 책상과 의자가 놓여져 있었습니다.

빈 공간이 거의 없을 정도로 빽빽하게 책상과 의자가 있더군요.

위 사진의 천장이 잘 보이진 않지만 1층 좌측의 천장이 2층입니다.


1층 기둥 우측


1층 우측은 천장이 뚫려져 있어서 훤하네요 :)

1층에서도 2층에 설치된 스크린이 보이죠?


2층 우측에서 내려다 본 모습


1층에서 발표자가 강의를 진행하면,

2층에서는 2층 우측에 있는 발코니에 기대어 발표를 볼 수 있는 구조였습니다.


2층 좌측 좌석


2층 좌측에 의자에 앉는 분들을 위해 TV도 놓여있었습니다.

TV로는 1층 전경과 발표자의 모습이 조그마하게 보입니다.

가운데에 놓여져 있는 TV 보이시죠?



발표는 위의 순서로 진행되었습니다.

저는 참가자가 아닌 발표자로 갔기 때문에 모든 세션에 참석하진 않았는데요,

차라리 서둘러서 처음부터 참석했으면 더 좋았을걸이란 후회가 들었습니다.


"타이젠 개발환경 소개" 세션을 발표해주신 서영진 강사님.

개인적으로 서영진 강사님을 만나고 싶어서 일찍 가려 했으나 몸이 안따라줘 진심으로 아쉽습니다.


"누구나 쉽게 만드는 Tizen Web App"을 발표 중인 강석현 연구원님입니다.

발표 일주일 전부터 발표 준비를 하셔서 저도 서둘러 준비했는데요,

강석현 연구원님 아니었으면 발표자료를 시간 내에 완성하지 못했을거예요 :)

발표가 끝나고 점심시간에도 질문을 받고 계시는게 인상적이었습니다.


"Android 개발 경험자를 위한 Tizen Native Application Basic"는 이비오 연구원님께서 발표해주셨습니다.

이 발표 전에 도착하여 느긋하게 홍차 한 잔 마시고 발표를 들었는데요,

안드로이드와 타이젠을 비교하며 App Lifecycle을 설명해주신 부분이 인상적이었습니다.

제 발표와 겹치는 부분이 있어서 발표를 열심히 들으면서 넣고 뺄걸 계산하느라 사진은 못 찍었습니다.


"Native Application Life Cycle & Optimization"을 발표하고 있는... 접니다.

사진을 보니 뭔가 손동작을 하고 있는데요,

발표를 하고 보니 전 발표하면서 손을 많이 사용하더군요.

핀마이크를 꼽아달라고 부탁드렸는데 탁월한 선택이었네요;

제게 할당된 시간이 45분 밖에 안되었는데요,

실습과 함께 병행하여 설명하기에는 정말 적은 시간이어서 실습은 일부러 뺐습니다.

발표를 들으시는 분께 질문은 이 블로그에 올려달라고 하고 50분 넘은 발표를 마무리 했는데요,

다음에 다른 행사를 통해 진득하게 발표하고 싶단 생각이 듭니다.

중간에 고개를 끄덕이며 호응해주신 분들께 감사를 표하고 싶습니다.


"Tizen에서 Unity로 게임 만들기"는 이영호 Unity 에반젤리스트께서 해주셨습니다.

제 발표를 하고 진이 빠져 사진을 찍진 못했지만,

발표를 정말 능수능란하게 잘 하시더군요~

Unity의 매력을 짧은 시간에 잘 설명해주셨습니다. :)


"cocos2d-x로 Tizen 시작하기"는 서석원 연구원님께서 진행하셨습니다.

오픈소스인 cocos2d-x를 타이젠 SDK에 붙이는 것을 시연해주셨습니다.


실습을 진행하며 발표를 하기란 정말 쉽지 않더군요.

각자 노트북을 가져와 SDK 부터 설치를 하고 실습을 하는데,

노트북 성능이 제각각이고 사용하는 운영체제도 윈도우, 우분투, iOS로 다양하다보니 우여곡절이 많았습니다.


타이젠 시료 TM1


그래도 타이젠 시료 TM1를 참가자들 모두에게 나눠주는 것을 보니...

엄청 부러웠습니다.

쓰지 않으실 분은 제게 버려주시면 안될까요? :)


이 날 행사에 사용된 모든 발표자료는 이번 주 중으로 올라올 것으로 기대하고 있습니다.

발표한 내용을 좀 더 보강 + 수정해서 공개할 것으로 알고 있습니다.

발표자료가 공개되는 것과는 별개로 제 발표내용을 별도로 포스팅하려고 합니디ㅏ.

조금만 기다려주시고 문의사항이 있으면 언제든지 질문 올려주세요!


다음 타이젠 행사가 벌써 기대가 되네요.

그럼 좋은 하루 보내세요~


끝_

  1. 코코콩 2015.08.31 11:20 신고

    포스팅 참 잘하시네요 하하; 윤진님은 TM1을 못받으셨나보네요... 달라고하면 주시지않을까요 ㅎㅎ;

    • 코코콩님, 안녕하세요. TM1은 무지 귀한 시료라서 저희도 받기 힘듭니다 :) 귀한 시료 받으셨으니 많은 도움이 되었으면 좋겠습니다... 부러워요. 히히.

  2. 와우~~사진에 제가보여요! 2015.08.31 11:20

    윤진님! 강의 잘 들었습니다.
    전체적으로 매끄럽지 못한 부분이나 초보자부터 전문 개발자까지 안고 가려하다보니 애매한점들도 보였는게 좀 아쉽네요 ㅠㅠ

    준비하신 좋은 강의를 시간상 준비하신 부분들을 다 못들어 아쉽습니다 ㅠㅠㅎㅎ
    다음 데브랩에서 뵙도록 하겠습니다!!!

    • 안녕하세요! 윤진입니다.
      이번 데브랩 행사에는 여러 미숙한 점이 많았는데요, 특히 짧은 시간에 실습까지 병행하느라 시간이 너무 부족했습니다. 다음 데브랩 행사에는 저희 모두 더 많이 준비해서 찾아뵙겠습니다. 개발자 수준에 맞게 다양한 세션 개발도 해야겠네요~!
      근데 어느 사진에 계신가요? 이름이라도 알려주세요. 하핫. 다음에는 인사라도 할 수 있으면 좋겠습니다.

  3. 이준호 2015.09.03 20:37

    오... Only Cap 자료 찾다보니 블로그도 하시네요.

    다음에 강의하시면 배우러 가야겠네요.

    • 이수석님이 그렇게 자랑하시는 천재소년님께서 오실줄은 몰랐어요. 오히려 제가 배워야죠~! 앞으로도 많이 알려주세요! 존경합니다.

  4. 2015.09.08 12:07

    비밀댓글입니다

    • 2015.09.08 13:24

      비밀댓글입니다

  5. 천재태지서주영 2015.09.13 23:45

    현장감이 살아있는 포스팅 잘 봤어요 ^^

    • 구글러 서주영님께서 이곳까지 왕림을 다해주시고 매우 영광!! :) 소스콘 EFL 트랙에 EFL앱에 대해 발표할건데 그때는 볼 수 있겠네. 히히


안녕하세요~ 타이젠 개발자 윤진입니다.


이번 주 토요일에 타이젠 행사가 있습니다.

"TIZEN DEVLAB @SEOUL"

타이젠 웹앱 / 네이티브앱을 개발하기 위한 방법을 이론 & 실습을 통해 공유할 예정입니다.


시간 : 2015. 8. 25(토) 10:00 ~ 18:00

장소 : 서울 서초구 나루터로 65 신사장 2층


'신사장' 이름에서 왠지 여인숙은 예상하셨다면 오해입니다.

위의 이미지는 신사장 홈피에서 가져왔는데요,

행사장소로 넓진 않지만 위의 사진처럼 세련되게 꾸며질겁니다.


DEVLAB 행사는 아래 스케쥴로 진행될 예정입니다.

총 7개 주제가 준비되어 있습니다.



13:45~14:30에 진행되는 "Native Application Life Cycle & Optimization"은 제가 진행할 예정입니다.

타이젠 앱의 Life Cycle을 하나씩 짚어보면서,

그 안에서 성능 & 메모리 최적화를 할 수 있는 포인트를 함께 고민해볼 생각입니다.

타이젠 앱을 실제로 만들 개발자들에게 도움이 되면 좋겠습니다. :)

다른 주제들도 개발자들에게 실질적인 도움이 될 수 있도록 준비하고 있습니다.


행사가 진행되는 장소가 협소하여,

사전등록은 이미 마감되어 많이 아쉽습니다.

만약 취소하는 사람이 생기면 추가로 등록을 받아준다고 하는데요,

관심있으신 분들은 결원을 노려보세요~


제가 발표할 자료는 차곡차곡 정리하고 있는데요,

외부로 오픈할 수 있는 부분을 추려서 차후에 다시 블로깅하도록 하겠습니다.


그럼 좋은 하루 보내세요~

끝_

edc를 이용하여 간단한 3D 효과를 줄 수 있습니다.

정밀하게 조절하기가 힘들어서 혹은 조절할 수가 없어서

정교한 효과와는 거리가 있습니다만,

지루한 2D 효과에 지쳤다면 한 번쯤 도전해볼 필요가 있습니다.


이번 포스팅에서는 원근효과를 주는 방법에 대해 살펴보겠습니다.



안녕하세요, Tizen 개발자 윤진입니다.


3D 효과를 적용하기 위해서는 map 블록을 사용해야 합니다.

collections - group - parts - part - description - map

위의 구조의 종단에 map 블록이 있습니다.

description 에에 있다는 것은 program으로 map의 상태를 변경하여 3D 효과를 줄 수 있다는 겁니다.


코드 상에서 map을 보면 아래와 같은 필드들과 사용됩니다.

description {
        ..
        map {
            perspective: "다른 파트이름";
            light: "이름";
            on: 1;
            smooth: 1;
            perspective_on: 1;
            backface_cull: 1;
            alpha: 1;
            rotation {
                ...
            }
        }
        ...
    }


위의 map 블록에서 사용한 필드-

perspective, light, on, smooth, perspective_on, backface_cull, alpha, rotate

우선 위의 필드 중 확대/축소와 관련된 필드인 perspective를 살펴보도록 하겠습니다.


- perspective: [다른 파트이름];

perspective 필드에는 현재 파트의 zplane을 정할때 참조하는 파트를 적어줍니다.

참조하는 파트의 zplane에 따라 현재 파트의 zplane도 확정됩니다.


그렇다면, zplane은 무엇일까요?

zplane은 2차원의 x축과 y축에 이은 3차원의 z축을 의미합니다.

zplane의 설정값에 따라 파트의 멀고 가까움이 결정됩니다.

zplane의 값이 커지면 파트가 가까워져서 커지고,

zplane의 값이 작아지면 파트가 점점 멀어져서 작아집니다.


위의 참조하는 파트는 아래와 같이 perspective 블록을 사용하여 zplane을 설정해야합니다.

       part {
         name: "zoom_out";
         type: RECT;
         description {
           state: "default" 0.0;
           perspective {
             zplane: -140;
           }
           visible: 0;
         }
       } 


perspective 필드에 사용할 파트는 화면에 보이지 않아도 됩니다.

따라서 color 필드를 사용하지 않았고,

visible을 '0'으로 설정하였습니다.

하지만, 영역만큼은 반드시 가지고 있어야 하기에 RECT 타입을 사용하였습니다.

(SPACER 타입도 사용하면 안됩니다)

rel1 / rel2를 사용하진 않았지만,

default로 rel1은 0.0으로 rel2는 1.0으로 설정되니 영역이 잡힌거나 다름없습니다.

perspective는 이 영역의 정가운데 점 하나만을 perspective 로 활용합니다.

zplane은 -140이니 이 파트에 perspective를 걸어둔다면 파트가 작아질 것입니다.


       part {
         name: "zoom_in";
         type: RECT;
         description {
           state: "default" 0.0;
           perspective {
             zplane: 140;
           }
           visible: 0;
         }
       }

위의 파트는 zplane이 140입니다.

perspective로 위의 파트를 걸어두면 파트는 더 커지게 됩니다.



- on: [0 or 1];

map 블록을 활성화(1) 혹은 비활성화(0) 시킵니다.

default가 비활성화이기 때문에 map 블록을 사용하려면 반드시 on: 1;을 해주어야 합니다.



perspective를 확인하기 위해서 우선 rectangle을 3개 만들어보겠습니다.

       part {
         name: "rect_1";
         type: RECT;
         description {
             state: "default" 0.0;
             rel1 { relative: 0.1 0.1; to: "bg"; }
             rel2 { relative: 0.2 0.2; to: "bg"; }
             color: 100 0 100 255;
             visible: 1;
           }
         }
         part {
           name: "rect_2";
           type: RECT;
           description {
             state: "default" 0.0;
             rel1 { relative: 0.2 0.2; to: "bg"; }
             rel2 { relative: 0.3 0.3;  to: "bg"; }
             color: 150 0 150 255;
             visible: 1;
           }
         }
         part {
           name: "rect_3";
           type: RECT;
           description {
             state: "default" 0.0;
             rel1 { relative: 0.3 0.3; to: "bg"; }
             rel2 { relative: 0.4 0.4; to: "bg"; }
             color: 200 0 200 255;
             visible: 1;
           }
         }


색상을 점차 밝은 색으로 변경하며 세 개의 사각형을 그렸습니다.

세 개의 사각형 모두 relative 0.1의 폭과 높이를 가지고 있습니다.

실제로는 아래와 같이 보이겠지요.



이번에는 사각형에 각각의 perspective를 적용합니다.

제일 상단의 사각형에는 -140의 zplane이 적용된 파트를 보게 하고,

제일 하단의 사각형은 140의 zplane이 적용된 파트를 보게합니다.

중간에 있는 사각형은 zplane이 없습니다.


그리고 zplane이 적용된 파트는 전체화면을 영역으로 가지도록 만들겠습니다.

전체영역을 가지고 있다고 하더라도,

실제 perspective가 되는 것은 영역의 정가운데에 점입니다.

정가운데 점이 perspective 관점이 되어서 다른 파트의 원근을 조정합니다.

영역으로는 원근법의 중심점을 정하고,

zplane으로는 원근을 정합니다.


collections {
   group {
     name: "main";
     parts {
       part {
         name: "bg";
         type: RECT;
         description {
           state: "default" 0.0;
           color: 255 255 255 255;
           visible: 1;
         }
       }
       part {
         name: "zoom_out";
         type: RECT;
         description {
           state: "default" 0.0;
           perspective {
             zplane: -140;
           }
           visible: 0;
         }
       } 
       part {
         name: "zoom_in";
         type: RECT;
         description {
           state: "default" 0.0;
           perspective {
             zplane: 140;
           }
           visible: 0;
         }
       }
       part {
         name: "rect_1";
         type: RECT;
         description {
             state: "default" 0.0;
             rel1 { relative: 0.1 0.1; to: "bg"; }
             rel2 { relative: 0.2 0.2; to: "bg"; }
             color: 100 0 100 255;
             visible: 1;
             map {
               perspective: "zoom_out";
               on: 1;
             }
           }
         }
         part {
           name: "rect_2";
           type: RECT;
           description {
             state: "default" 0.0;
             rel1 { relative: 0.2 0.2; to: "bg"; }
             rel2 { relative: 0.3 0.3;  to: "bg"; }
             color: 150 0 150 255;
             visible: 1;
           }
         }
         part {
           name: "rect_3";
           type: RECT;
           description {
             state: "default" 0.0;
             rel1 { relative: 0.3 0.3; to: "bg"; }
             rel2 { relative: 0.4 0.4; to: "bg"; }
             color: 200 0 200 255;
             visible: 1;
             map {
               perspective: "zoom_in";
               on: 1;
             }
           }
         }
     }
  }
}


rect1 파트는 가운데 점에서 봤을때,

zplane이 -140이 되어 더 작아집니다.

더 작아지지만 원래 있던 위치보다 가운데 쪽으로 '많이' 다가오게 됩니다.

이는 소실점이 있는 원근법을 생각하시면 될 겁니다.

1m가 떨어진 두 물체를 가까이에서 보면 1m의 거리만큼으로 보이겠지만,

먼 거리에서 보면 1cm로 보일 수도 있겠죠.

물체가 멀어지면 멀어질수록 가운데로 다가오게 됩니다.


rect3 파트는 가운데 점에서 봤을때,

zplane이 140이 되어서 더 커집니다.

더 커지지만 원래 있던 위치보다 가운데 쪽에서 '조금' 멀어지게 됩니다.

완전히 가운데 있지 않는 한,

눈에 가까이 올수록 가운데에서 멀어지게 되는 것이지요.


종합하자면 아래 그림처럼,

rect1은 작아지고 rect2쪽으로 다가옵니다.

rect3는 커지면서 rect2로 멀어집니다.



오늘은 perspective에 대해서 알아보았습니다.

그럼 좋은 하루 보내세요~

끝_



Swallow 타입을 이용하여,

C에서 생성한 오브젝트를 edc에 넣을 수 있습니다.

사실 edc에서 사용하는 모든 타입은 C에서도 그대로 만들 수 있습니다.

이 말은 굳이 edc를 사용하지 않아도 C로만 화면 구성을 할 수 있다는 것이지요.


하지만, edc는 레이아웃에 특화 되어 있습니다.

화면 구성을 edc 빼고 논할 수는 없지요.

그래서 edc에서는 화면 구성을 하고,

나머지 필수 요소는 Swallow 타입을 이용하여,

C에서 코딩하곤 합니다.



안녕하세요, Tizen 개발자 윤진입니다.


SWALLOW는 파트의 기본적인 타입 중에 하나입니다.

C에서 생성한 오브젝트를 edc의 SWALLOW에 넣을 수 있습니다.


collections - group - part { ... type: SWALLOW ... }


SWALLOW 파트로만 이뤄진 그룹을 하나 보겠습니다.

repo. : git://review.tizen.org/framework/uifw/elementary

branch : tizen_2.3

source : data/themes/widgets/conformant.edc


group { name: "elm/conformant/base/default";
   parts {
      part { name: "elm.swallow.indicator";
         type: SWALLOW;
         description { state: "default" 0.0;
            fixed: 0 1;
            align: 0.0 0.0;
            rel2.relative: 1.0 0.0;
         }
      }
      part { name: "elm.swallow.content";
         type: SWALLOW;
         description { state: "default" 0.0;
            fixed: 0 1;
            align: 0.5 0.5;
            rel1.relative: 0.0 1.0;
            rel1.to_y: "elm.swallow.indicator";
            rel2.relative: 1.0 0.0;
            rel2.to_y: "elm.swallow.clipboard";
         }
      }
      part { name: "elm.swallow.clipboard";
         type: SWALLOW;
         description { state: "default" 0.0;
            fixed: 0 1;
            align: 0.0 1.0;
            rel1.relative: 0.0 0.0;
            rel1.to_y: "elm.swallow.virtualkeypad";
            rel2.relative: 1.0 0.0;
            rel2.to_y: "elm.swallow.virtualkeypad";
         }
      }
      part { name: "elm.swallow.virtualkeypad";
         type: SWALLOW;
         description { state: "default" 0.0;
            fixed: 0 1;
            align: 0.0 1.0;
            rel1.relative: 0.0 0.0;
            rel1.to_y: "elm.swallow.softkey";
            rel2.relative: 1.0 0.0;
            rel2.to_y: "elm.swallow.softkey";
         }
      }
      part { name: "elm.swallow.softkey";
         type: SWALLOW;
         description { state: "default" 0.0;
            fixed: 0 1;
            align: 0.0 1.0;
            rel1.relative: 0.0 1.0;
         }
      }
   }
}


위의 소스에 SWALLOW 타입을 사용할 때 주의해야하는 점이 있습니다.

우선, rel1 / rel2에서 영역을 제대로 잡아주지 않고 있는 것을 기억하세요.

위의 rel1 / rel2는 '면'으로 영역을 확정하지 않고 '점'이나 '선'이 되도록 설정하고 있습니다.

'점'이나 '선'은 크기가 없지요.


그렇다면 크기는 어디서 설정해주고 있는 것일까요?

위의 edc 파일에서는 min이 전혀 보이지 않으므로 c 파일에서 min을 설정해주었다고 유추할 수 있습니다.

C에서 evas_object_size_hint_min_set() 함수로 영역의 최소값을 정하였겠지요.

C 파일단에서 크기를 확정하고 Swallow 영역에 대입한다는 사실에 주목해야 합니다.


fixed가 사용되고 있는 점도 주의하세요.

(fixed와 관련해서는 이 포스트를 참고해주세요.)

c에서 설정한 min값으로 부모 영역의 크기에 영향을 주지 않기 위해서 fixed를 사용했습니다.


어쨌든 SWALLOW 파트에 오브젝트를 넣을거면, SWALLOW 파트는 fixed 처리하는게 좋습니다.

fixed를 1로 처리 하여 SWALLOW 파트의 크기에 직접적으로 영향을 미치지 못하게 하지요.


물론, c 파일에서 설정한 min값이 SWALLOW 타입의 파트에도 적용이 되어야 한다면,

fixed를 1로 처리해서는 안됩니다.

fixed: 0 0;과 같은 방식으로 설정하면 됩니다.


SWALLOW 파트 중에 "elm.swallow.indicator" 파트에 들어가는 부분을 C에서 발췌하였습니다.

SWALLOW에 넣을 오브젝트를 생성(_create_xxxx_indicator())하고,

elm_layout_content_set()을 사용하여 레이아웃 내에 위치하는 SWALLOW 파트에 넣고 있네요.


   if (indmode == ELM_WIN_INDICATOR_SHOW)
     {
        old_indi = elm_layout_content_get(conformant, INDICATOR_PART);

        //create new indicator
        if (!old_indi)
          {
             if ((sd->rot == 90)||(sd->rot == 270))
               {
                  if (!sd->landscape_indicator)
                    sd->landscape_indicator = _create_landscape_indicator(conformant);

                  if (!sd->landscape_indicator) return;

                  evas_object_show(sd->landscape_indicator);
                  elm_layout_content_set(conformant, INDICATOR_PART, sd->landscape_indicator);
               }
             else
               {
                  if (!sd->portrait_indicator)
                    sd->portrait_indicator = _create_portrait_indicator(conformant);

                  if (!sd->portrait_indicator) return;

                  evas_object_show(sd->portrait_indicator);
                  elm_layout_content_set(conformant, INDICATOR_PART, sd->portrait_indicator);
               }

          }
        elm_object_signal_emit(conformant, "elm,state,indicator,show", "elm");


C에서는 오브젝트를 만들고,

elm_layout_content_set()을 이용하여 SWALLOW 영역에 넣어줍니다.

오브젝트를 만들고 사이즈를 관리하는 법에 대해서는 차후에 다시 설명하겠습니다.


SWALLOW 파트를 만들고,

거기에 넣을 오브젝트를 C파일에서 만들어 간단하게나마 연동해 보았습니다.


오늘은 여기까지 하겠습니다.

그럼 좋은 하루 보내세요~

끝_


edc에 유려한 디자인을 입하기 위해서는 이미지가 필수입니다.

아무래도 기본 도형이나 텍스트만으로는 한계가 있겠지요.


이번 포스팅에서는 IMAGE 타입에 대해 살펴보도록 하겠습니다.

이미지 파트를 사용하여 이미지를 원하는대로 배치해보도록 하겠습니다.

이미지는 미리 준비해주세요.



안녕하세요, Tizen 개발자 윤진입니다.


이미지 타입의 파트를 사용하려면 이미지가 있어야겠지요.

이미지는 edc 파일과 하나가 되어 edj 파일을 만듭니다.

edc 내에서 확정하여 사용하는 이미지 파일은 edj로 컴파일될 때 합쳐질 수 있습니다.


블로깅을 하며 edc에서 edj로 컴파일되는 과정을 언급한 적이 없었는데요,

아주 간단하게 언급하자면,

edc는 텍스트 기반의 스크팁트이므로 edj라는 기계가 인지할 수 있는 언어로 컴파일해야하죠.

이 때 edj에는 edc에서 언급한 이미지 파일을 내재할 수 있습니다.

그 때 사용하는 블록이 images 블록입니다.



- images {}

collections와 동일한 레벨로 사용하는 images 블록이 있습니다.

이 블록에서 edj에 포함될 이미지들을 확정하지요.

edje_cc는 컴파일을 진행하며 images 블록을 참고하여 edj와 이미지들이 한 몸이 됩니다.

images 블록에는 image 필드를 넣을 수 있습니다.



- image: [이미지파일] [압축방법] [압축레벨];

이미지 필드에는 이미지파일과 압축방법이 명시됩니다.

이미지 파일은 절대경로/상대경로 어느 방식으로나 적어둘 수 있습니다.

여기에 명시한 경로값을 이미지 파트에서 그대로 사용하면 됩니다.


압축방법으로는 RAW, COMP, LOSSY[0~100], USER를 사용할 수 있습니다.

RAW는 날 것 그대로 사용하는 경우,

COMP는 무손실 압축으로 이미지를 사용하고,

LOSSY는 압축레벨과 함께 이미지를 손실 압축하고,

USER는 edj에 이미지를 포함하지 않습니다.


edc에서 이미지 파트를 사용하기 위한 준비가 완료되었습니다.

이제 이미지를 사용하기 위해,

파트의 타입을 IMAGE로 설정해봅시다.

그리고 세부 설정을 위해 part - description 내에 image 블록을 사용합니다.



- image {}

이미지 블록에는 여러 필드를 사용할 수 있습니다.

normal, tween, border, middle, border_scale, border_scale_by

위의 인자 정도만 익혀도 이미지를 사용하는데 무리가 없습니다.



- normal: "파일이름";

normal 상태에서 사용하는 이미지의 파일이름을 지정합니다.

파일은 절대경로 혹은 상대경로로 지정할 수 있습니다.

만약 edc 파일과 이미지 파일이 같은 위치에 있다면 경로를 써줄 필요가 없겠지요.


이미지 파트에 다수의 이미지를 설정할 수 있습니다.

2개 이상의 이미지가 설정된다면 애니메이션으로 동작하게 됩니다.

이때 normal로 설정하는 이미지가 시작/끝 프레임이 됩니다.

normal이 시작/끝 두 개의 역할을 하기 때문에 뭔가 어색한 애니메이션이 될 수도 있습니다.

차라리 normal을 시작으로 제한하고,

마지막 frame은 다른 이름으로 하는게 더 명확했을 거라 생각이 듭니다.



- tween: "파일이름";

tween에는 애니메이션에서 시작/끝 프레임을 제외한 다른 프레임을 설정합니다.

tween은 몇 개를 사용해도 상관없으며,

tween으로 입력하는 순서대로 애니메이션이 재생됩니다.

각각의 이미지가 재생되는 시간은 program을 이용하여 조절할 수 있습니다.

그 부분은 차후에 program을 설명하며 자세히 살펴보겠습니다.



- border: [왼쪽] [오른쪽] [위] [아래];

border에는 4가지 값을 입력합니다.

단위는 픽셀로써 이미지의 왼쪽/오른쪽/위/아래의 가장자리영역을 지정합니다.

이미지가 스케일에 따라 확대/축소된다고 하더라도,

위에 지정된 가장자리는 왜곡없이 표시됩니다.


라운드 형의 버튼 이미지를 사용하는 경우,

가로 혹은 세로가 상대적으로 더 길어지면 라운드 형태가 왜곡될 수 있습니다.

이를 막히 위해 border를 사용하여 가장자리 형태를 유지합니다.


border가 좌우만 설정되어 있다면,

이미지는 좌우로 확대가 가능합니다.

border가 상하로만 설정되어 있다면,

이미지는 상하로 확대가 가능할테지요.

border가 상하좌우로 모두 설정되어 있다면,

border는 9개 영역으로 나뉘게 됩니다.

이 중 좌상/좌하/우상/우하 영역만 고정 되고 다른 영역은 유동적으로 변합니다.



- middle: [0/1/NONE/DEFAULT/SOLID];

border가 설정되어 있을때 사용합니다.

border로 설정된 영역 외에 나머지 영역은 middle이지요.

0이나 NONE을 지정하면 middle 영역이 보이지 않습니다.

1이나 DEFAULT 혹은 SOLID로 지정하면 middle 영역이 보이지요.

아래 예시를 보면, middle에 대한 개념이 확실하게 잡히실 겁니다.


images {
  image: "btn.png" COMP;
}

collections {
   group {
     name: "main";
     parts {

       part {
         name: "bg";
         type: RECT;
         description {
           state: "default" 0.0;
           color: 255 255 255 255;
           visible: 1;
         }
       }

       part {
         name: "example";
         type: IMAGE;
         description {
           state: "default" 0.0;
           image {
             normal: "btn.png";
           }
           rel1.relative: 0.5 0.1;
           rel1.to: "bg";
           rel2.relative: 0.5 0.1;
           rel2.to: "bg";
           min: 61 56;
         }
       }

       part {
         name: "border_example";
         type: IMAGE;
         description {
           state: "default" 0.0;
           image {
             normal: "btn.png";
             border: 20 20 20 20;
           }
           rel1.relative: 0.5 0.3;
           rel1.to: "bg";
           rel2.relative: 0.5 0.3;
           rel2.to: "bg";
           min: 122 56;
         }
       }

       part {
         name: "middle_0_example";
         type: IMAGE;
         description {
           state: "default" 0.0;
           image {
             normal: "btn.png";
             border: 20 20 20 20;
             middle: 0;
           }
           rel1.relative: 0.5 0.5;
           rel1.to: "bg";
           rel2.relative: 0.5 0.5;
           rel2.to: "bg";
           min: 122 56;
         }
       }

       part {
         name: "middle_1_example";
         type: IMAGE;
         description {
           state: "default" 0.0;
           image {
             normal: "btn.png";
             border: 20 20 20 20;
             middle: 1;
           }
           rel1.relative: 0.5 0.7;
           rel1.to: "bg";
           rel2.relative: 0.5 0.7;
           rel2.to: "bg";
           min: 122 56;
         }
       }

       part {
         name: "middle_none_example";
         type: IMAGE;
         description {
           state: "default" 0.0;
           image {
             normal: "btn.png";
             border: 20 20 20 20;
             middle: DEFAULT;
           }
           rel1.relative: 0.5 0.9;
           rel1.to: "bg";
           rel2.relative: 0.5 0.9;
           rel2.to: "bg";
           min: 122 56;
         }
       }

     }
   }
}



- border_scale: [0 혹은 1];

border도 scale factor의 영향을 받을 수 있게 합니다.

scale에 대해선 이전 포스팅에서 언급한 바 있습니다.

화면 해상도가 바뀔 경우 스케일 팩터가 바뀔텐데요,

그에 맞춰 border에서 지정해둔 픽셀값에 스케일 팩터가 곱해져서 적용됩니다.



- border_scale_by: [0.0~];

border_scale을 enable할 때만 의미가 있는 필드입니다.

border 영역에 적용되는 스케일 팩터를 따로 설정할 수 있습니다.

border_scale_by로 설정한 스케일 값에 스케일 팩터를 곱한 값이 최종 적용됩니다.

스케일팩터가 2.0이고 border_scale_by가 0.5라면,

다른 scale 영역들이 2.0배씩 늘어날때,

border 영역은 2.0 x 0.5로 곱해져서 1.0으로(그대로) 보여지게 됩니다.



이미지에 대한 설명은 여기까지 하겠습니다.

그럼 좋은 하루 보내세요~

끝_

  1. Tizen Develer 2015.11.25 10:49

    상세한 설명 감사합니다 : )

edc파일로 문자열을 출력할 수도 있습니다.

문자열은 edc 파일에서 직접 입력할 수도 있고,

C파일에서 elm_object_part_text_set() 함수를 사용하여,

필요할 때마다 문자열을 입력할 수 있습니다.


문자열이 전혀 없는 앱은 거의 없을 겁니다.

복잡다단한 문자표현의 세계에 첫 발을 text 블록으로 내딛어 보겠습니다.



안녕하세요, Tizen 개발자 윤진입니다.


edc에 문자열을 지원하는 타입은 2가지가 있습니다.

- TEXT

- TEXTBLOCK

위의 두 가지 중에 TEXT 타입을 먼저 살펴보겠습니다.

TEXT는 TEXTBLOCK에 비하여 간단한 문자열을 표시하는데 사용하지요.

TEXT 타입이 TEXTBLOCK 타입에 비해 multiline이라든가 기능에는 제한은 있지만,

간단한 연산만 필요하기에 훨씬 빠릅니다.



- text {}

텍스트 파트에는 텍스트에 대한 추가정보를 기술하기 위한 text 블록이 필요합니다.

text {}는 part - description 내에 위치하지요.

description에 위치한다는 것은,

각 상태(state)에 따라 text의 설정값을 변경할 수 있다는 것이겠죠.

곧, program으로 텍스트의 모양새를 여러가지로 바꿀 수 있습니다.



- text: "문자열";

text 블록 내에 블록과 동일한 이름의 필드인 text를 사용할 수 있습니다.

text 필드에 명시한 문자열은 default로 사용되는 문자열입니다.

default는 외부에서 해당 텍스트 파트에 아무 것도 set하지 않으면 나타납니다.

edc에서 문자열을 확정할 수 있다면 text 필드를 사용하면 됩니다.



- font: "폰트명";

텍스트에 폰트를 지정할 수 있습니다.

font를 지정하려면 플랫폼에서 지정한 값을 넣어줘야 하겠지요.

"Sans"나 "Arial"과 같은 글꼴 이름을 적어주면 됩니다.

물론 해당 글꼴이 플랫폼에 탑재가 되어 있어야겠지요?



- size: [폰트사이즈];

폰트 사이즈를 입력할 수 있습니다.

양수를 적어넣으면 됩니다.



- align: [x축, 0.0~1.0] [y축, 0.0~1.0];

텍스트 파트에서 정렬을 하기 위해서 align을 사용합니다.

두 개의 인자를 적어주면 되는데 각각 x축/y축 기준입니다.

텍스트 파트에서 rel1/rel2로 지정한 파트의 영역 내에서,

텍스트의 배열을 어떻게 설정할지를 align으로 정하게 됩니다.


collections {
   group {
     name: "main";
   parts {
      part {
         name: "label";
         type: TEXT;
         scale: 1;
         description {
            state: "default" 0.0;
            color: 255 0 0 255;
            text {
               text: "TEXT";
               font: "Sans";
               size: 24;
               align: 0.5 0.5;
            }
         }
      }
   }
}

위의 코드에서는 화면 한가운데에 "TEXT"라는 문자열을 표시하지요.

폰트는 "Sans"이고 폰트사이즈는 24입니다.




- effect: [EFFECT];

폰트에 이펙트를 추가할 수 있습니다.

effect 필드는 description이 아닌 part에 넣어주어야 합니다.

그 말은 state에 따라 effect를 바꿀 수 없다는 것이겠지요.

이펙트는 종류가 많아보이긴 하지만 따지고 보면 윤곽선, 그림자로 귀결됩니다


•    PLAIN : effect가 없습니다.
•    OUTLINE  : 윤곽선
•    SOFT_OUTLINE : 부드러운 윤곽선
•    SHADOW : 그림자
•    SOFT_SHADOW : 부드러운 그림자
•    OUTLINE_SHADOW : 윤곽선 + 그림자
•    OUTLINE_SOFT_SHADOW : 윤곽선 + 부드러운 그림자
•    FAR_SHADOW : 멀리 떨어진 그림자
•    FAR_SOFT_SHADOW : 멀리 떨어진 부드러운 그림자
•    GLOW : 발광윤곽선


눈으로 직접 보는게 이해가 빠르겠네요.

아래처럼 9개의 이펙트를 위한 그룹을 만들어보겠습니다.


예시에 보면 color3가 쓰였는데요,

color3는 윤곽선이나 그림자 색상을 의미합니다.

color3는 color와 함께 description에 쓰이므로 state에 따라 바꿀 수 있습니다.


collections {
   group {
     name: "main";
     parts {
       part {
         name: "bg";
         type: RECT;
         description {
           state: "default" 0.0;
           color: 255 255 255 255;
         }
       }

       part {
         name: "PLAIN";
         type: TEXT;
         effect: PLAIN;
         description {
           state: "default" 0.0;
           color: 255 0 255 255;
           text {
             text: "PLAIN EFFECT";
             font: "Sans";
             size: 20;
             align: 0.5 0.0;
            }
         }
      }
     
      part {
         name: "OUTLINE";
         type: TEXT;
         effect: OUTLINE;
         description {
           state: "default" 0.0;
           color: 255 0 255 255;
           color3: 0 0 0 255;
           text {
              text: "OUTLINE EFFECT";
              font: "Sans";
              size: 20;
              align: 0.5 0.1;
            }
         }
      }
       part {
         name: "SOFT_OUTLINE";
         type: TEXT;
         effect: SOFT_OUTLINE;
         description {
           state: "default" 0.0;
           color: 255 0 255 255;
           color3: 0 0 0 255;
           text {
              text: "SOFT_OUTLINE EFFECT";
              font: "Sans";
              size: 20;
              align: 0.5 0.2;
            }
         }
      }
 
      part {
         name: "SHADOW";
         type: TEXT;
         effect: SHADOW;
         description {
           state: "default" 0.0;
           color: 255 0 255 255;
           color3: 0 0 0 255;
            text {
               text: "SHADOW EFFECT";
               font: "Sans";
               size: 20;
               align: 0.5 0.3;
            }
         }
      }
     
      part {
         name: "SOFT_SHADOW";
         type: TEXT;
         effect: SOFT_SHADOW;
         description {
           state: "default" 0.0;
           color: 255 0 255 255;
           color3: 0 0 0 255;
            text {
               text: "SOFT_SHADOW EFFECT";
               font: "Sans";
               size: 20;
               align: 0.5 0.4;
            }
         }
      }
 
      part {
         name: "OUTLINE_SHADOW";
         type: TEXT;
         effect: OUTLINE_SHADOW;
         description {
           state: "default" 0.0;
           color: 255 0 255 255;
           color3: 0 0 0 255;
            text {
               text: "OUTLINE_SHADOW EFFECT";
               font: "Sans";
               size: 20;
               align: 0.5 0.5;
            }
         }
      }
 
      part {
         name: "OUTLINE_SOFT_SHADOW";
         type: TEXT;
         effect: OUTLINE_SOFT_SHADOW;
         description {
           state: "default" 0.0;
           color: 255 0 255 255;
           color3: 0 0 0 255;
           text {
               text: "OUTLINE_SOFT_SHADOW EFFECT";
               font: "Sans";
               size: 20;
               align: 0.5 0.6;
            }
         }
      }
 
      part {
         name: "FAR_SHADOW";
         type: TEXT;
         effect: FAR_SHADOW;
         description {
           state: "default" 0.0;
           color: 255 0 255 255;
           color3: 0 0 0 255;
            text {
               text: "FAR_SHADOW EFFECT";
               font: "Sans";
               size: 20;
               align: 0.5 0.7;
            }
         }
      }
 
      part {
         name: "FAR_SOFT_SHADOW";
         type: TEXT;
         effect: FAR_SOFT_SHADOW;
         description {
            state: "default" 0.0;
            color: 255 0 255 255;
            color3: 0 0 0 255;
            text {
               text: "FAR_SOFT_SHADOW EFFECT";
               font: "Sans";
               size: 20;
               align: 0.5 0.8;
            }
         }
      }
 
      part {
         name: "GLOW";
         type: TEXT;
         effect: GLOW;
         description {
           state: "default" 0.0;
           color: 255 0 255 255;
           color3: 0 0 0 255;
            text {
               text: "GLOW EFFECT";
               font: "Sans";
              size: 20;
               align: 0.5 0.9;
            }
         }
      }
   }
}



오늘은 여기까지 하겠습니다.

그럼 좋은 하루 보내세요~

끝_

 
 
 
 

  1. YOhoho 2015.11.23 14:58

    color2는 윤곽선
    color3는 그림자 색상이군요

    • 안녕하세요, YOhoho님. 또 오셨군요. 감사합니다 :) 컬러 뒤에 붙는 숫자가 커질수록 텍스트에서 멀어지죠~ 근데 솔직히 필드이름에 숫자가 들어간게 맞는지는 모르겠네요 :)

오늘은 파트의 상태를 적어놓는 description에서,

가장 중요한 필드 중에 하나인 rel을 살펴보도록 하겠습니다.


rel은 파트의 위치와 크기를 관장하는 필드입니다.

형태를 가지고 있는 물체에는 위치와 크기 속성이 필수인만큼,

이 필드는 꼼꼼이 잘 살펴볼 필요가 있습니다.



안녕하세요, Tizen 개발자 윤진입니다.


rel 필드는,

collections - group - parts - part - description 아래에 위치하는 필드입니다.

description 안에 있다는 것만으로도,

rel 필드는 state에 따라 변화가 가능한 필드라는 것을 알 수 있습니다.


rel은 2개의 필드가 하나의 쌍으로 동작합니다.

rel1과 rel2가 각각 시작점, 끝점의 역할을 담당하게 되지요.

이 두 점으로 사각의 영역을 얻을 수 있습니다.

part는 이 두 점으로 기준으로 위치와 크기가 결정됩니다.



- rel1/rel2 

rel1과 rel2는 각각의 블록을 가지고 있습니다.

rel1 { ... }

rel2 { ... }

위와 같이 독립된 블록을 가집니다.

이름만 봐서는 rel3, rel4가 있어도 이상해보이진 않지만,

직사각형 영역으로 형태를 표현하는 것이 충분하다고 여기는지 2개의 필드만 사용하고 있습니다.

정말 그러한지는 각자 좀 더 고민해보시죠.


rel1은 왼쪽 상단 모서리를 의미합니다.

rel2는 오른쪽 하단 모서리를 의미하지요.

이 두 점만으로 직사각형을 표현할 수 있습니다.

rel1과 rel2 블록 안에 명시한 내용이 각각 모서리 위치를 구체화 합니다.



- relative: [X축] [Y축];

rel 블록에서 가장 먼저 등장하는 것이 relative입니다.

relative는 상대적인 위치를 나타냅니다.

화면에 표시되는 영역은 0.0 ~ 1.0 범위입니다.

x축/y축 기준으로 비율에 맞게 화면에 표시가 됩니다.


collections {
  group {
    name: "storycompiler";
    parts {
      part {
        name: "red_rectangle";
        type: RECT;
        description {
          state: "default" 0.0;
          rel1.relative: 0.0 0.5;
          rel2.relative: 1.0 1.0;
          color: 255 0 0 255;
          visible: 1;
        }
      }
    }
  }
}


rel1에 0.0 0.5를 적어놓으면,

시작점은 X축 기준으로는 0이고, y축 기준으로는 가운데입니다.

rel2에 1.0 1.0을 적어놓으면,

끝점은 x축/y축 모두 마지막 좌표입니다.

위의 코드를 출력한 결과는 아래와 같습니다.



0.0 이하 혹은 1.0 이상 영역은 화면 밖에 표시가 됩니다.

화면 밖에서 화면 안으로 들어오는 애니메이션 효과를 주고 싶을때,

-1.0 이나 2.0 과 같은 수치를 써주곤 합니다.


rel1과 rel2에 같은 값을 표기할 수도 있습니다.

시작점과 끝점이 같은 값이라면 결과는 '점'입니다.

점은 화면에 표시가 되지 않습니다.


그렇다면 왜 점을 사용하는 것일까요?

점은 min값과 좋은 짝이 됩니다.

점과 min을 함께 사용한다면,

점은 위치를 나타내고,

min이 크기를 지정하게 될 겁니다.

(min값과 관련된 내용은 이 포스팅을 참고해주세요)


만약 시작점과 끝점을 달리하여 영역을 만들고 추가로 min값을 넣는 경우,

논리적 모순이 생길 수도 있습니다.

rel1/rel2는 비율로 크기를 지정하는데,

그 크기가 min값과 다를 수 있기 때문입니다.


예를 들어, 화면의 사이즈가 100 x 100이고,

rel1은 0.0 0.0, rel2는 0.1 0.1으로 지정했다고 하죠.

rel로 잡은 영역은 10 x 10의 크기입니다.

하지만, 거기에 min값으로 50 50을 주면,

어떤 값을 선택해야할지 알 수가 없게됩니다.

10 10일까요? 50 50일까요?


바로 이 점이 edc를 어렵게 만드는 점이기도 한데요,

하나의 필드에 두 개의 역할(위치, 크기)를 부여하였기 때문에,

크기를 나타내는 min과 충돌이 날 수 있습니다.

따라서 min으로 크기를 설정하고자 하면,

반드시 rel로는 점을 만드시는게 좋습니다.



- to: [다른 파트 이름];

to는 굉장히 유용하게 사용되는 필드입니다.

위에서 rel1/rel2로 위치를 잡을때 화면 전체를 기준으로 설명하였는데요,

to 필드를 추가하면, to 필드에 명시한 파트를 기준으로 rel1 / rel2가 지정됩니다.

반대로 to 필드가 없으면 전체화면을 기준으로 위치를 잡게 되겠지요.


collections {
   group {
      name: "to_example";
 
      parts {
         part {
            name: "bg";
            type: RECT;
            scale: 1;
            description {
               state: "default" 0.0;
               rel1.relative: 0.0 0.0;
               rel2.relative: 1.0 1.0;
            }
         }
         part {
            name: "region";
            type: RECT;
            scale: 1;
            description {
               state: "default" 0.0;
               color: 255 0 0 255;
               rel1.relative: 0.2 0.2;
               rel1.to:"bg";
               rel2.relative:0.8 0.8;
               rel2.to:"bg";
            }
         }
      }
   }
}



- to_x: [다른 파트 이름];

- to_y: [다른 파트 이름];

위에서 설명한 to는 to_x와 to_y가 동일한 경우에 사용합니다.

만약 x축 기준영역과 y축 기준영역이 다를 경우,

to_x와 to_y를 사용하면 됩니다.

파트의 위치가 반드시 한 파트를 기준으로 정해야한다는 규칙은 없습니다.

서로 다른 두 개의 파트를 각각 x축 기준 y축 기준으로 사용하면 됩니다.


group {
      parts {
         part {
            name: "to_part";
            type: RECT;
            scale: 1;
            description {
               state: "default" 0.0;
               color: 255 0 0 255;
               rel1.relative: 0.2 0.2;
               rel1.to:"bg";
               rel2.relative:0.8 0.8;
               rel2.to_x: "some_part";
               rel2.to_y: "other_part";
               }             }          }       }    }


위의 코드에서 시작점은 bg를 기준으로 설정되었지만,

끝점의 x축은 some_part를 기준으로,

y축은 other_part를 기준으로 위치를 잡습니다.

 

- offset: [x축] [y축];

offset은 음수, 0, 양수를 사용할 수 있습니다.

단위는 픽셀입니다.

여기서 사용하는 값은 relative와 to로 결정된 위치에 마지막 수정을 가합니다.

보통 미세한 조정이 필요한 경우에 사용합니다.


offset에 적용되는 값은 이전에 설명한 scale과는 무관하게 동작합니다.

scale이 1로 설정되어 있더라도,

offset에 설정한 값은 적힌 값 그대로 사용됩니다.


보통 선을 만들거나 1~2픽셀 단위로 영역을 조정할 때 사용합니다.

-100 이나 100 픽셀로 offset를 주진 않습니다.

저 정도 크기로 영역을 조정하려면 relative를 사용하는 것이 맞습니다.


collections {
   group {
      parts {
         part {
            name: "part_three";
            type: RECT;
            scale: 1;
            description {
               state: "default" 0.0;
               color: 255 0 0 255;
               rel1 {
                  relative: 0.0 0.0;
                  to:"some_part";
                  offset: 1 -1;
               }
               rel2 {
                  relative:0.0 1.0;
                  to:"other_part";
                  offset: 1 -1;
               }
            }
         }
      }
   } 


위치에 대한 이야기는 여기서 마치겠습니다.

그럼 좋은 하루 보내세요~

끝_

  1. Tizen Develer 2015.11.23 17:10

    상세한 설명 감사드립니다ㅎㅎ 초보 개발자인데 이렇게 상세하게 설명되어 있는 블로그는 처음봐요!!
    열심히 보고 배우겠습니다~

part 블록을 처음 접했을때,

description 블록의 역할이 와닿지 않았습니다.

part 블록에 바로 넣어도 될만한 필드들을 굳이 description으로 감싸기 때문이죠.


하지만, program이 description 단위로 동작한다는 것을 본 이후에는,

description 파트도 치열한 고민의 산물이란 것을 깨달았습니다.



안녕하세요, Tizen 개발자 윤진입니다.


description 파트는 program에 의해 변할 수 있는 요소들을 넣어줍니다.

description에서 정의하는 모든 필드는 상태에 따라 변하는 필드라고 보시면 됩니다.

description의 필드값을 program으로 직접 변경하진 않고,

한 part 내에 위치한 다수의 description 사이에서 상태변환을 하게 되지요.


따라서 description의 이름은 name이라 부르지 않고 state라고 합니다.

part의 확정된 설정값이 아닌,

유동적으로 변모하는 상태를 나타내기 때문입니다.


우선 description에서 다루는 필드르 아래 코드에서 훑어보겠습니다.

description {
   state: "description_name" INDEX;
   inherit: "other_description_name" INDEX;
   visible: 1;
   align: 0.5 0.5;
   min: 0 0;
   max: -1 -1;
   fixed: 0 0;
   rel1 { ... }
   rel2 { ... }
   step: 0 0;
   aspect: 1 1;
}

위에 언급된 필드 중에 rel1, rel2는 다음 포스팅에서 살펴보도록 하겠습니다.

rel 블록 내에는 또 주요한 필드들이 있고 해당 필드에 대해서는 할 말이 좀 있어서요.

그 외의 필드는 하나씩 살펴보도록 하겠습니다.



- state: [이름] [인덱스];

state의 이름은 고유한 값이어야 합니다.

그리고 state 중 하나는 반드시 "default"여야만 합니다.

"default"는 파트가 load될 때 initial 상태이기 때문이지요.

그리고 인덱스는 0.0에서 1.0의 값으로 입력합니다.

인덱스가 있는 이유는 상태가 동일한 이름을 지닌다고 해도 인덱스로 구분지을 수 있기 때문이죠.

위에 언급한 "default"의 0.0 인덱스가 가장 기본이 되는 description입니다.



- inherit: [다른 description의 이름] [다른 description의 인덱스];

다른 description에서 설정한 필드를 그대로 가져올 수 있습니다.

inherit한 이후에 설정한 필드들은 inherit된 필드에 override됩니다.

inherit는 필드 한 두개만 다르고 나머지 필드는 모두 일치할 때 유용하게 사용됩니다.



- visible: [0 혹은 1];

화면에 보일지 감출지를 결정합니다.

0을 설정하면 해당 파트는 보여지지 않습니다.

1을 설정해야 비로소 화면에 보입니다.

화면에 보이지 않으면 이벤트도 그 파트에는 전달되지 않습니다.

원래부터 없는 셈치게 되죠.

default 값은 1입니다.

따로 적어주지 않으면 화면에 보이게 됩니다.



- align: [X축] [Y축];

align으로 X축 혹은 Y축 기준으로 정렬을 할 수 있습니다.

align을 지정하면 이 파트에 삽입되는 다른 요소의 정렬에 적용됩니다.

이 파트 자체가 다른 곳에 삽입될 때 적용되는 것이 아닙니다.

0.0 ~ 1.0의 값을 지정할 수 있습니다.

0.0은 왼편 정렬, 0.5는 가운데 정렬, 1.0은 오른편 정렬입니다.

double 형이니 만큼 0.25, 0.3 같은 값을 주어 애매한 정렬을 할 수도 있겠죠.

default 값은 X축, Y축 모두 가운데 정렬인 0.5 0.5입니다.



- min: [width] [height];

min 필드는 두 개의 값을 가지고 있습니다.

가로와 세로를 기준으로 파트의 min 사이즈를 지정할 수 있습니다.

min은 말 그대로 최소한의 크기입니다.

파트의 크기는 min에서 설정한 값으로 확정됩니다.

min 값은 relative로 설정한 값과 충돌을 일으킬 수 있기 때문에,

가급적이면 relative를 '점'으로 설정한 곳에 사용해야 합니다.

이에 대해선 relative를 설명할 때 다시 언급하도록 하겠습니다.



- max: [width] [height];

max 필드도 두 개의 값을 가지고 있습니다.

가로와 세로를 기준으로 파트의 max 사이즈를 지정할 수 있습니다.

max는 말 그대로 최대한의 크기입니다.

파트의 크기가 변하는 상황에서 참조하는 값입니다.

파트의 크기가 바로 max 값으로 지정되진 않지요.



- fixed: [가로, 0 or 1] [세로, 0 or 1];

fixed는 매우 중요한 필드입니다.

여기에 어떤 값을 주었느냐에 다라 다른 그룹에 지대한 영향을 미칠 수 있습니다.

인자는 2개인데 각각 가로와 세로를 의미합니다.

가로 혹은 세로를 기준으로 현재 파트의 min값의 영향력을 결정할 수 있습니다.


만약 fixed가 1이라면,

현재 파트의 min값은 현재 파트를 담고 있는 객체에 아무 영향을 주지 못합니다.

현재 파트를 담고 있는 객체의 크기가 현재 파트보다 작더라도,

현재 파트를 담을 수 있습니다.

'담다'는 용어보다는 붙여놓는다는 용어가 어울릴지도 모르겠다.


반대로 fixed가 0이라면,

현재 파트의 min값은 현재 파트를 담고 있는 객체에 영향을 줍니다.

현재 파트가 100 x 100이고 현재 파트를 담는 객체가 10 x 10인 경우,

부모 객체는 현재 파트의 min 값에 맞춰서 100 x 100이 됩니다.


따라서 fixed를 사용하려면 부모/자식 같의 크기를 잘 염두하여 사용해주세요.

특히 파트 사이즈가 변한다면 더욱 주의하셔야 합니다.

사이즈가 변하기 전에는 부모 파트의 크기가 제대로 잡혀있었는데,

자식의 사이즈가 변한 후에는 부모 파트도 같이 변해서 애초의 목적과 달라질 수 있습니다.



- step: [width] [height];

part를 resize하는 경우, step에 설정한 가로/세로 크기만큼의 단계로 확대/축소됩니다.

만약 step이 필요없다면 "0 0"으로 설정해두면 됩니다.

개인적으로 step을 사용해본 경험이 없어서 타이젠 소스를 뒤져보았습니다.

타이젠 플랫폼에서도 step을 사용한 예는 거의 없네요.


         part { name: "e.table.days"; type: TABLE;
            description { state: "default" 0.0;
               rel1.to_y: "e.table.daynames";
               rel1.relative: 0.0 1.0;
               rel1.offset: 2 2;
               rel2.offset: -3 -3;
               step: 7 5;
               table {
                  homogeneous: TABLE;
                  padding: 1 1;
                  align: 0.5 0.5;
                  min: 1 1;
               }
            }
         /* ... 생략 ... */


위처럼 TABLE을 만드는 경우 step을 사용하고 있습니다.

TABLE의 크기를 변경할 때 step에 명시된 크기 7, 5만큼 변경되겠지요.


위에서 7, 5인 이유는 캘린더를 위한 테이블이기에,

월화수목금토일을 담기 위한 7열에, 총 5주를 표기하기 위해서인 것으로 보입니다.

부모의 크기가 커지더라도 캘린더 테이블 파트는 7, 5 단위씩 커져기에,

모두가 균일한 크기를 유지할 수 있도록 합니다.



- aspect: [가로, 0 or 1] [세로, 0 or 1];

파트의 사이즈를 재조정하는 경우,

가로/세로의 사이즈가 일정 비율로 늘거나 줄어야 하는 경우가 있습니다.

이미지의 경우에는 특히 그러하지요.

그럴 때, aspect를 사용합니다.

가로/세로의 값으로 1로 주면, 이미지는 비율대로 크기가 조정됩니다.

가로/세로를 각각 1 혹은 0, 0 혹은 1로 설정하여 사용한 경우는 보지 못했습니다.

가로/세로 모두 1 아니면 0을 사용하지요.


- aspect_preference: [DIMENSION];

aspect_preference는 aspect와 함께 사용합니다.

값으로는 BOTH, VERTICAL, HORIZONTAL, NONE을 넣어줄 수 있습니다.

여기서 설정한 Dimension으로 비율이 결정됩니다.

보통의 이미지라면 BOTH로 해도 무방합니다.

세로를 기준으로 가로의 사이즈를 조절하고 싶다면 VERTICAL을,

가로를 기준으로 세로의 사이즈를 조절하고 싶다면 HORIZONTAL을,

그리고 따로 기준이 필요없다면 NONE으로 설정합니다.



- color: [Red] [Green] [Blue] [Alpha];

RGB와 Alpha 값을 설정할 수 있습니다.

RGB값으로 색상을 정하고 알파값으로 투명도를 정할 수 있습니다.

각 값은 0~255까지로 지정합니다.

숫자가 높아질수록 각각의 색상이 점차 뚜렷해집니다.

알파값의 경우 0이면 투명, 255에 가까울수록 불투명해집니다.



오늘은 여기까지 하겠습니다.

그럼 좋은 하루 보내세요~

끝_


part의 영역 중 일부만 노출해야하는 경우가 있습니다.

포토샵에 마스킹을 생각하시면 됩니다.

자신이 지정한 영역만 보이고 그 외의 영역은 아예 렌더링도 하지 않습니다.

바로 그러한 기능이 필요할 때 clip_to를 사용합니다.


clip이 자르다 혹은 깎다는 의미가 있는데요,

clip to로 지정한 영역 외에는 잘라버려서 보이지 않는다고 보면 됩니다.



안녕하세요, Tizen 개발자 윤진입니다.


clip_to: [another part's name];

clip_to는 파트블록 내에서 사용합니다.

필드값으로 다른 파트의 이름을 적어주어야 합니다.

현 파트의 영역 중 필드값으로 지정한 파트의 영역와 겹치는 부분만 렌더링하게 됩니다.


우선, 간단하게 이미지를 화면에 그려보도록 하겠습니다.

images {
  image: "bg.jpg" COMP;
}
collections {
  group {
    name: "storycompiler";
    parts {
      part {
        name: "bg";
        type: RECT;
        description {
          state: "default" 0.0;
          rel1.relative: 0.0 0.0;
          rel2.relative: 1.0 1.0;
          color: 0 0 0 255;
          visible: 1;
        }
      }
      part {
        name: "img";
        type: IMAGE;
        scale: 0;
        description {
          state: "default" 0.0;
          image.normal: "bg.jpg";
          rel1 { relative: 0.5 0.5; to: "bg"; }
          rel2 { relative: 0.5 0.5; to: "bg"; }
          min: 1145 425;
          fixed: 1 1;
          align: 0.5 0.5;
          visible: 1;
        }
      }
    }
  }
}


위의 코드에 있는 collections, group, parts, part 블록은 이미 지난 포스팅에서 설명을 드렸습니다.

image 타입에 대해서 아직 다루진 않았지만,

최소한의 기능만을 사용하였기에 코드만 봐도 이해에 어려움이 없으리라 생각합니다.


IMAGE 타입을 가진 img 파트는 bg 파트의 정중앙(0.5 0.5)에 위치하는 '점'입니다.

하지만, min값을 가지고 있기 때문에 min값만큼 영역이 늘어나게 됩니다.

그래서 나온 결과는 위의 캡쳐이미지와 같습니다.


코드에는 bg와 img 파트만 있는데요,

clip_to를 테스트하기 위하여 가운데 점으로부터 100 x 100짜리 사각형을 하나 만들어보겠습니다.


      part {
        name: "clip";
        type: RECT;
        description {
          state: "default" 0.0;
          rel1 { relative: 0.5 0.5; to: "bg"; }
          rel2 { relative: 0.5 0.5; to: "bg"; }
          color: 255 0 0 255;
          min: 100 100;
          align: 0.5 0.5;
          visible: 1;
        }
      }


위의 파트까지 포함하여 출력하면 아래 이미지를 볼 수 있습니다.

clip 사격형의 color는 RGBA 기준으로 255 0 0 0으로 붉게 두었습니다.


          color: 255 0 0 255;

자, 이제 clip_to를 위한 준비를 마쳤습니다.

img 파트에 clip_to 필드를 추가합니다.


      part {
        name: "img";
        type: IMAGE;
        scale: 0;
        clip_to: "clip";
        description {
          state: "default" 0.0;
          image.normal: "bg.jpg";
          rel1 { relative: 0.5 0.5; to: "bg"; }
          rel2 { relative: 0.5 0.5; to: "bg"; }
          min: 1145 425;
          fixed: 1 1;
          align: 0.5 0.5;
          visible: 1;
        }
      }


위처럼 한 줄 추가하면 굉장히 극적인 변화가 일어납니다.

clip 파트는 clip_to의 대상이 되기 때문에 img파트를 위한 '체'만 제공할 뿐입니다.

clip 파트가 '붉은색' 사각형이었기 때문에 '붉은 체'가 되겠지요.


img파트는 clip파트 영역만큼만 화면에 보이게 됩니다.

clip 파트가 '붉은 체'이기 때문에 붉게 물든 이미지가 보이겠네요.

그 외의 영역은 렌더링을 하지 않겠지요.

img보다 뒷편에 있는 bg의 검은 영역만 보이겠죠.



이전 이미지에서는 붉은 색 사각형에 가려져 보이지 않던 영역이 보이는 것을 확인할 수 있습니다.

붉은 색 사각형 영역만큼만 보이고 있습니다.


clip 영역에 애니메이션을 주면,

여러가지 재미난 효과를 추가할 수도 있습니다.


오늘은 여기까지 하겠습니다.

그럼 좋은 하루 보내세요~

끝_


edc의 part에 들어가는 필드 중에 ignore_flags가 있습니다.

무언가를 무시하기 위한 목적으로 만들어진 필드일텐데요,

이름만 봐서는 역할이 분명하게 다가오지 않네요.


이럴 때는 구글링으로 궁금증을 해소하거나,

EFL 소스를 뒤져보거나,

시간과 노력을 들여 순수한 삽질로 기능을 유추해야 합니다.

아니면, EFL 커미터에게 헬프를 외치면 됩니다.



안녕하세요, Tizen 개발자 윤진입니다.


우선, EFL 공식 사이트에서 설명을 찾아보겠습니다.

"Specifies whether events with the given flags should be ignored,

i.e., will not have the signals emitted to the parts."


플래그에 대한 이야기가 나옵니다.

플래그를 설정하면 이벤트가 무시될 수 있다고 하네요.

하지만, 단순히 ignore_flags에 넣는 값에 따라 이벤트를 무시한다면,

이전 포스팅에서 다룬 mouse_events와 다를 바가 없겠지요.


ignore_flags는 mouse_events처럼 무조건적으로 이벤트를 통제하는 것이 아닙니다.

경우에 따라 이벤트를 막거나 혹은 받을 수 있습니다.

그렇다면 그 '경우에 따라'는 어디에서 기인하는 것일까요?


파트 자신이 스스로 각각의 경우를 만들어낼 수 있을까요?

아닙니다. ignore_flags를 적어놓고 있는 파트 자신은 스스로 각각의 경우를 발생하지 못합니다.

대신 위의 파트와 관련이 있는 다른 파트들이 각각의 경우를 만들어냅니다.


어째서 이러한 구조가 필요한 것일까요?

스크롤이 가능한 영역을 생각해보지요.

스크롤이 가능한 영역에 다수의 객체가 삽입되었습니다.

스크롤을 하기 위해 press를 한 후 스크롤을 좌우로 움직입니다.

그리고 release를 하면 스크롤 내에 있던 객체는 이벤트를 받아야할까요?


분명 사용자는 스크롤을 목적으로 press - move - release를 했는데,

사용자의 의도와는 다르게 스크롤 내에 삽입된 객체가 release에 대한 이벤트를 처리할 수 있습니다.

사실 삽입객체는 이벤트를 ignore해야하는데 말이지요.


바로 여기에 ignore_flags 필드가 필요한 겁니다.

삽입객체에 "ignore_flags: ON_HOLD;"를 지정하면,

누군가가 ON_HOLD라고 외치는 순간 자신에게 오는 모든 이벤트는 무시하게 됩니다.

스크롤 와중에 삽입객체들은 이벤트를 받으면 안되지요.


이 사실을 파악하기 이해 먼저 evas 소스를 뒤져보았습니다.

Repository : git://review.tizen.org/framework/uifw/evas

Branch : tizen_2.4


/**
 * @brief Enumeration for events.
 */
typedef enum _Evas_Event_Flags
{
   EVAS_EVENT_FLAG_NONE = 0, /**< No fancy flags set */
   EVAS_EVENT_FLAG_ON_HOLD = (1 << 0), /**< The event is being delivered but should be put "on hold" until the on hold flag is unset \n
   The event should be used for informational purposes and maybe for some indications visually, but should not actually perform anything. */
   EVAS_EVENT_FLAG_ON_SCROLL = (1 << 1) /**< The event occurs while scrolling \n
   For example, DOWN event occurs during scrolling; the event should be used for informational purposes and maybe for some indications visually, but should not actually perform anything. */
} Evas_Event_Flags; /**< Flags for Events */


Evas 단에서 이미 ON_HOLD에 대한 enum을 정의하고 있습니다.

EVAS_EVENT_FLAG_ON_HOLD가 설정된 객체(Evas_Object 혹은 group 혹은 part)는,

타 객체에서 설정한 EVAS_EVENT_FLAG_ON_HOLD에 의해 이벤트를 받지 못합니다.


elementary 소스를 뒤져보면,

대부분의 위젯들이 event를 처리하는 콜백에서 해당 객체가 ON_HOLD 처리가 되어 있는지 확인하고,

ON_HOLD가 set되어 있으면 event 콜백 진입 직후에 return 해버립니다.


Repository : git://review.tizen.org/framework/uifw/elementary

Branch : tizen_2.4

./elm_video.c:31:   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
./elm_flip.c:1541:   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
./elm_flip.c:1572:   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
./elm_flip.c:1634:   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
./elm_scroller.c:127:   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
./elc_popup.c:2148:   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
./elm_flipselector.c:440:   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
./elm_slideshow.c:34:   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
./elc_multibuttonentry.c:80:   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
./elm_gengrid.c:852:   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
./elm_gengrid.c:2312:   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
./elm_diskselector.c:913:   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
./elm_web.c:180:   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
./elm_entry.c:3208:   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
./elm_button.c:297:   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
./elm_interface_scrollable.c:2143:   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
./elm_map.c:4378:   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
./elm_panel.c:818:   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
./elc_ctxpopup.c:1198:   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
./elm_genlist.c:2682:   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
./elm_genlist.c:3547:   //if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
./elm_radio.c:164:   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
./els_scroller.c:1863:   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return ;
./els_scroller.c:1931:   //   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return ;
./els_scroller.c:2193:   //   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return ;
./els_scroller.c:2512:   //   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return ;
./elm_list.c:426:   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
./elm_colorselector.c:1760:   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
./elm_slider.c:381:   if (mev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
./elm_slider.c:391:   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
./elc_naviframe.c:1332:   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return;
./elc_naviframe.c:1773:   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
./elm_check.c:155:   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
./elc_player.c:51:   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
./elm_toolbar.c:756:   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;
./elm_photocam.c:944:   if (ev->event_flags & EVAS_EVENT_FLAG_ON_HOLD) return EINA_FALSE;


스크롤러 등에 삽입되어 이벤트를 유연하게 처리하고자 한다면,

위의 위젯들처럼 ON_HOLD가 설정된 event에는 return 처리를 해야겠지요.


그렇다면, 최초 발생한 이벤트는 어떻게 되는 것일까요?

ON_HOLD된 파트들은 건너뛰고,

계속 부모 객체를 찾아갑니다.

ON_HOLD가 설정되지 않은 부모 객체까지 타고 올라가서 이벤트를 처리하게 합니다.

그와 관련된 부분은 아래 propagate 함수에서 엿보실 수 있습니다.


Repository : git://review.tizen.org/framework/uifw/elementary

Branch : tizen_2.4

src/lib/elm_widget.c

EAPI Eina_Bool
elm_widget_event_propagate(Evas_Object *obj,
                           Evas_Callback_Type type,
                           void *event_info,
                           Evas_Event_Flags *event_flags)
{
   API_ENTRY return EINA_FALSE; //TODO reduce.

   if (!_elm_widget_is(obj)) return EINA_FALSE;
   Evas_Object *parent = obj;
   Elm_Event_Cb_Data *ecd;
   Eina_List *l, *l_prev;

   while (parent &&
          (!(event_flags && ((*event_flags) & EVAS_EVENT_FLAG_ON_HOLD))))
     {   
        sd = evas_object_smart_data_get(parent);
        if ((!sd) || (!_elm_widget_is(obj)))
          return EINA_FALSE;  //Not Elm Widget
        if (!sd->api) return EINA_FALSE;

        if (sd->api->event(parent, obj, type, event_info))
          return EINA_TRUE;

        EINA_LIST_FOREACH_SAFE(sd->event_cb, l, l_prev, ecd)
          {https://docs.enlightenment.org/auto/edje/edcref.html
             if (ecd->func((void *)ecd->data, parent, obj, type, event_info) ||
                 (event_flags && ((*event_flags) & EVAS_EVENT_FLAG_ON_HOLD)))
               return EINA_TRUE;
          }
        parent = sd->parent_obj;
     }   

   return EINA_FALSE;
}


이상입니다.

다음 포스팅에서도 part의 기본필드를 알아보도록 하겠습니다.


그럼 좋은 하루 보내세요~

끝_


* References

https://docs.enlightenment.org/auto/edje/edcref.html


part 블록에서는 자칫 정신을 잃으면, 급류에 휩쓸려 내려가 죽습니다;

워낙에 많은 복병과 암초가 기다리고 있기 때문에,

가급적이면 많은 예외사항을 다뤄보도록 하겠습니다.

만약 누락된 것이 있다면 댓글로 남겨주세요.

힘 닿는 만큼 추가해보도록 하겠습니다.



안녕하세요, Tizen 개발자 윤진입니다.


part는 parts 블록 안에 위치합니다.

parts 블록 안에는 1개 이상의 part를 배치할 수 있습니다.

parts 안에는 part 말고 다른 블록은 없지요.


parts 안에 쌓이는 part의 순서에도 의미가 있습니다.

위에 있는 part 일수록 레이어는 가장 아래에 위치합니다.

하나씩 part를 만들때 가장 상단에 있는 part부터 차곡차곡 쌓는다고 생각하면 됩니다.



개별적인 part는 완결된 화면 구성 단위인 group 내에 위치한 구성 '요소'입니다.

뒤집에 말하면, 각각의 구성요소가 모여서 하나의 의미있는 group이 되지요.


group {
   parts {
      part{} /* 최하단 레이어 */
      part{}
      part{}
      part{}
      part{}
      part{} /* 최상단 레이어 */
   }
}


part는 선이나 사각형이 될 수 있고,

이미지나 텍스트가 될 수도 있습니다.

버튼과 같은 다른 group을 통째로 넣을 수도 있습니다.

각각의 쓰임에 따라 syntax가 조금씩 달라집니다.


group {
   parts {
      ...
      part {
         name: "part_name";
         type: IMAGE;
         mouse_events:  1;
         repeat_events: 0;
         ignore_flags: NONE;
         clip_to: "another_part";
         source:  "group_name";
         pointer_mode: AUTOGRAB;
         description { }
         dragable { }
         items { }
      }
      ...
   }
}


part 내에서 사용하는 기본적인 필드를 우선 살펴보겠습니다.

여기서 언급하는 필드로 파트의 속성을 엿볼 수 있습니다.

필드의 세부적인 속성값이나 여기에 언급하지 않은 필드도 다른 포스팅에서 다룰 예정입니다.

한 번에 모두를 다루기에는 그 양이 너무 많네요.


- name: [part_name];

   파트의 이름을 지정할 수 있습니다.

   파트 이름은 program에서 애니메이션 효과를 줄 때 사용할 수 있습니다.

   c코드에서 파트이름으로 파트에 직접 접근할 수도 있습니다만 일반적인 용례는 아닙니다.


   어쨌든 외부에서 접근할 수 있으니,

   다른 파트 이름과 구별되는 고유의 이름을 지어주어야 합니다.

   파트이름은 큰 따옴표로 감싸주세요.



- type: [TYPE];

   타입은 아래처럼 확정된 값을 따옴표 없이 대문자로 넣을 수 있습니다.

   만약 아무런 값도 지정하지 않았다면 default로 IMAGE가 설정됩니다.

•    TEXT : 싱글라인 텍스트
•    TEXTBLOCK : 멀티라인/스타일이 가능한 텍스트블록
•    RECT : 사각형
•    IMAGE : 이미지
•    SWALLOW : group을 통째로 탑재할 수 있는 SWALLOW 타입(c에서 확정)
•    GROUP : group을 통째로 탑재할 수 있는 GROUP 타입(edc에서 확정)

•    BOX : 박스에 다른 그룹을 차곡차곡 삽입
•    TABLE : 테이블

•    EXTERNAL : 익스터널 오브젝트
•    PROXY : 파트 컨텐트 재사용(속도 최적화)
•    SPACER : 파트 위치+크기 지정(메모리 최적화)



- mouse_events:  [1 or 0];

   이름은 마우스 이벤트이지만 파트영역에서 발생하는 모든 이벤트를 통제할 수 있습니다.

   설정할 수 있는 값은 True를 뜻하는 1과 False를 뜻하는 0입니다.

   True를 설정하면 해당 파트가 '이벤트를 받을 수 있는 상황에서' 이벤트를 받게 됩니다.


   이벤트를 받을 수 있는 상황이란,

   - 파트영역이 화면에 보여야하고,

   - 파트영역을 덮는 다른 파트가 있으면 안됩니다.


   흔히 저지르는 실수 중에 하나가 투명한 파트를 상위 레이어에 만들어 두고,

   그 아래에 있는 파트에서 이벤트를 기다리는 것이지요.

   아무리 기다려도 위에 있는 레이어가 낚아채버리면 이벤트는 오지 않습니다.

   가장 기본적인 원칙이지요.


   만약 0으로 설정하면 어떤 이벤트도 받지 않습니다.

   이벤트를 받을 수 있는 상황인데 이벤트를 받지 않으면,

   그 하위에 있는 레이어에게 기회가 돌아가게 됩니다.

   역으로 자기보다 상단에 레이어가 있지만,

   상단 레이어가 mouse_events를 0으로 설정하면 자기가 이벤트를 받을 수 있습니다.

   default 값은 이벤트를 처리한다는 뜻으로 1로 설정하지요.



- repeat_events: [1 or 0];

   위에서도 언급하였지만 이벤트는 레이어의 높낮이에 영향을 받습니다.

   최상위 레이어부터 최하위 레이어까지 이벤트가 순서대로 전달될 수 있습니다.

   만약 상위 레이어가 이벤트를 처리하였지만, 하위레이어도 이벤트를 받아야하는 경우도 있을 수 있습니다.

   그럴 때 repeat_events를 사용하여 이벤트를 하위 레이어에 전달할 수도 있습니다.

   default는 0이기 때문에 이벤트를 받은 레이어 아래에 이벤트를 전달하지 않습니다.



- scale: [1 or 0];

   scale은 매우 중요한 개념이지만 그 중요도만큼이나 까다로운 필드입니다.

   scale 값을 True인 1로 설정하면, scale factor의 영향을 받는다는 의미이고,

   False인 0으로 설정하면, scale factor의 영향을 받지 않는다는 의미입니다.


   scale factor는 무엇일까요?

   scale factor는 double 형의 상수입니다.

   해상도와 화면사이즈가 제각각인 디스플레이에서,

   육안으로 봤을때 유사한 크기로 교정하기 위해 플랫폼에서 제공하는 계산된 인자입니다.


   예를 들어 동일한 해상도의 1인치/3인치 디스플레이가 있다고 합시다.

   1인치 화면에서 1cm 너비로 보이는 파트영역을,

   3인치 화면에서 3cm가 아닌 여전히 1cm로 너비를 지정하고 싶을 경우,

   1인치에서 1로 scale factor를 지정하였다면,

   3인치에서는 1/3로 scale factor를 지정합니다.

   그러면 1인치에서는 1cm x 1scale factor = 1cm로 설정이 되고,

   3인치에서는 3cm x 1/3scale factor = 1cm로 설정이 되겠지요.


   굉장히 간단하게 설명을 드렸지만, 대강의 의미는 전달되었을거라 생각합니다.

   차후에 scale factor에 대한 이야기를 제대로 할 기회가 있겠지요.


   이러한 scale factor에 영향을 받는 값은,

   min, max 그리고 font size입니다.

   위의 세값을 설정하지 않은 파트는 scale을 1로 지정하여도 scale의 영향을 받지 않습니다.

   반대로 min, max, font size를 지정한 파트에 scale 값을 0으로 줘버리면,

   scale factor의 영향을 받지 않고 지정한 사이즈 그대로 화면에 보여집니다.

  

   default값은 1.0입니다.

   스케일 값을 사용하는 것이 default이지요.



- pointer_mode: [MODE];

   파트영역 내에서 시작하였지만, 파트영역 밖에서 끝난 이벤트를 처리하는 방식을 지정할 수 있습니다.

   mouse down과 mouse up 이벤트로 설명하는 것이 빠르겠네요.

   파트영역 내에서 mouse down을 하였지만,

   mouse를 move하여 파트영역 밖으로 빠져나간 후 mouse up을 할 수 있습니다.

   그렇게 되면 mouse up이벤트를 파트영역이 받아야 할까요?

   그에 대한 선택을 사용자가 pointer_mode로 할 수 있습니다.


   AUTOGRAB 값을 주면,

   mouse up 이벤트가 파트영역 외부에서 이뤄지더라도 mouse down이 발생한 파트가 이벤트를 받습니다.


   NOGRAB 값을 주면,

   mouse up 이벤트가 파트영역 외부에서 이뤄지면 mouse down이 발생한 파트로는 이벤트가 오지 않습니다.


   default는 AUTOGRAB이기 때문에 NOGRAB을 사용하지 않는 이상,

   pointer_mode를 굳이 사용할 필요는 없습니다.



- precise_is_inside: [1 or 0];

   투명한 영역을 가지고 있는 이미지에서 빛을 발하는 '훌륭한' 기능입니다.

   이미지가 이벤트를 받는 경우,

   이미지의 투명한 영역은 이벤트를 받지 않고,

   불투명한 영역에서만 이벤트를 받고 싶을 수도 있습니다.

   바로 그럴 경우, precise_is_inside를 1로 지정하면 됩니다.

   그러면 투명한 영역은 파트영역 내부(inside)로 포함되지 않습니다.


   default 값은 0입니다.

   투명한 영역도 이미지의 영역이므로 이벤트를 모두 처리합니다.


오늘은 여기까지 하겠습니다.

part가 가지는 다른 무수한 기능은 다음 포스팅에서 하나씩 살펴보겠습니다.


그럼 좋은 하루 보내세요~

끝_


edc에서 group은 비교적 군더더기 없이 만들어져 있습니다.

group을 사용할 때, '충돌'이나 '이해할 수 없는 동작'을 고민할 필요가 없습니다.


group과 얽힌 재미난 에러를 하나쯤 언급하기 위해 기억을 더듬고 있지만,

도통 떠오르지 않네요.

비교적 간단한 역할을 담당하고 있으니 실구현에도 어려움은 없는 녀석이었나봅니다.

여러분도 그럴 것이라 믿어의심치 않습니다. :)



안녕하세요, Tizen 개발자 윤진입니다.


edc를 작성할 때 group은 하나의 완결된 구성이 됩니다.

c파일에서 elm_layout_add(), elm_layout_file_set() 콤보로 가져다 쓰는 단위가 group입니다.

하나의 collections에 수많은 group이 있다면,

c에서 필요한 group만큼 elm_layout_add()를 불러서 사용하면 됩니다.


그렇다면 완결된 구성을 위해서는 그 안에 어떤 요소를 담고 있어야 할까요?

그룹이 가진 많은 요소 중에 가장 중요한 요소는 parts와 programs 두가지입니다.

parts는 화면을 구성하는 part의 상위 블록이고,

programs는 part에 움직임을 부여할 수 있는 program의 상위 블록이지요.


collections {
   group {
      parts {
         part{}
         part{}
         part{}
         part{}
      }
      programs {
         program{}
         program{}
         program{}
         program{}
      }
   }


지난
collections 포스팅에서도 언급한 블록도에서 programs를 추가해봤습니다.

위의 블록도처럼 group에 parts와 programs만 있으면 화면에 무언가 그려낼 수 있습니다.

parts와 programs 블록은 각각 며칠씩 공을 들여 설명해보도록 하겠습니다.


group에는 parts와 programs 외에 다른 요소들도 있습니다.

name, inherit, min, max.

위의 요소들은 parts와 programs에 비하면 아주 간단하게 설명할 수 있습니다.


- name: [group name];

   그룹의 이름을 지정합니다.

   위에서 잠깐 언급한 elm_layout_file_set()에서 세번째 인자가 그룹 name입니다.

   c파일에서는 group이 있는 파일명과 여기서 지정한 그룹명으로 그룹에 접근할 수 있습니다.

   만약 group 이름이 동일하다면 새로운 group이 이전 group을 완전히 override해버립니다.

   edc에서 group override를 의미있게 사용하는 것을 보질 못해서,

   이 부분은 컴파일을 위한 편의가 아닐까 추정하고 있습니다.

   어쨌든, override되지 않게 그리고 문맥에 맞게 사용하려면 group명을 잘 지어주세요.

   언제나 모든 것은 적절한 네이밍에서 시작하지요.


- min: [width] [height];

   min의 의미는 "최소한 이 사이즈를 확보해주세요"입니다.

   group이 어디에 포함되어 들어가든 min 사이즈만큼은 확보가 됩니다.

   min에서 지정한 사이즈보다 group이 작아질 수는 없습니다.

   원칙적으로 그렇습니다.

   min에서는 그룹의 높이와 너비를 지정하겠지요.

   그룹의 높이/너비가 확정되어 있고 '절대로 변할 일이 없다'면,

   group 차원에서 정의해도 무방합니다.

   하지만, group이 상태에 따라 사이즈가 바뀐다면,

   여기서 min을 사용하면 안됩니다.

   min은 mandatory가 아니기에 상황에 따라 사용하면 됩니다.

   참고로 전 group에서 min을 사용하지 않습니다.

   min은 다른 곳에서 더 재미있는 형태로 사용할 수 있습니다.


- max: [width] [height];

   max는 min과는 반대의 개념입니다.

   "최대한 이 사이즈를 넘지 않도록 해주세요" 입니다.

   max의 중요성은 min에 비해 상당히 떨어지는데요,

   각각의 요소들이 사이즈를 잡을때 min을 기준으로 잡기 때문입니다.

   max는 느슨한 가이드라인이지요.

   그렇다고 사용하지 않는다는 것은 절대 아닙니다.

   차후에 min/max에 대해서는 계속 설명할 기회가 있을 겁니다.

   어쨌든 그룹이 max 값을 넘지 않게 합니다.

   min처럼 mandatory가 아니기 때문에 필요에 의해 사용하면 됩니다.


- alias: [additional group name];

   alias에서 그룹에 별칭을 지정할 수 있습니다.

   하나의 그룹이 다수의 이름을 가질 필요가 있을때 사용합니다.

   그룹을 하나 만들었는데 여러 군데에서 사용할 수 있고,

   각각에 고유한 네이밍을 하길 원할 때가 있습니다.

   그 때 alias는 의미있는 선택이 될 수 있습니다.


group의 모든 요소를 골고루 사용하는 define문을 icon.edc에서 찾았습니다.

Repository : git://review.tizen.org/framework/uifw/elementary

Branch : tizen_2.3

File : data/themes/widgets/icon.edc


#define GROUP_ALIAS_ICON(Name, Alias, File, Min, Max)                   \
   group { name: "elm/icon/"##Name##"/default"; min: Min Min; max: Max Max; \
      images.image: File COMP; parts { part { name: "base";             \
            description { aspect: 1.0 1.0; aspect_preference: BOTH;     \
               image.normal: File; } } } }
/*** 생략 ***/
GROUP_ALIAS_ICON("home", "toolbar/home", "icon_home.png", 32, 0);
GROUP_ALIAS_ICON("close", "toolbar/close", "icon_close.png", 32, 0);
GROUP_ALIAS_ICON("apps", "toolbar/apps", "icon_apps.png", 32, 0);
GROUP_ALIAS_ICON("arrow_up", "toolbar/arrow_up", "icon_arrow_up.png", 32, 0);
GROUP_ALIAS_ICON("arrow_left", "toolbar/arrow_left", "icon_arrow_left.png", 32, 0);
GROUP_ALIAS_ICON("arrow_right", "toolbar/arrow_right", "icon_arrow_right.png", 32, 0);
GROUP_ALIAS_ICON("chat", "toolbar/chat", "icon_chat.png", 32, 0);
GROUP_ALIAS_ICON("clock", "toolbar/clock", "icon_clock.png", 32, 0);
GROUP_ALIAS_ICON("delete", "toolbar/delete", "icon_delete.png", 32, 0);
GROUP_ALIAS_ICON("edit", "toolbar/edit", "icon_edit.png", 32, 0);
GROUP_ALIAS_ICON("refresh", "toolbar/refresh", "icon_refresh.png", 32, 0);
GROUP_ALIAS_ICON("folder", "toolbar/folder", "icon_folder.png", 32, 0);
GROUP_ALIAS_ICON("file", "toolbar/file", "icon_file.png", 32, 0);
GROUP_ALIAS_ICON("no_photo", "photo/no_photo", "head.png", 32, 0);


위에서 난데없는 #define이 나와서 당황하셨을 지도 모르겠군요.

C언어에서처럼 #define을 유사하게 사용할 수 있습니다.

우리가 살펴봐야할 부분은 GROUP_ALIAS_ICON의 Name, Alias, Min, Max입니다.

실제로 #define이 사용되는 부분을 보면,

Name, Alias, Min값을 주로 사용하고 있군요.

Max는 마지막 인자로 '0'을 넣어주고 있네요.

최대 크기가 0이라는 의미는 아니고 Max를 사용하지 않겠다는 의미입니다.

이 예시에서는 그룹의 Name과 Alias를 지정하고,

최소/최대 사이즈를 지정하였습니다.


group에 대한 설명은 이것으로 간단하게 마치겠습니다.

다음 시간에는 part에 대해서 살펴보도록 하겠습니다.


그럼 좋은 하루 보내세요~

끝_



EFL에 대해 블로깅을 하는 날이 오고야 말았습니다.

오늘부터 n일 동안 edc에 대해서 하나씩 살펴보도록 하겠습니다.


진도를 빨리 뺀다는 마음보다는,

다소 느리더라도 천천히 하나하나 맛을 음미하며 진행하고 싶네요.


하지만, 충분히 설명해낼 수 있을지는 확신이 안 서네요.



안녕하세요, Tizen 개발자 윤진입니다.


edc는 EFL의 백미라 할 수 있습니다.

(써 놓고 보니 '백미' 타이틀은 ecore나 evas에게 주어야하지 않나라는 생각도 듭니다;)

edc 스크립트를 사용하여 레이아웃을 잡고 이미지를 배치하고 텍스트를 심습니다.

이러한 정적인 배치는 edc의 part를 이용하여 구성할 수 있습니다.


위에 나열한 정적인 요소에 program을 통해 생명력을 불어넣을 수 있습니다.

part 하나 하나가 program의 손길로 동적인 효과를 가집니다.

네다섯줄의 스크립팅으로 부드러운 애니메이션을 탑재할 수 있습니다.


edc 스크립트에서 가장 처음 마주하게 되는 블록이 collections입니다.

collections에는 하나의 유의미한 단위로 동작하는 group이 들어갑니다.

group 화면을 구성하는 완결된 하나의 집합이고,

collections는 그러한 group을 1개 이상 가집니다.


예를 들어 버튼+텍스트의 집합을 하나의 완결된 'button' group이 있다고 하죠.

경우에 따라서 버튼의 모양은 천양지차로 다를 수 있습니다.

네모난 버튼이 일반적이긴 하지만, 사각이 라운딩 처리된 라운딩 버튼이 있을 수도 있습니다.

이럴 경우 네모난 버튼용 group과 라운딩 버튼용 group이 따로 둘 수 있습니다.

세모난 버튼용 group이나 투명 버튼용 group도 있을 수 있겠네요.

생김새는 조금씩 다르지만 버튼이라는 기능적인 유사성이 있기 때문에,

하나의 collections로 모아서 관리할 수 있겠죠.

이처럼 collections는 다양한 theme을 묶어주는 역할을 할 수 있습니다.


그렇다면 group이 하나만 있어도 collections로 묶어줘야 할까요?

네, 맞습니다.

collections는 group이 1개 이상 있는 경우에 반드시 써주어야 합니다.

collections로 감싸지지 않은 group은 제대로 컴파일되지 않습니다.

collections - group - parts - part

혹은

Collections - group - programs - program

위에 이르는 블록 구조에서 최상단에는 언제나 collections가 있습니다.


edc 파일은 collections를 반드시 갖지만,

두 개 이상 가질 수는 없습니다.

edc 파일에는 오직 하나의 collections만 사용할 수 있습니다.


collections {
   group {
      parts {
         part{}
         part{}
         part{}
         part{}
      }
   }


EFL elementary repository에서 사용하고 있는 edc 파일을 예제로 살펴보겠습니다.

Repository : git://review.tizen.org/framework/uifw/elementary

Branch : tizen_2.3

File : data/themes/default.edc

collections {
///////////////////////////////////////////////////////////////////////////////
   group { name: "elm/focus_highlight/top/default";
   /* ... 생략 ... */
      parts {
         part { name: "base";
            type: RECT;
            repeat_events: 1;
            description { state: "default" 0.0;
               rel1.relative: 0.0 0.0;
               rel2.relative: 1.0 1.0;
               visible: 0;
            }
         }
         part { name: "shine";
            type: IMAGE;
            mouse_events: 1;
            repeat_events: 1;
            ignore_flags: ON_HOLD;
            description { state: "default" 0.0;
               image {
                  normal: "emo-unhappy.png";
               }
               rel1.to: "base";
               rel1.relative: 1.0 0.0;
               rel1.offset: -15 -15;
               rel2.to: "base";
               rel2.relative: 1.0 0.0;
               rel2.offset: 14 14;
            }
            description { state: "disabled" 0.0;
               inherit:  "default" 0.0;
               color: 0 0 0 0;
            }
         }
   /* ... 생략 ... */
///////////////////////////////////////////////////////////////////////////////
   group { name: "elm/focus_highlight/bottom/default";
      parts {
         part { name: "shine";
            type: RECT;
            mouse_events: 1;
            repeat_events: 1;
            ignore_flags: ON_HOLD;
            description { state: "default" 0.0;
               color: 0 255 0 50;
               rel1.offset: 0 0;
               rel2.offset: 0 0;
            }
            description { state: "disabled" 0.0;
               inherit:  "default" 0.0;
               color: 0 0 0 0;
            }
         } 
   /* ... 생략 ... */
///////////////////////////////////////////////////////////////////////////////
   group { name: "elm/access/base/default";
      images {
         image: "access_glow.png" LOSSY 85;
      }
      parts {
         part { name: "block1"; type: RECT;
            mouse_events:  0;
            description { state: "default" 0.0;
               color: 0 0 0 200;
               rel1 { to: "base";
                  relative: 0.0 0.0;
                  offset: -100000 -100000;
               }
               rel2 { to: "base";
                  relative: 1.0 0.0;
                  offset: 100000 96;
               }
            }
         }
         part { name: "block2"; type: RECT;
            mouse_events:  0;
            description { state: "default" 0.0;
               color: 0 0 0 200;
               rel1 { to: "base";
                  relative: 0.0 1.0;
                  offset: -100000 -97;
               }
               rel2 { to: "base";
                  relative: 1.0 1.0;
                  offset: 100000 100000;
               }
            }
         }
         part { name: "block3"; type: RECT;
            mouse_events:  0;
            description { state: "default" 0.0;
               color: 0 0 0 200;
               rel1 { to: "block1";
                  relative: 0.0 1.0;
                  offset: 0 0;
               }
               rel2 { to_x: "base"; to_y: "block2";
                  relative: 0.0 0.0;
                  offset: 96 -1;
               }
            }
         }
         part { name: "block4"; type: RECT;
            mouse_events:  0;
            description { state: "default" 0.0;
               color: 0 0 0 200;
               rel1 { to_x: "base"; to_y: "block1";
                  relative: 1.0 1.0;
                  offset: -97 0;
               }
               rel2 { to: "block2";
                  relative: 1.0 0.0;
                  offset: -1 -1;
               }
            }
         }
         part { name: "base";
            mouse_events:  0;
            description { state: "default" 0.0;
               image.normal: "access_glow.png";
               image.border: 112 112 112 112;
               rel1.offset: -102 -102;
               rel2.offset:  101  101;
               fill.smooth: 0;
            }
         }
      }
   }


위에서 보시다시피 하나의 collections 아래에 다수의 group이 놓여져 있습니다.

focus와 highlight와 관련된 기능이 group으로 구현되어 있네요.


group이 더욱 많이지면 collections에다가 제대로 붙이기 힘들 정도로 길어질 수도 있습니다.

이럴 때는 collections 문 안에서 #include 문을 사용하여 group을 include할 수 있습니다.

같은 파일의 아랫 부분을 보면, #include 문을 사용했습니다.


collections {
   /* ... 생략 ... */
#include "widgets/bg.edc"
#include "widgets/border.edc"
#include "widgets/scroller.edc"
#include "widgets/label.edc"
#include "widgets/button.edc"
#include "widgets/clock.edc"
#include "widgets/datetime.edc"
#include "widgets/dayselector.edc"
#include "widgets/menu.edc"
#include "widgets/frame.edc"
#include "widgets/tooltip.edc"
#include "widgets/hover.edc"
#include "widgets/ctxpopup.edc"
#include "widgets/entry.edc"
#include "widgets/bubble.edc"
#include "widgets/photo.edc"
#include "widgets/thumb.edc"
#include "widgets/icon.edc"
#include "widgets/toolbar.edc"
#include "widgets/notify.edc"
#include "widgets/slideshow.edc"
#include "widgets/win.edc"
#include "widgets/list.edc"
#include "widgets/slider.edc"
#include "widgets/actionslider.edc"
#include "widgets/genlist.edc"
#include "widgets/check.edc"
#include "widgets/radio.edc"
#include "widgets/progressbar.edc"
#include "widgets/separator.edc"
#include "widgets/spinner.edc"
#include "widgets/index.edc"
#include "widgets/gengrid.edc"
#include "widgets/photocam.edc"
#include "widgets/map.edc"
#include "widgets/panes.edc"
#include "widgets/panel.edc"
#include "widgets/conformant.edc"
#include "widgets/calendar.edc"
#include "widgets/colorselector.edc"
#include "widgets/flipselector.edc"
#include "widgets/diskselector.edc"
#include "widgets/fileselector.edc"
#include "widgets/layout.edc"
#include "widgets/segment_control.edc"
#include "widgets/player.edc"
#include "widgets/video.edc"
#include "widgets/naviframe.edc"
#include "widgets/multibuttonentry.edc"
#include "widgets/popup.edc"
#include "ews.edc"
#include "widgets/pointer.edc"
}


위에서 사용한 #include 문은 현재 파일이 있는 위치를 기준으로 상대경로를 사용했습니다.

widgets 디렉토리 아래에 있는 수많은 edc 파일을 include하였지요.

edc 파일들을 하나씩 열어보면 모두 group인 것을 알 수 있습니다.

collections를 품고 있는 edc는 단 하나도 없습니다.

왜냐하면 이미 collections로 감싸졌기 때문입니다.


위의 예에서는 모든 위젯을 하나의 collections에서 관리하고 있습니다.

- 이처럼, 하나의 프로젝트 단위에서는 하나의 collections를 사용할 수 있습니다.

- 혹은, 각각의 위젯을 하나의 collections 단위로 쪼갤 수도 있겠지요.

관리상 용이한 것을 따르시면 됩니다.

꼭 정해진 것은 없습니다.


오늘은 collections에 대해서 간단하게 살펴보았습니다.

다음 시간에는 group에 대해서 훑어보도록 하겠습니다.


그럼 좋은 하루 보내세요~

끝_

2015년 7월 22일,

Tizen2 Seller Office에서 메일이 하나 왔습니다.



인도, 방글라데시, 스리랑카에 이어 네팔에서도 유료판매가 가능하다는 메일입니다.

타이젠이 인도를 중심으로 그 주변국가로 영역을 지속적으로 확장하고 있습니다.



7월 말 인도에서 열리는 Tizen Developer Summit으로,

남부아시아에서 타이젠의 존재를 다시 한 번 입증하겠지요.



그리고 올 9월 2015 Tizen Developer Conference는 중국에서 열리는 만큼,

점차 타이젠의 영역이 넓어지지 않을까 조심스럽게 생각해봅니다.



182개국 중 4개국에서 유료앱 판매가 가능하게 되었으니,

이제 남은 178개국까지 유료앱 판매가 확대되길 기대해봅니다


그럼 좋은 하루 보내세요.

끝_

타이젠 네이티브 앱을 개발하려면 화면 구성을 해야겠지요.

Enventor가 화면을 구성할 때 좋은 친구가 되어줄 것입니다.


Enventor를 사용하여 레이아웃에 이미지를 넣어봅시다.

Enventor에 이미지를 위한 공간을 마련하는 것은 어렵지 않은데요,

이미지를 위한 공간에 이미지를 포함시키려면 이미지파일은 어디에 두어야 할까요?



안녕하세요, Tizen 개발자 윤진입니다.


Tizen 2.3 SDK에서 edc 파일을 더블클릭하면 Enventor가 런칭됩니다.

Enventor에 이미지를 저장하기 위한 파트를 하나 만들어둡니다.

그리고 파트에 이미지를 하나 지정합니다.

이미지 파일은 어디에 두는게 좋을까요?

Enventor > Setting > Image Paths

위의 경로를 변경하여 이미지를 저장해봅니다.



Image Paths를 이미지 파일이 있는 디렉토리로 변경하고,

Enventor의 preview 영역을 확인하니 이미지가 제대로 나옵니다.


자, 그리고 컴파일을 시도하면 위의 edc 파일을 빌드할 수 없다고 에러가 나옵니다.

무엇이 문제인 것일까요?


Eventor와 Tizen SDK가 완벽하게 통합되지 않았습니다.

위에서 설정한 Image Paths는 Enventor 만을 위한 메뉴입니다.

Tizen SDK에서 빌드를 위한 Image Paths도 지정해주어야 합니다.


Project Explorer > (마우스 우클릭) > Properties

위처럼 진입하여 메뉴윈도우를 띄웁니다.

C/C++ Build > Settings > Tool Settings > EDC Resource Compiler > misc

위의 메뉴까지 진입하면 Image Path를 입력할 수 있는 메뉴가 나옵니다.



Image Path에 있는 "+" 버튼을 눌러서 이미지 파일이 있는 위치를 추가해줍니다.

그리고 OK를 눌러 다시 빌드를 해봅니다.

이제 빌드에 성공하였네요.


그럼 좋은 하루 보내세요~

끝_


최신 버전 Ubuntu 15.04 64비트에 Tizen 2.3 SDK를 설치해보았습니다.

올초에 나온 Tizen 2.3 SDK는 14.04까지 공식지원하고 있습니다.

다행히 15.04에서도 SDK의 기본 기능을 사용하는데 문제는 없습니다.


하지만, 드디어 에러를 만나게 됩니다.

Tizen SDK 내에 edc 파일을 편집할 때 사용하는 enventor라는 툴이 실행이 안되더군요.

이번 포스팅은 enventor를 '임시'로 사용할 수 있는 방법을 공유합니다.



안녕하세요, Tizen 개발자 윤진입니다.


이번 포스팅은 타이젠 2.3 SDK에서 공식지원하지 않는 Ubuntu 15.04 환경에서 벌어진 일을 다룹니다.

Ubuntu 14.04에서는 위와 같은 에러 없이 Eventor를 사용하실 수 있습니다.

하지만, 최신 버전의 우분투에서 타이젠 SDK를 사용하고 싶으시다면 이번 포스팅을 참고해주세요.



SDK에서 edc 파일을 편집하기 위해 파일을 더블클릭하면 위와 같은 팝업창이 뜹니다.

팝업 내용은 edc 편집툴인 enventor를 런칭하지 못한다는 내용인데요,

에러로그 뷰를 살펴보라고 하지만, 에러로그 뷰에는 별 다른 내용이 없습니다.

그래서 이를 해결하기 위해서 enventor를 커맨트창에서 직접 실행해보았습니다.


$ ~/tizen-sdk/tools/enventor/bin/enventor 
/home/storycompiler/tizen-sdk/tools/enventor/bin/enventor: error while loading shared libraries: libelementary.so.1: cannot open shared object file: No such file or directory


elementary 라이브러리가 없어서 enventor가 실행이 안되는 것이었군요.

하지만, 타이젠 SDK에는 elementary 라이브러리가 포함되어 있습니다.


$ ls ~/tizen-sdk/tools/efl-tools/lib/libelementary.so.1
/home/storycompiler/tizen-sdk/tools/efl-tools/lib/libelementary.so.1

위의 위치를 보시면 EFL에서 제공하는 다수의 라이브러리를 확인하실 수 있습니다.

물론 elementary도 찾을 수 있지요.

라이브러리가 있는데 찾지 못하는 것은 라이브러리 위치가 등록되어있지 않기 때문입니다.

타이젠 라이브러리 디렉토리를 등록하기 위해 /etc/ld.so.conf.d 디렉토리에 tizen.conf 파일을 새로 만듭니다.

그 안에 위의 라이브러리 디렉토리를 추가해둡니다.


$ cat /etc/ld.so.conf.d/tizen.conf
/home/storycompiler/tizen-sdk/tools/efl-tools/lib


그리고 다시 enventor를 실행해봅니다.

이번에는 아래처럼 libgnutls 라이브러리가 없다고 나옵니다.


$ ~/tizen-sdk/tools/enventor/bin/enventor 
/home/storycompiler/tizen-sdk/tools/enventor/bin/enventor: error while loading shared libraries: libgnutls.so.26: cannot open shared object file: No such file or directory


libgnutls.so.26 버전은 여기에서 다운로드 받을 수 있습니다.

위의 사이트가 열리지 않을 경우에 대비하여 64비트 우분투 15.04용 rpm을 첨부합니다.

lib64gnutls26-2.12.14-2-mdv2012.0.x86_64.rpm

아래와 같이 libgnutls.so.26 버전을 설치합니다.

여기에서는 64비트 환경에 맞춰서 64비트용의 라이브러리를 설치하였습니다.


$ sudo rpm -Uvh --force --nodeps lib64gnutls26-2.12.14-2-mdv2012.0.x86_64.rpm
rpm: RPM should not be used directly install RPM packages, use Alien instead!
rpm: However assuming you know what you are doing...
경고: lib64gnutls26-2.12.14-2-mdv2012.0.x86_64.rpm: Header V3 DSA/SHA1 Signature, key ID 26752624: NOKEY
준비 중...                         ################################# [100%]
Updating / installing...
   1:lib64gnutls26-2.12.14-2          ################################# [100%]

그리고 다시 enventor를 실행해봅니다.

이번에는 libgcrypt.so.11 파일이 없다고 나오네요.

$ ~/tizen-sdk/tools/enventor/bin/enventor
/home/storycompiler/tizen-sdk/tools/enventor/bin/enventor: error while loading shared libraries: libgcrypt.so.11: cannot open shared object file: No such file or directory


따라서 이번에도 libgcrypt.so.11 버전을 찾아서 받습니다.

위의 버전은 여기에서 다운로드 받으실 수 있습니다.

위의 사이트가 열리지 않을 경우에 대비하여 64비트 우분투 15.04용 rpm을 첨부합니다.

lib64gcrypt11-1.5.4-5.mga5.x86_64.rpm

$ sudo rpm -Uvh --force --nodeps lib64gcrypt11-1.5.4-5.mga5.x86_64.rpm
rpm: RPM should not be used directly install RPM packages, use Alien instead!
rpm: However assuming you know what you are doing...
경고: lib64gcrypt11-1.5.4-5.mga5.x86_64.rpm: Header V3 RSA/SHA1 Signature, key ID 80420f66: NOKEY
준비 중...                         ################################# [100%]
Updating / installing...
   1:lib64gcrypt11-1.5.4-5.mga5       ################################# [100%]


libgcrypt는 /usr/lib64에 설치가 됩니다.

하지만, 위의 위치는 ld.conf에 등록된 위치가 아닐 수 있습니다.

$ ls /usr/lib64/libgcrypt.so.11
/usr/lib64/libgcrypt.so.11


따라서 좀 전에 elementary를 등록하기 위해 만든 tizen.conf에 lib64도 등록해둡니다.

$ cat /etc/ld.so.conf.d/tizen.conf 
/home/storycompiler/tizen-sdk/tools/efl-tools/lib
/usr/lib64
$ sudo ldconfig


그리고 다시 enventor를 실행하면 이번엔 libtasn1.so.3이 없다는 에러가 나옵니다.

$ ~/tizen-sdk/tools/enventor/bin/enventor 
/home/storycompiler/tizen-sdk/tools/enventor/bin/enventor: error while loading shared libraries: libtasn1.so.3: cannot open shared object file: No such file or directory


이번에도 libtasn1.so.3을 여기에서 다운로드 받습니다.

위의 사이트가 열리지 않을 경우에 대비하여 64비트 우분투 15.04용 rpm을 첨부합니다.

libtasn1-3-1.2-31.2.x86_64.rpm

$ sudo rpm -Uvh --force --nodeps libtasn1-3-1.2-31.2.x86_64.rpm 
rpm: RPM should not be used directly install RPM packages, use Alien instead!
rpm: However assuming you know what you are doing...
경고: libtasn1-3-1.2-31.2.x86_64.rpm: Header V3 DSA/SHA1 Signature, key ID 92fbd4a7: NOKEY
준비 중...                         ################################# [100%]
Updating / installing...
   1:libtasn1-3-1.2-31.2              ################################# [100%]


위의 파일마저 제대로 설치하였다면, 이제는 enventor를 실행할 수 있습니다.


자, 이제 다시 개발의 재미에 빠져보시죠.

그럼 좋은 하루 보내세요~

끝_


* References

http://rpmfind.net/linux/rpm2html/search.php?query=libgnutls.so.26%28%29%2864bit%29

http://rpmfind.net/linux/rpm2html/search.php?query=libgcrypt.so.11%28%29%2864bit%29

http://rpm.pbone.net/index.php3/stat/4/idpl/23618373/dir/redhat_el_5/com/libtasn1-3-1.2-31.2.x86_64.rpm.html


2015년 TDC 타이젠 개발자 회의 일정이 확정되었습니다.

시간 : 9월 17일 ~ 18일

장소 : 중국 광둥성 선전시 푸텐구 쉐라톤 호텔



위치를 보니 역대 TDC 중 가장 가까운 곳에서 열리네요.

홍콩 바로 위가 광둥성 선전시이니 비행기로 3시간 30분 거리입니다.


7월말에 열리는 TDS 타이젠 개발자 모임은 인도 벵갈루루에서 열리고,

9월에 열리는 TDC 타이젠 개발자 회의는 중국 선전시에서 열리는군요.

2015년 타이젠은 북미에서 아시아로 시선을 돌렸습니다.

이왕 아시아를 순회하는 김에 한국에서 다음 제품이 출시되길 기원합니다.

저가 스마트폰 대신 하이엔드 모바일 제품으로 성능을 만천하에 보여주면 좋겠군요.


TDC 2015의 슬로건은,

"타이젠, 모든 것을 연결하는 최고의 방법"

'연결'을 주제로 잡고 있습니다.


위의 키워드로도 흥미진진한 얘기거리가 떠오르네요.

타이젠 공식 사이트에서는 TDC의 세션을 등록을 할 수 있습니다.

7월 3일부터 세션등록을 시작하여 8월 2일까지 받습니다.

이렇게 등록된 세션들은 8월 10일에 스케쥴표와 함께 나타나겠지요.


타이젠 위원회는 크게 아래와 같은 주제를 공모하고 있습니다.

- 타이젠 프로젝트 및 플랫폼 개발

- 앱 개발, 운용, 에코시스템

- 기기 개발, 타이젠 프로파일, IoT


타이젠에 관심있는 분들은 서브미션을 직접 개설하여 연사가 되실 수 있습니다.

혹은 TDC 등록 절차를 통해 서브미션에 청중으로 참여할 수도 있습니다.

7월 인도행보다는 9월 홍콩행이 더욱 구미가 당깁니다.

늦은 여름 휴가를 겸하여 다녀오는 것도 좋겠군요.

https://www.regonline.com/Register/Checkin.aspx?EventID=1732778

위의 사이트에서 등록할 수 있습니다.



현재 환율로 2만 7천여원으로 등록 가능합니다..

타이젠은 에코시스템을 키우기 위해 최대한 저렴한 가격으로 행사를 지원하고 있습니다.

2만 7천원이면... 공짜나 다름없죠.


중국에서 열리는 행사이니만큼 중국어로 진행되겠군요.

영어로 등록할 수 있는 버튼이 있는 것으로 보아 영어권 개발자를 위한 배려도 있겠지요.


세션이 등록되어 확정되면 다시 한 번 소식을 전하도록 하겠습니다.

그럼 좋은 하루 보내세요~


끝_


2015. 7. 1 현재,

타이젠 SDK는 우분투 14.04까지 공식지원합니다.

우분투 최신버전인 15.04는 차기 SDK에서 지원하겠죠.


이미 우분투 15.04를 설치하신 분은,

타이젠 툴을 설치하면서 에러를 마주하실지도 모릅니다.



안녕하세요, Tizen 개발자 윤진입니다.


우분투 15.04를 설치하고 타이젠 gbs 툴을 설치하였습니다.

gbs 설치는 아래 포스팅을 참고하시면 됩니다.

[Tizen] 우분투에 타이젠 플랫폼 툴인 gbs & sdb 설치해보기

[Tizen] 타이젠 gbs의 모든 것


하지만 gbs를 설치하고 실행하면 아래와 같은 에러를 마주하실 수 있습니다.

$ gbs
Traceback (most recent call last):
  File "/usr/bin/gbs", line 30, in <module>
    from gitbuildsys import cmd_build
  File "/usr/lib/pymodules/python2.7/gitbuildsys/cmd_build.py", line 33, in <module>
    from gitbuildsys.cmd_export import get_packaging_dir, config_is_true
  File "/usr/lib/pymodules/python2.7/gitbuildsys/cmd_export.py", line 34, in <module>
    from gbp.scripts.buildpackage_rpm import main as gbp_build
ImportError: No module named buildpackage_rpm


이 에러는 buildpackage_rpm 모듈이 없어서 발생합니다.

buildpackage_rpm 모듈은 tizen에서 제공하는 git-buildpackage-rpm(0.6.15 버전)에서 설치됩니다.

하지만, 같은 패키지(0.6.22 버전)가 우분투 15.04에도 정식 탑재되었죠.

안타깝게도 우분투에 설치된 gbp의 버전이 높지만, tizen.org에서 필요로 하는 기능은 없습니다.

따라서 우분투에 설치된 gbp를 downgrade해야합니다.


우분투의 특정 패키지를 downgrade를 하기 위해서는,

과거 한 시점으로 Pinning해서 그 시점의 패키지를 받도록 해야합니다.

간단한 설정파일을 하나 만들어주세요.

$ vi /etc/apt/preferences.d/tizen
Package: *
Pin: origin download.tizen.org
Pin-Priority: 1000

위처럼 만들어 놓으면, 타이젠에서 제공하는 패키지를 우선적으로 설치하게 됩니다.


이제 gbs를 위한 패키지를 설치할 차례입니다.

좀 전에 설정한 pinning을 아래처럼 반영합니다.

$ sudo apt-get update


그리고 필요한 패키지를 아래처럼 설치하면 됩니다.

생각보다 많은 패키지들이 다운그레이드됩니다.

$ sudo apt-get install deltarpm createrepo git-buildpackage-common git-buildpackage-rpm git-buildpackage osc
패키지 목록을 읽는 중입니다... 완료
의존성 트리를 만드는 중입니다      
상태 정보를 읽는 중입니다... 완료
createrepo 패키지는 이미 최신 버전입니다.
createrepo 패키지 수동설치로 지정합니다.
deltarpm 패키지는 이미 최신 버전입니다.
deltarpm 패키지 수동설치로 지정합니다.
git-buildpackage 패키지는 이미 최신 버전입니다.
git-buildpackage-rpm 패키지는 이미 최신 버전입니다.
git-buildpackage-rpm 패키지 수동설치로 지정합니다.
osc 패키지는 이미 최신 버전입니다.
osc 패키지 수동설치로 지정합니다.
다음 패키지가 자동으로 설치되었지만 더 이상 필요하지 않습니다:
  libatk-wrapper-java libatk-wrapper-java-jni libgconf2-4 libgif4 libice-dev
  libpthread-stubs0-dev libsm-dev libx11-dev libx11-doc libxau-dev libxcb1-dev libxdmcp-dev
  libxt-dev python-dateutil python-deltarpm python-keyring python-secretstorage
  x11proto-core-dev x11proto-input-dev x11proto-kb-dev xorg-sgml-doctools xtrans-dev
Use 'apt-get autoremove' to remove them.
제안하는 패키지:
  python-notify zipmerge
다음 새 패키지를 설치할 것입니다:
  git-buildpackage-common
0개 업그레이드, 1개 새로 설치, 0개 제거 및 1개 업그레이드 안 함.
149개를 완전히 설치하지 못했거나 지움.
0 바이트/292 k바이트 아카이브를 받아야 합니다.
이 작업 후 3,944 k바이트의 디스크 공간을 더 사용하게 됩니다.
계속 하시겠습니까? [Y/n] y
경고: 다음 패키지를 인증할 수 없습니다!
  git-buildpackage-common
확인하지 않고 패키지를 설치하시겠습니까? [y/N] y


설치 직후부터 gbs를 사용하실 수 있습니다.

$ gbs
Usage: gbs [GLOBAL-OPTS] SUBCOMMAND [OPTS]
           ...

gbs - the command line tool for Tizen package developers

Global Options:
  -h, --help            show this help message and exit
  -V, --version         show program's version number and exit
  -c CONF, --conf CONF  specify config file for gbs
  -d, --debug           debug output
  -v, --verbose         verbose output

Subcommands:
  changelog (ch)        update the changelog file with the git commit messages
  remotebuild (rb)      remote build package
  devel                 Manage devel branches
  export (ex)           export files and prepare for build
  chroot (chr)          chroot to build root
  import (im)           import spec file/source rpm/tar ball to git repository
  clone (cl)            Clone a git repository
  createimage (cr)      create image using ks file
  submit (sr)           submit tag to gerrit and trigger building in OBS
  pull                  Update a package git repository
  build (lb)            local build package

Try 'gbs SUBCOMMAND --help' for help on a specific subcommand.


그럼 좋은 하루 보내세요~

끝_

데스크탑 PC를 한 대 사서 우분투를 설치하였습니다.

가물가물한 기억을 더듬어서 환경설정을 하고 있습니다.

기본적인 환경설정에만 꼬박 하루가 지나가네요.


사실 윈도우 PC에는 이미 타이젠 SDK가 설치되어 있습니다.

하지만, 윈도우에서는 개발하는 손맛이 나질 않아 우분투에도 타이젠 SDK를 설치하려고 합니다.

타이젠 SDK를 설치하는 과정 자체에는 어려운 것이 전혀 없으나,

타이젠 SDK를 위한 우선 설치해야하는 것들이 있습니다.



안녕하세요, Tizen 개발자 윤진입니다.


만약 타이젠 SDK를 윈도우에 설치하시려면 아래 포스팅을 참고해주세요.

[Tizen] 타이젠 SDK 윈도우에 설치하기, "생각보다 쉽다"


타이젠 SDK는 이클립스를 사용하고 있기 때문에 오라클 JDK를 설치해야합니다.

우분투 환경에서는 open jdk도 받을 수 있으나,

open jdk로는 이클립스를 구동할 수 없습니다.

반드시 오라클에서 배포하는 JDK 받으셔야 이클립스를 제대로 실행할 수 있습니다.


여기를 눌러 오라클 홈페이지에 들어갑니다.

2015. 6. 30 현재 가장 최신은 Java SE Development Kit 8u45 버전입니다.



위의 화면에서 "Accept License Agreement"를 눌러서 라이센스에 동의해주세요.

라이센스에 동의해야만 jdk를 다운로드 받을 수 있습니다.

우분투는 Linux x86(32비트)이나 Linux x64(64비트)를 다운로드 받으셔야 합니다.

여기서는 64비트용 jdk-8u45-linux-x64.tar.gz를 다운로드 받겠습니다.

오라클이 서버를 만드는 회사이니 만큼 다운로드 하나는 확실하게 그리고 빠르게 되네요. :)


다운로드가 완료되었으면 우선 압축부터 풀어야 합니다.

$ tar xvzf jdk-8u45-linux-x64.tar.gz


그리고 압축이 풀린 디렉토리를 통째로 옮깁니다.

$ sudo mkdir -p /usr/lib/jvm/jre1.8.0
$ sudo mv jdk1.8.0_45/* /usr/lib/jvm/jre1.8.0/


자바는 openjdk와 oracle jdk처럼 버전이 다양하기 때문에,

좀 전에 다운로드받은 oracle jdk가 실행될 수 있도록 설정해줍니다.

$ sudo update-alternatives --install <link> <name> <path> <priority>
$ sudo update-alternatives --install /usr/bin/java java /usr/lib/jvm/jre1.8.0/bin/java 0

곧, /usr/bin/java에 좀 전에 다운로드받은 /usr/lib/jvm/jre1.8.0/bin/java의 링크를 만들어두는 것이지요.


그리고 우분투 파이어폭스에서도 자바를 사용할 수 있도록 자바플러그인을 복사합니다.

$ mkdir ~/.mozilla/plugins
$ ln -s /usr/lib/jvm/jre1.8.0/lib/i386/libnpjp2.so ~/.mozilla/plugins/


마지막으로 추가로 필요한 패키지 몇 개를 설치합니다.

$ sudo apt-get install expect gtk2-engines-pixbuf libgnome2-0 qemu-user-static libwebkitgtk-1.0-0 gettext gksu module-init-tools libudev-dev libsdl1.2debian ruby
패키지 목록을 읽는 중입니다... 완료
의존성 트리를 만드는 중입니다      
상태 정보를 읽는 중입니다... 완료
gettext 패키지는 이미 최신 버전입니다.
libgnome2-0 패키지는 이미 최신 버전입니다.
libgnome2-0 패키지 수동설치로 지정합니다.
module-init-tools 패키지는 이미 최신 버전입니다.
다음 패키지가 자동으로 설치되었지만 더 이상 필요하지 않습니다:
  libatk-wrapper-java libatk-wrapper-java-jni libgconf2-4 libgif4 libice-dev
  libpthread-stubs0-dev libsm-dev libx11-dev libx11-doc libxau-dev libxcb1-dev libxdmcp-dev
  libxt-dev x11proto-core-dev x11proto-input-dev x11proto-kb-dev xorg-sgml-doctools
  xtrans-dev
Use 'apt-get autoremove' to remove them.
다음 패키지를 더 설치할 것입니다:
  libgksu2-0 libjavascriptcoregtk-1.0-0 libudev1 libwebkitgtk-1.0-common tcl-expect udev
다음 새 패키지를 설치할 것입니다:
  expect gksu gtk2-engines-pixbuf libgksu2-0 libjavascriptcoregtk-1.0-0 libudev-dev
  libwebkitgtk-1.0-0 libwebkitgtk-1.0-common qemu-user-static tcl-expect
다음 패키지를 업그레이드할 것입니다:
  libudev1 udev
2개 업그레이드, 10개 새로 설치, 0개 제거 및 146개 업그레이드 안 함.
18.6 M바이트/19.6 M바이트 아카이브를 받아야 합니다.
이 작업 후 130 M바이트의 디스크 공간을 더 사용하게 됩니다.
계속 하시겠습니까? [Y/n]


이제 타이젠 SDK 설치를 위한 준비가 끝났습니다.

타이젠 홈페이지에 방문하여 SDK를 다운로드 받습니다.



DOWNLOAD THE SDK 버튼을 누르면 Tizen SDK를 받을 수 있는 페이지가 나옵니다.

아래 페이지에 표시된 화살표 링크를 눌러 운영체제에 맞는 SDK를 고를 수 있습니다.



여기서는 64비트 우분투용 tizen-sdk_2.3.63_ubuntu-64.bin를 다운로드 받겠습니다.

다운로드 받으시고 실행권한을 주셔야 합니다.

$ chmod +x tizen-sdk_2.3.63_ubuntu-64.bin

그리고 바로 실행해보시지요.


만약, 설치가 여전히 안된다면 openjdk 때문일겁니다.

openjdk를 사용하실 필요가 없다면 지우셔도 무방합니다.

$ sudo rm -rf /usr/lib/jvm/java-8-openjdk-amd64



Install > Advanced에 들어가서,

- Package server : SDK이미지를 서버에서 내려받거나,

- SDK Image : 이미 다운로드받은 이미지로 설치할 수 있습니다.

여기서는 Package server를 선택합니다.

그리고 Install을 누르면 다음 항목으로 넘어갑니다.



여기서는 mobile & wearable을 모두 설치할 것이므로 Custom 버튼을 누릅니다.

라디오 버튼이 체크박스로 바뀌면,

Mobile-2.3 / Wearable-2.3 / Other tools를 모두 체크합니다.

다음으로 넘어가면 라이센스 항목이 나옵니다.



라이센스를 자세히 읽어보시고...

I agree 버튼을 눌러 다음으로 넘어가세요.



기본적으로 Installation Location은 ~/tizen-sdk로 되어 있고,

Data Location은 ~/tizen-sdk-data로 되어 있습니다.

다른 경로를 원하시면 변경하실 수 있습니다.

여기서는 그대로 사용하도록 하겠습니다.

이제 Install 버튼을 누르면 설치가 됩니다.

서버로부터 패키지를 다운로드 받고 설치하기 때문에 서버 상태에 따라 시간이 많이 걸릴 수도 있습니다.


설치가 완료되면 바로 Tizen SDK를 사용하실 수 있습니다.

개발의 재미에 빠져보세요~


끝_

  1. 앨리삵 2015.10.05 20:25 신고

    우분투에서 타이젠 빌드하려고 고군분투중입니다.
    한줄기 빛과 같은 블로그 포스팅 감사해요 ㅠㅅㅠ

  2. 정말 멋진 홈피를 가지고 계십니다! :)
    그래픽스 전문가에게 직접 배운다는 생각으로 열심히 방문해야겠습니다. 하핫.



일시 : 2015년 7월 30일 ~ 31일

장소 : 인도 남부 벵갈루루 리츠칼튼 호텔

웹사이트 : http://tizendevsummit.com/index.html



인도 남부 벵갈루루의 위치는 위의 지도에서 확인하실 수 있습니다.

7월 30일 기준으로 리츠칼튼 호텔 1박에 28만원입니다.

아직 방이 여유가 있으니 예약하고 싶어지는군요.


타이젠 개발자 회담은 앱 & 플랫폼 개발자를 위한 행사입니다.

올해 인도에서 출시된 Mobile Z1은 물론이고 Wearable, TV, IoT까지 행사내용에 포함되어 있습니다.

앱개발자, 플랫폼 디자이너, ISV업체, OEM업체, 하드웨어업체, 소프트웨어업체 등 기술 컨텐츠에 관심을 가질만한 사람은 누구나 참석할 수 있습니다.

C언어 기반의 Native앱을 개발하는 개발자와 HTML5 기반의 웹앱을 개발하는 개발자 모두에게 이틀동안 타이젠에 대해 설명하는 자리가 되겠군요.


이틀간 열리는 행사에서 흥미로운 주제를 몇 개 뽑아보았습니다.

첫날 점심시간 이후에 열리는 "Breakthrough Games with Tizen"이 흥미롭습니다.



삼성전자 타이젠 R&D 그래픽스팀의 최성열 연구원께서 발표하시는군요.

OpenGl-ES와 DALi 툴킷으로 게임그래픽개발에 대해 설명하는 자리가 되겠네요.


같은 시간에 열리는 다른 세션도 구미가 당깁니다.

드디어 TV SDK가 나오나 봅니다.

삼성전자 타이젠 스마트 TV가 국무총리 대상을 받았는데요.

타이젠 TV에 올라가는 앱을 개발하는 SDK에 대한 세션입니다.

SDK 환경 및 가이드를 해주는 자리가 되겠네요.

C언어 기반의 Native 앱보다는 HTML5 기반의 웹앱을 위한 세션으로 보입니다.


다음 시간에 열리는 세션 중에 웨어러블 세션이 있습니다.

타이젠 플랫폼은 이미 삼성 기어 시리즈에 탑재되어 있습니다.

웨어러블 플랫폼의 주요 기능에 대해 전파하는 자리가 되겠네요.

이 세션 역시 웹앱 위주로 설명하는 자리가 되겠네요.


16:30분부터는 타이젠 UI Framework인 EFL과 DALi에 대해 설명하는 자리도 있습니다.

타이젠 네이티브앱에서 사용하는 EFL과 DALi를 엿볼 수 있습니다.

단지 UI 컴포넌트를 설명하는 자리는 아니고,

scene graph나 opengl 가속렌더링, mainloop, thread 등에 대해 훑어보는군요.

게다가 여기에 DALi라는 3D UI 엔진도 소개할 예정입니다.

1시간이 무척이나 짧아보이네요.


이제 둘째날로 넘어갑니다.

둘째날 아침 10시에 타이젠 플랫폼의 퍼포먼스에 대한 세션이 있습니다.

Z1 스마트폰의 사양을 생각할 때,

부팅속도가 상당히 최적화되어 있다고 생각하는데요.

모바일이나 웨어러블 앱을 최적화하는 툴&팁을 공유하는 자리가 되겠군요.


그 다음 시간에는 IoTivity에 대한 세션도 있습니다.

IoTivity의 API셋을 소개하는 자리가 될 것으로 보이는데요.

Things & 센서 관리 서비스를 엿볼 수 있겠군요.

Protocol Manager Service를 사용하여 OIC 규약에 맞게 다양한 디바이스들을 연결할 수 있다고 하니 실체가 궁금해집니다.

IoTivity는 삼성전자가 리드하고 있는 만큼,

타이젠 플랫폼과도 거리를 좁히고 있나보군요.


둘째날 점심에 열리는 세션에서 타이젠의 방향을 볼 수 있습니다.

타이젠앱은 모바일, 웨어러블, TV에서 동작합니다.

다양한 프로파일, 특히 TV까지 포괄하는 플랫폼은 타이젠이 처음이겠군요.

마무리하는 세션이니만큼 타 플랫폼과 차별화되는 특장점들이 나와주겠군요.


이틀간 열리는 짧은 행사입니다.

플랫폼을 설명하기에 이틀은 터무니없이 짧죠.

그렇지만, 타이젠을 미래의 먹거리로 생각하는 사람에게는 좋은 시작이 되겠네요.


Early bird로 1,999루피(35,000원)에 입장권을 구매할 수 있습니다.

이 정도면 거의 공짜...

이참에 휴가내어 인도로 놀러가야겠군요.


끝_

  1. 김재천 2015.06.27 19:15

    잘봤습니다^^

타이젠 네이티브 앱을 개발하려면 네이티브 API를 사용해야합니다.

그리고 일부 네이티브 API는 별도의 Privilege 권한이 있어야 사용할 수 있습니다.


타이젠 네이티브 API에 어떤 Privilege가 있는지 살펴보고,

어떤 식으로 관리되고 있는지 훔쳐보도록 하겠습니다.


Tizen 2.3으로 오픈된 소스를 기반으로 정리하였습니다.



안녕하세요, Tizen 개발자 윤진입니다.


타이젠 SDK에서 관리하는 Privilege를 찾아보았습니다.

git://review.tizen.org/sdk/doc/content의 master브랜치,

api-reference/native/tools/privilege_desc.txt 파일에 Privilege가 명시되어 있습니다.

privilege_desc.txt를 그대로 가져오고,

각각 한글로 간단하게 번역해두었습니다.


http://tizen.org/privilege/account.read
Allows the application to read accounts.
계정을 읽을 수 있습니다.

http://tizen.org/privilege/account.write   
Allows the application to create, update, and delete accounts.   
계정을 생성, 수정, 삭제할 수 있습니다.

http://tizen.org/privilege/alarm   
Allows the application to set an alarm and wake the device up at the scheduled time.   
알람을 설정하고 디바이스를 알람시간에 깨울 수 있습니다.

http://tizen.org/privilege/application.launch   
Allows the application to be opened conditionally or to open another application.   
앱을 상황에 맞게 열거나 다른 앱을 런칭할 수 있습니다.

http://tizen.org/privilege/appmanager.kill   
Allows the application to close another application.
다른 앱을 닫을 수 있습니다.

http://tizen.org/privilege/appmanager.launch   
Allows the application to manage another application opening conditionally.   
다른 앱을 조건에 맞게 열 수 있습니다.

http://tizen.org/privilege/appmanager.setting   
Allows the application to read and update default application preferences.   
디폴트 앱의 설정을 읽고 수정할 수 있습니다.

http://tizen.org/privilege/appsetting   
Allows the application to manage application settings.
앱의 설정을 관리할 수 있습니다.    

http://tizen.org/privilege/appusage   
Allows the application to receive notifications about foreground application changes.   
foreground에 있는 앱의 변화를 받을 수 있습니다.

http://tizen.org/privilege/appwidgetprovider.install   
Allows the application to add Dynamic Box to the home screen.   
다이나믹박스를 홈스크린에 추가할 수 있습니다.

http://tizen.org/privilege/audiomanager.route   
Allows the application to set audio input and output routes and receive notifications about route events.   
오디오 입출력 경로를 설정하고 경로이벤트에 대한 알림을 받을 수 있습니다.

http://tizen.org/privilege/audiorecorder   
Allows the application to manage audio recording.   
오디오레코딩을 관리할 수 있습니다.

http://tizen.org/privilege/bluetooth.admin   
Allows the application to change Bluetooth settings, such as turning Bluetooth on or off, and setting the local device name.   
블루투스 설정을 변경할 수 있습니다. - 블루투스 on / off, 로컬 디바이스 이름 변경

http://tizen.org/privilege/bluetooth.gap   
Allows the application to use the Generic Access Profile (GAP), for example, to scan for and pair devices.   
Generic Access Profile(GAP)을 사용할 수 있습니다. - 페어 디바이스를 스캔하기 등

http://tizen.org/privilege/bluetooth.health   
Allows the application to use the Health Device Profile (HDP), for example, to send health data.   
Health Device Profile을 사용할 수 있습니다. - 헬스 데이타 보내기 등

http://tizen.org/privilege/bluetooth.opp   
Allows the application to use the Object Push Profile (OPP), for example, to send files.
Object Push Profile을 사용할 수 있습니다. - 파일 보내기 등

http://tizen.org/privilege/bluetooth.spp   
Allows the application to use the Serial Port Profile (SPP), for example, to send serial data.   
Serial Port Profile을 사용할 수 있습니다. - 시리얼 데이타 보내기 등

http://tizen.org/privilege/bluetoothmanager   
Allows the application to change Bluetooth system settings related to privacy and security, such as the visible mode.   
블루투스 시스템 설정(프라이버시, 시큐리티)을 변경할 수 있습니다. - visible 모드 등

http://tizen.org/privilege/bookmark.read   
Allows the application to read bookmarks.   
북마크를 읽을 수 있습니다.

http://tizen.org/privilege/bookmark.write   
Allows the application to create, update, and delete bookmarks.   
북마크를 생성, 수정, 삭제할 수 있습니다.

http://tizen.org/privilege/calendar.read   
Allows the application to read schedule and task information.   
스케쥴과 업무 정보를 읽을 수 있습니다.

http://tizen.org/privilege/calendar.write
Allows the application to create, update, and delete schedule and task information.   
스캐쥴과 업무 정보를 생성, 수정, 삭제할 수 있습니다.

http://tizen.org/privilege/callforward
Allows the application to control the call forwarding service.   
콜 포워딩 서비스를 컨트롤할 수 있습니다.

http://tizen.org/privilege/camera
Allows the application to manage device cameras to preview and capture pictures.
프리뷰를 보고 사진을 찍을 수 있습니다.

http://tizen.org/privilege/cellbroadcast
Allows the application to manage the Cell Broadcast Service (CBS).   
Cell Broadcast Service를 관리할 수 있습니다.

http://tizen.org/privilege/certificate.read
Allows the application to read certificates.   
인증서를 읽을 수 있습니다.

http://tizen.org/privilege/certificate.write
Allows the application to add, update, and delete certificates.   
인증서를 추가, 수정, 삭제할 수 있습니다.

http://tizen.org/privilege/contact.read
Allows the application to read contacts.
연락처 정보를 읽을 수 있습니다.

http://tizen.org/privilege/contact.write
Allows the application to add, update, and delete contacts.   
연락처 정보를 추가, 수정, 삭제할 수 있습니다.

http://tizen.org/privilege/content.read
Allows the application to read content.   
컨텐츠를 읽을 수 있습니다.

http://tizen.org/privilege/content.write
Allows the application to create, update, and delete content.   
컨텐츠를 추가, 수정, 삭제할 수 있습니다.

http://tizen.org/privilege/customnetaccount
Allows the application to use the Internet with a specified bearer.
특정 배러와 함께 인터넷을 사용할 수 있습니다.

http://tizen.org/privilege/datacontrol.consumer
Allows the application to access specific data exported by other applications.
다른 앱이 준 데이타에 접근할 수 있습니다.

http://tizen.org/privilege/dns
Allows the application to provide the Domain Name Service (DNS).   
Domain Name Service를 제공할 수 있습니다.

http://tizen.org/privilege/download
Allows the application to manage HTTP downloads.   
HTTP 다운로드를 관리할 수 있습니다.

http://tizen.org/privilege/geolocationpermission.read
Allows the application to read geolocation permissions.   
지리정보 권한을 읽을 수 있습니다.

http://tizen.org/privilege/geolocationpermission.write
Allows the application to delete geolocation permissions.   
지리정보 권한을 지울 수 있습니다.

http://tizen.org/privilege/http
Allows the application to communicate with the HTTP server.   
HTTP 서버와 통신할 수 있습니다.

http://tizen.org/privilege/ime
Allows the application to provide a way to input characters and symbols into an associated input field.   
소프트웨어 키보드를 제공할 수 있습니다.

http://tizen.org/privilege/imemanager
Allows the application to manage the installed input methods.    
설치된 소프트웨어 키보드를 관리할 수 있습니다.


http://tizen.org/privilege/inputmanager
Allows the application to generate touch and key events, and capture screens.    
터치, 키 이벤트를 만들고 스크린을 캡쳐할 수 있습니다.


http://tizen.org/privilege/location
Allows the application to use the user location data.  
유저의 지리데이터를 이용할 수 있습니다.  

http://tizen.org/privilege/lockmanager
Allows the application to unlock the device.   
디바이스를 언락할 수 있습니다.

http://tizen.org/privilege/messaging.read
Allows the application to receive messages, and to retrieve messages from the message boxes.   
메시지를 받고 메시지박스에서 메시지를 긁어올 수 있습니다.

http://tizen.org/privilege/messaging.write
Allows the application to write SMS, MMS, and email messages.   
SMS, MMS와 이메일을 쓸 수 있습니다.

http://tizen.org/privilege/netstatisticsmanager
Allows the application to reset network statistics.   
네트워크 정보를 리셋할 수 있습니다.

http://tizen.org/privilege/network.account
Allows the application to manage network accounts.   
네트워크 계정을 관리할 수 있습니다.

http://tizen.org/privilege/network.connection
Allows the application to manage network connections.   
네트워크 커넥션을 관리할 수 있습니다.

http://tizen.org/privilege/network.statistics
Allows the application to read network statistics.   
네트워크 정보를 읽을 수 있습니다.

http://tizen.org/privilege/networkmanager
Allows the application to update system network accounts.
시스템 네트워크 계정을 수정할 수 있습니다.

http://tizen.org/privilege/nfc.admin
Allows the application to change NFC settings, such as turning NFC on or off.   
NFC 설정을 변경할 수 있습니다. - NFC on / off

http://tizen.org/privilege/nfc.common
Allows the application to use NFC common features.   
NFC 공통 기능을 사용할 수 있습니다.

http://tizen.org/privilege/nfc.p2p
Allows the application to push NFC messages to other devices.   
다른 기기에 NFC 메시지를 푸쉬할 수 있습니다.

http://tizen.org/privilege/nfc.tag
Allows the application to read and write NFC tag information.   
NFC 태그정보를 읽고 쓸 수 있습니다.

http://tizen.org/privilege/nfcmanager
Allows the application to change NFC system settings, such as turning on or off reserved push, which sends predefined NDEF messages.   
NFC 시스템 설정을 변경할 수 있습니다. - 예약 푸쉬를 on / off 하기

http://tizen.org/privilege/notification
Allows the application to provide user notifications, such as messages and badges.   
유저 알림을 제공할 수 있습니다. - 메시지나 배지

http://tizen.org/privilege/package.info
Allows the application to receive package information.   
패키지 정보를 받을 수 있습니다.

http://tizen.org/privilege/packagemanager.info
Allows the application to receive detailed package information.   
자세한 패키지 정보를 받을 수 있습니다.

http://tizen.org/privilege/packagemanager.install
Allows the application to install or uninstall application packages.   
앱 패키지를 설치 혹은 삭제할 수 있습니다.

http://tizen.org/privilege/packagemanager.setting
Allows the application to set package configurations.   
패키지 설정값을 변경할 수 있습니다.

http://tizen.org/privilege/power
Allows the application to hold and control power states.   
파워 상태를 유지하거나 조절할 수 있습니다.

http://tizen.org/privilege/privacymanager.read
Allows the application to read privacy settings.   
프라이버시 설정값을 읽을 수 있습니다.

http://tizen.org/privilege/privacymanager.write
Allows the application to change privacy settings.   
프라이버시 설정을 변경할 수 있습니다.  

http://tizen.org/privilege/privilegemanager.read
Allows the application to read privilege information.   
프라이버스 정보를 읽을 수 있습니다.

http://tizen.org/privilege/push
Allows the application to receive push notifications.   
푸쉬 알림을 받을 수 있습니다.

http://tizen.org/privilege/secureelement
Allows the application to access to secure smart card chip such as UICC/SIM, embedded secure element, or secure SD card.   
UICC/SIM 카드에 접근할 수 있습니다.

http://tizen.org/privilege/setting
Allows the application to update or read user settings.   
유저 설정을 읽거나 수정할 수 있습니다.

http://tizen.org/privilege/settingmanager.read
Allows the application to read security or privacy settings.   
시큐리티나 프라이버시 설정을 읽을 수 있습니다.

http://tizen.org/privilege/settingmanager.write
Allows the application to change security or privacy settings.   
시큐리티나 프라이버시 설정을 변경할 수 있습니다.

http://tizen.org/privilege/shortcut.install
Allows the application to add and remove shortcuts from the home screen.   
홈스크린에서 숏컷을 추가 혹은 삭제할 수 있습니다.

http://tizen.org/privilege/smstrigger
Allows the application to receive SMS messages from a specified port.
특정 포트로부터 SMS 메시지를 받을 수 있습니다.

http://tizen.org/privilege/socket
Allows the application to communicate with other devices and servers.
다른 디바이스나 서버와 통신할 수 있습니다.

http://tizen.org/privilege/system
Allows the application to access system information.
시스템 정보에 접근할 수 있습니다.

http://tizen.org/privilege/systemmanager
Allows the application to access secure system information.
보안 시스템 정보에 접근할 수 있습니다.

http://tizen.org/privilege/telephony
Allows the application to retrieve telephony information, such as network, SIM, and call details.
텔레포니 정보를 긁어올 수 있습니다. - Network, SIM, Call 상제정보

http://tizen.org/privilege/telephonymanager
Allows the application to configure the mobile networks.
모바일 네트워크를 설정할 수 있습니다.


http://tizen.org/privilege/uimanager
Allows the application to manage UI properties.   
UI 속성을 관리할 수 있습니다.

http://tizen.org/privilege/userprofile.read
Allows the application to read the user profile.
유저 프로파일을 읽을 수 있습니다.

http://tizen.org/privilege/userprofile.write
Allows the application to manage the user profile.
유저 프로파일을 관리할 수 있습니다.

http://tizen.org/privilege/vibrator
Allows the application to turn on and use vibrate.
진동키능을 켜겨나 사용할 수 있습니다.

http://tizen.org/privilege/videorecorder
Allows the application to manage video recording with the camera.
카메라를 사용하여 비디오 녹화를 할 수 있습니다.

http://tizen.org/privilege/wappush
Allows the application to manage WAP push messages.
WAP 푸쉬 메시지를 관리할 수 있습니다.

http://tizen.org/privilege/web.privacy
Allows the application to manage the user data stored by the Web control or browser.
웹컨트롤이나 브라우저에서 저장된 유저데이터를 관리할 수 있습니다.

http://tizen.org/privilege/web.service
Allows the application to display Web content or use the Web content-related API.
웹컨텐트를 표시하고 웹컨텐트 관련 함수를 사용할 수 있습니다.

http://tizen.org/privilege/wifi.admin
Allows the application to manage Wi-Fi on the device, such as turning Wi-Fi on or off, and connecting to AP.
Wi-Fi를 관리할 수 있습니다. - 와이파이를 on / off 하고, AP에 접속하기

http://tizen.org/privilege/wifi.read
Allows the application to request Wi-Fi information.
Wi-Fi 정보를 요청할 수 있습니다.

http://tizen.org/privilege/wifi.wifidirect.admin
Allows the application to manage Wi-Fi Direct on the device.
Wi-Fi Direct 기능을 관리할 수 있습니다.

http://tizen.org/privilege/wifi.wifidirect.read
Allows the application to request Wi-Fi Direct information.
Wi-Fi Direct 정보를 요청할 수 있습니다.

http://tizen.org/privilege/wifimanager
Allows the application to manage the Wi-Fi system settings, such as updating AP information.
Wi-Fi 시스템 설정을 관리할 수 있습니다. - AP 정보 갱신 등


위에서 기술된 Privilege를 앱에서 사용하는 것이지요.

플랫폼 버전마다 사용할 수 있는 Privilege는 다를 수 있습니다.


SDK에서 개발할 때는,

- Project Explorer에서 자신의 프로젝트 내에 있는 tizen-manifest.xml 선택

- Tizen Manifest Editor에서 Privileges 탭 선택

- Add 버튼을 눌러 Privilege를 추가할 수 있습니다.



SDK 외부에서 개발할 경우에는,

각 앱의 xml파일에 직접 Privilege를 기술해야 합니다.


<?xml version="1.0" encoding="utf-8" ?>
<manifest xmlns="http://tizen.org/ns/packages" package="org.tizen.data-provider-slave" version="1.0.0" install-location="auto" support-mode="screen-reader">
    <!-- ... 생략 ... -->
    <ui-application appid="org.tizen.data-provider-slave" exec="/usr/apps/org.tizen.data-provider-slave/bin/data-provider-slave" nodisplay="true" multiple="true" type="capp" taskmanage="false">
    <!-- ... 생략 ... -->
    </ui-application>
    <privileges>
        <privilege>http://tizen.org/privilege/location</privilege>
        <privilege>http://developer.samsung.com/tizen/privilege/privacymanager.read</privilege> <!-- weather -->
    </privileges>
    <!-- ... 생략 ... -->
</manifest>


위의 코드는 git://review.tizen.org/apps/livebox/data-provider-slave의 tizen_2.3 브랜치,

org.tizen.data-provider-slave.xml 파일에서 따왔습니다.

SDK 외부에서 개발하는 앱은 위처럼 자신에게 필요한 Privilege를 xml 파일에 직접 추가해야 하지요.


Security/Tizen 2.X smack-privilege-config


앱에 추가된 Privilege는,

앱이 설치되는 시점에 Privilege 레벨에서 Smack 레벨로 변경됩니다.


git://review.tizen.org/framework/security/smack-privilege-config의 tizen_2.3 브랜치,

permissions_mobile/permissions_2_3_0 디렉토리에는 수많은 *.smack 파일이 있습니다.

그 중 EFL_org.tizen.privilege.camera.smack 파일을 열어보겠습니다.


~APP~ device::camera rw----
~APP~ mm_qcamera_daemon -w----
~APP~ privilege::tizen::camera rw----
~APP~ system::vconf_multimedia rw----


카메라를 사용하기 위해 필요한 스맥룰이 명시되어 있습니다.

~APP~은 위의 privilege를 설정한 앱의 스맥레이블로 치환될 것입니다.

간단히 내용을 살펴보면,

device::camera에 접근하기 위한 읽고 쓰는 권한,

mm_qcamera_daemon에 쓰기 권한,

privilege::tizen::camera를 읽고 쓰는 권한,

system::vconf_multimedia를 읽고 쓰는 권한 등의 스맥권한을 부여합니다.


이렇게 부여된 스맥레이블은,

네이티브 API가 사용하는 파일/디렉토리 등에 접근할 수 있게 할겁니다.

만약 제대로된 스맥레이블 없이 파일/디렉토리에 접근하려하면 Permission denied 에러가 나오겠죠.


git://review.tizen.org/framework/security/privilege-checker의 tizen_2.3 브랜치,

capi/src/privilege_checker.c 소스를 살펴보면,

앱이 Privilege를 가지고 있는지 여부를 직접 체크하는 부분도 있습니다.


int privilege_checker_check_package_privilege(const char* package_id, const char* privilege_name)
{
    // ... 생략 ...
    //find privilege in cache
    for(i=0; i<g_cached_privileges_size; i++)
    {
        if(hash_value == g_cached_privileges[i].hash_value)
        {
            matched_index = i;
            ++matched_cnt;
        }
    }

    if(matched_cnt == 1){
        LOGD("Found cached hash privilege");
        return PRIV_CHECKER_ERR_NONE;

    }
    // ... 생략 ...
    LOGD("Not Found cached privilege");

    // ... 생략 ...
    res = pkgmgrinfo_pkginfo_foreach_privilege(handle, __privilege_checker_privilege_list_by_pkgid_cb, user_data);
    // ... 생략 ...

    TryReturn(g_isMached == true, PRIV_CHECKER_ERR_INVALID_PRIVILEGE, "[PRIV_CHECKER_ERR_INVALID_PRIVILEGE] %s privilege denied", privilege_name);

    return PRIV_CHECKER_ERR_NONE;
}

그래서 API를 수행할 때, API를 호출한 앱의 권한을 체크하여 수행여부를 결정하게 됩니다.

예를 들어,

git://review.tizen.org/framework/api/application의 tizen_2.3 브랜치,

app_control/app_control.c 소스를 보면 Call Operaion로 런칭요청이 온 경우 Privilege가 있는지 체크합니다.


int app_control_send_launch_request(app_control_h app_control, app_control_reply_cb callback, void *user_data)
{
    // ... 생략 ...
    // Check the privilege for call operation
    if (!strcmp(operation, APP_CONTROL_OPERATION_CALL))
    {
    // ... 생략 ...

        ret = privilege_checker_check_package_privilege(pkg_id, "http://tizen.org/privilege/call");
        pkgmgrinfo_appinfo_destroy_appinfo(app_info);
        if (ret != PRIV_CHECKER_ERR_NONE)
        {
            if (ret == PRIV_CHECKER_ERR_INVALID_PRIVILEGE)
            {
                return app_control_error(APP_CONTROL_ERROR_PERMISSION_DENIED, __FUNCTION__, "no privilege for Call operation");
            }
        }
    }
}


Privilege는 Smack으로 치환되어 관리될 수 있고,

Privilege 자체로 관리될 수도 있습니다.


끝_


* SMACK에 대한 이야기를 쌓아본다

http://storycompiler.tistory.com/51


* References

https://wiki.tizen.org/wiki/Security/Tizen_2.X_smack-privilege-config

https://wiki.tizen.org/wiki/Security/Tizen_2.X_cert-svc#Additional_certificate_service_APIs

웨어러블 디바이스가 하나둘씩 출시되고 있습니다.

삼성전자가 출시한 시계만 해도,

기어 1, 기어 Fit, 기어 2, 기어 S가 있습니다.

거기에 원형 디스플레이의 기어가 조만간 출시될 예정이죠.


이 원형 디스플레이를 가진 기어를 위한 SDK가 드디어 배포되었습니다.

Early Access Program으로 사전등록한 개발자에게 SDK를 배포하고 있네요.

사전등록을 위해서 까다로운 절차는 없습니다.

그저 Join만 하면 됩니다. :)



안녕하세요, Tizen 개발자 윤진입니다.


Early Access Program에 참여하라는 메일입니다.

"Get ready for the next gear"

문구 뒤로 보이는 원형 디스플레이가 눈에 띕니다.

원형 디스플레이에는 지역정보와 시간정보 그리고 날씨정보가 노출되어 있습니다.

기어가 보여줄 정보가 되겠군요.


메일의 하단부에 "Join us" 버튼이 있네요.

버튼을 누르니 아래 사이트에 접근하더군요.

http://developer.samsung.com/wearable/sub.html



위의 사이트에는 EAP에 참여하기 위해서는 삼성 개발자 계정이 있어야 한다고 언급되어 있습니다.

삼성계정이 없으면 이 기회에 하나 만들고,

Sign up 버튼을 눌러 SDK 사용자에 대한 간단한 정보를 입력하시죠~


승인메일이 바로 오진 않습니다.

적어도 주말에는 승인메일이 오지 않았습니다.

주말이 지난 월요일 오전 10시경에 승인메일을 받은 기억이 납니다.

시스템이 자동으로 승인을 하진 않을테고,

수동으로 신청자를 가려 승인해주는게 아닌가 합니다.


승인메일은 아래 내용을 담고 전송됩니다.

Gear SDK Early Access Program에 대한 간단한 정보가 있고,

다운로드 페이지로 접근할 수 있는 버튼이 있네요.



권한이 없는 상태에서 다운로드 페이지로는 갈 수 없습니다.

다운로드를 받으시려면 필히 승인까지 받으셔야 합니다.


다운로드 페이지에 접근하면 아래와 같은 화면이 나옵니다.

처음으로 언급된 것이 기어앱의 동작방식이네요.

기어앱은,

- Standalone : 기어만 있어도 앱을 100% 활용할 수 있는 경우

- Companion : 모바일과 기어가 연결되어야 앱을 100% 활용할 수 있는 경우

위의 두 방식 중 하나로 동작하게 됩니다.



설치 전에 설치 방법이 언급된 More Details 버튼을 누릅니다.

위의 버튼을 누르면 아래처럼 자세한 설치방법이 나옵니다.



이 설치방법은 다운로드를 마치고 설치할 때 참고하시면 됩니다.

More Details 아래에는 플랫폼별 인스톨 매니져가 있네요.

자신의 OS에 해당하는 인스톨 매니져를 다운로드 받습니다.

- MacOS 64 bits

- Ubuntu 32 bits

- Ubuntu 64 bits

- Windows 32 bits

- Windows 64 bits


다운로드를 요청하면,

라이센스가 나옵니다.



라이센스에 동의한다는 의미로 두 군데에 모두 체크를 합니다.

두 군데 모두 체크가 되면, Download라는 버튼이 생성됩니다.

Download를 눌러 타이젠 SDK를 다운로드 받습니다.


윈도우 64비트용 인스톨 메니져는 약 810메가 정도의 용량입니다.

전송속도는 시스템마다 차이가 있겠지만,

2분 남짓이면 다운로드받을 수 있습니다.


다운로드 받은 파일은 압축되어 있습니다.

압축을 풀고 실행파일을 실행합니다.

윈도우의 경우에는 "tizen-sdk_2.3.74_windows-64.exe" 실행합니다.



인스톨 매니져가 정상적으로 실행되었다면,

위의 화면을 볼 수 있습니다.


Install 혹은 Update > Advanced

위의 경로에서 Advanced 버튼을 누릅니다.



Advanced Configuration에서,

SDK image를 선택합니다.

그리고 다운로드 받은 파일 중 "tizen-sdk-image-TizenSDK_2.3.1_RC7_EAP-windows-64.zip" 파일을 선택한 후 OK를 누릅니다.


여기까지 진행되었으면 아래와 같은 화면을 보실 수 있습니다.

Profiles에는 Wearable 2.3.1만 설치할 수 있습니다.



Wearable 2.3.1이 선택된 것을 확인하고,

Install 버튼을 누릅니다.



타이젠 SDK에 대한 라이센스가 나옵니다.

I agree 버튼을 눌러주세요.


"Ready to install?"

인스톨 준비가 다 되었는지 묻습니다.



Installation Location과 Data Location의 위치를 변경할 수 있습니다.

다만 여기서는 기존에 설정된 디렉토리를 그대로 사용하도록 하겠습니다.

중간에 있는 Install 버튼을 눌러 인스톨을 시작합니다.



인스톨이 완료되면 위의 화면이 나옵니다.

Close를 누릅니다.


그리고 타이젠 IDE를 실행하여 이클립스를 띄웁니다.

왼편 하단에 Connection Explorer가 있습니다.

가장 왼편에 에뮬레이터를 닮은 버튼을 눌러 Emulator manager를 누릅니다.



아래처럼 에뮬레이터 매니져가 런칭되었습니다.

에뮬레이터 매니져는 다음 세 개의 탭으로 되어 있습니다.

- wearable-2.3.1

- custom

- all



wearable-2.3.1 탭에 진입하여,

Create New VM 아래에 있는 '+' 버튼을 누릅니다.

그러면 그 자리에 폰 모양의 에뮬이 하나 생깁니다.



폰 오른쪽에 Detail을 설정할 수 있는 부분이 있습니다.

거기서 Name 정도를 바꿔줄 수 있습니다.

그리고 아래 Confirm을 누릅니다.



위의 이미지처럼 에뮬레이터가 하나 등록되었습니다.

사이즈는 360x360입니다.

원형 디스플레이가 360x360이겠지요.


에뮬레이터의 재생버튼을 눌러,

에뮬레이터를 런칭합니다.



원형 디스플레이를 가진 wearable 2.3.1 버전을 보실 수 있습니다.

이번에 추가된 장치로 오른 편에 용두가 있습니다.

그리고 원형디스플레이를 감싸고 있는 rotary도 있습니다.

신규 피쳐를 이용하여,

재미난 앱을 짤 수 있겠군요.


끝_




타이젠에 올라가는 앱은 타이젠 SDK를 사용하여 빌드할 수 있습니다.

하지만, 타이젠 플랫폼 자체를 빌드하기 위해서는 SDK로는 안됩니다.


타이젠 그룹에서는 타이젠 플랫폼의 패키지들을 빌드할 수 있는 환경을 제공하고 있습니다.

타이젠 개발자들은 실제로 이러한 방법으로 패키지를 만들어내고 있습니다.


지금 이 순간에도,

세계 각지의 타이젠 개발자들은 타이젠 빌드서버에 접속하여 빌드를 하고 있습니다.



안녕하세요, Tizen 개발자 윤진입니다.


gbs를 사용하려면 우선 설치가 되어 있어야겠지요?

gbs는 아래 포스팅을 참고하여 설치하실 수 있습니다.

"우분투에 Tizen 플랫폼 툴인 gbs & sdb 설치해보기, http://storycompiler.tistory.com/35"


우분투 15.04 환경에서 gbs가 동작하지 않는 문제가 있습니다.

이 문제는 아래 포스팅을 참고해주세요.

[Tizen] 우분투 15.04에서 gbs 실행에러 처리


gbs는 Git Build System의 약자로,

타이젠 플랫폼의 패키지를 빌드하기 위한 커맨드라인 툴입니다.

- Git repo.를 기준으로 tar.gz 파일을 생성한 뒤,

- 로컬 빌드를 수행하고,

- 타이젠 메인에 업로드할 수 있습니다.



gbs로 빌드하기 위해서는 위의 그림 좌우에 있는 4개의 박스가 필요합니다.

- Source Code

   git을 기반으로한 소스 repository는 빌드 대상이 되겠지요.

   타이젠 오픈소스는 아래 포스팅을 참고하여 클론 받으실 수 있습니다.

   "Tizen 오픈소스 모두 내려받기, http://storycompiler.tistory.com/16"

- Build config

   gbs의 설정파일은 빌드하기 위한 방법이 명시되어 있습니다.

- Repositories

   빌드하기 위한 재료입니다. 플랫폼을 이루는 rpms가 저장된 곳이지요.

- Local repository

   플랫폼을 이루는 패키지 중 일부만 임의로 변경하고자 하는 경우에,

   Local repo.에 패키지를 설치해두면 됩니다.

   gbs는 빌드를 하며 Local repo.를 먼저 살펴보고 패키지를 찾기 때문이죠.

   Local repo.에 패키지가 없으면 Repositories에서 찾습니다.

   대부분 패키지는 Repositories에서 찾게 되겠지요.


gbs, source를 구비했다면 이제 빌드를 위한 기본설정을 할 차례입니다.

설정을 한 파일은 아래 위치 중 한 군데에 놓으면 됩니다.


  • $PWD/.gbs.conf: project-specific configuration settings that affect only the specific project in the specified working directory. These settings have the highest precedence.
  • /home/<user>/.gbs.conf: user-specific configuration settings that affect only the specified user.
  • /etc/gbs.conf: system-wide configuration settings that affect the entire system. These settings have the lowest precedence.


상단에 있는 $PWD/.gbs.conf의 우선순위가 가장 높고,

/etc/gbs.conf의 우선순위가 가장 낮습니다.

우선순위 순으로 conf 파일을 찾아보고 높은 순위의 conf 설정대로 빌드가 수행되죠.


gbs 명령은 빌드하고자 하는 프로젝트의 디렉토리에서 수행합니다.

혹은 다수의 프로젝트를 빌드하기 위해서는 프로젝트들이 모여있는 디렉토리에서 하면 되지요.

$PWD는 gbs를 수행하는 그 위치를 의미합니다.

gbs가 실행되면 우선적으로 명령을 실행한 디렉토리에 .gbs.conf 파일이 있는지 확인하게 됩니다.


위의 위치에 .gbs.conf가 없다면,

일반적으로 설정 파일을 놓는,

/home/<user>/.gbs.conf 파일을 참조하게 됩니다.

다수의 프로젝트를 빌드하려면 위의 위치에 .gbs.conf 파일을 설치하는 편이 좋습니다.


마지막으로 /etc/gbs.conf는 어느 사용자나 사용할 수 있는 설정파일입니다.

다수의 사용자를 위해 gbs 환경을 제공해야하는 경우에 사용하면 됩니다.


그 외의 위치에 다른 이름으로 conf 파일을 만들고자 하는 경우도 있을 겁니다.

그럴 때에는 gbs 명령을 수행할 때 별도의 위치에 다른 이름으로 있다는 것을 gbs에 알려줘야 합니다.

-c 옵션으로 conf 파일의 위치를 넘겨줄 수 있습니다.

$ gbs -c ~/my-gbs.conf build ...


gbs를 설치하였다면,

기본적으로 /home/<user>/.gbs.conf 파일이 설치되어 있을 겁니다.

그 내용을 먼저 살펴보겠습니다.


$ cat ~/.gbs.conf 
[general]
#Current profile name which should match a profile section name
profile = profile.tizen

[profile.tizen]
#Common authentication info for whole profile
#user =
#CAUTION: please use the key name "passwd" to reset plaintext password
#passwd =
obs = obs.tizen
#Comma separated list of repositories
repos = repo.tizen_latest
#repos = repo.tizen_main, repo.tizen_base
#Build config for gbs build
#buildconf = <patch/to/build-config-file>
#Comma separated list of additional packages be excluded building
#exclude_packages = libtool,gettext

[obs.tizen]
#OBS API URL pointing to a remote OBS.
url = https://api.tizen.org
#Optional user and password, set if differ from profile's user and password
#user =
#passwd =

#Repo section example
[repo.tizen_latest]
#Build against repo's URL
url = http://download.tizen.org/releases/daily/trunk/ivi/latest/
#Optional user and password, set if differ from profile's user and password
#user =
#passwd =

#Individual repo is also supported
#[repo.tizen_base]
#url = http://download.tizen.org/releases/daily/trunk/ivi/latest/repos/base/ia32/packages/
#[repo.tizen_main]
#url = http://download.tizen.org/releases/daily/trunk/ivi/latest/repos/ivi/ia32/packages/


위의 설정값 중 굵은 글씨로 표시된,

[repo.tizen_latest] 섹션의 url 필드값만 변경하면 빌드를 할 수 있습니다.

url 필드에 타이젠 플랫폼의 릴리스 바이너리 주소를 입력하면 드디어 빌드를 위한 재료가 준비된 셈입니다.

url 필드에 입력하는 주소로 빌드에 사용할 플랫폼의 버전을 선택할 수 있습니다.

타이젠 플랫폼에는 2015. 6. 6 현재 10개의 릴리스 버전이 있습니다.

각각의 릴리스 버전 아래에 url을 명시해두었으니 복사해서 쓰시면 됩니다.


- Tizen 1.0 : 2012년 4월 30일 첫번째 빌드

   url = 없음, gbs 빌드 대상이 아니었음.

- Tizen 2.0 Emulator : 2013년 2월 18일 7번째 빌드

   url = http://download.tizen.org/releases/2.0-emul/tizen-2.0-emul_20130218.7/repos/base/ia32/packages/

- Tizen 2.0 : 2013년 2월 19일 4번째 빌드

   url = http://download.tizen.org/releases/2.0/latest/

- Tizen 2.1 Beta : 2013년 5월 5일 3번째 빌드

   url = http://download.tizen.org/releases/2.1b/tizen-2.1_20130505.3/

- Tizen 2.1 : 2013년 5월 17일 6번째 빌드

   url = http://download.tizen.org/releases/2.1/latest/

- Tizen 2.2 Beta : 2013년 7월 1일 5번째 빌드

   url = 없음

- Tizen 2.2 Emulator : 2013년 7월 19일 2번째 빌드

   url = http://download.tizen.org/releases/2.2-emul/latest/

- Tizen 2.2 : 2013년 7월 19일 3번째 빌드

   url = http://download.tizen.org/releases/2.2/latest/

- Tizen 2.2.1 : 2013년 11월 7일 3번째 빌드

   url = http://download.tizen.org/releases/2.2.1/latest/

- Tizen 2.3 : 2015년 3월 11일 3번째 빌드

   [mobile]

   url = http://download.tizen.org/releases/2.3/2.3-mobile/tizen-2.3-mobile_20150311.3/

   [wearable]

   url = http://download.tizen.org/releases/2.3/2.3-wearable/tizen-2.3-wearable_20150311.3/


각각의 릴리스 버전은 아래 사이트에서도 확인할 수 있습니다.

릴리스 사이트 : http://download.tizen.org/releases/



위에서 클론을 받은 타이젠 소스 repo.에서 gbs를 수행해보시죠.

$ gbs build -A i586
info: generate repositories ...
info: build conf has been downloaded at:
      /var/tmp/usr-gbs/tizen.conf
info: start building packages from: /home/user/tizen/apps/apps.home.settings (git)
2015-06-07 00:38 +0900
gbs 0.23.2
info: prepare sources...
info: start export source from: /home/user/tizen/apps/apps.home.settings ...
Argument "" isn't numeric in numeric eq (==) at /usr/bin/depanneur line 642.
warning: Deprecated option '--git-export-only', please use '--no-build' instead!
info: Creating (native) source archive org.tizen.setting-0.1.98.tar.gz from 'HEAD'
info: package files have been exported to:
     /home/user/GBS-ROOT/local/sources/tizen/org.tizen.setting-0.1.98-99
info: retrieving repo metadata...
info: parsing package data...
info: building repo metadata ...
info: resolving skipped packages ...
info: package dependency resolving ...
info: next pass:
org.tizen.setting
...


첫 빌드는 릴리스 패키지를 다운로드 & 인스톨해야 하므로 꽤나 시간이 걸립니다.

하지만, 두번째 빌드부터는 첫번째 빌드에서 구축한 환경에서 이뤄지므로 금방 빌드를 할 수 있습니다.


만약 빌드를 진행하다가 멈춘다면,

$ gbs build -A armv7l --clean --clean-repos

설치도중 에러가 발생한 것일 수도 있으니,

clean으로 깨끗이 정리한 뒤 다시 빌드를 시도해보세요.


빌드를 성공하면 아래와 같은 메시지를 볼 수 있습니다.

...
info: finished building starter
info: updating local repo
info: *** Build Status Summary ***
=== Total succeeded built packages: (1) ===
info: generated html format report:
     /home/user/GBS-ROOT/local/repos/tizen/i586/index.html
info: generated RPM packages can be found from local repo:
     /home/user/GBS-ROOT/local/repos/tizen/i586/RPMS
info: generated source RPM packages can be found from local repo:
     /home/user/GBS-ROOT/local/repos/tizen/i586/SRPMS
info: build logs can be found in:
     /home/user/GBS-ROOT/local/repos/tizen/i586/logs
info: build roots located in:
     /home/user/GBS-ROOT/local/BUILD-ROOTS/scratch.i586.*
info: Done


위에서 굵은 글씨로 표시되어있는 장소가,

빌드 결과물인 rpm 파일이 저장되어 있는 위치입니다.


빌드를 해보았으니,

conf 파일을 자세히 살펴보아 자신의 환경에 맞게 설정해보도록 하죠.


conf 파일은 총 4개의 섹션으로 이뤄져 있습니다.

[general] / [profile] / [obs] / [repo]

위의 4가지 섹션을 각각 살펴보겠습니다.

개인적으로 사용하는  .gbs.conf 파일을 붙여놓겠습니다.

gbs.conf

[general]
#upstream_branch = upstream
packaging_branch = tizen_2.3
buildroot = ~/GBS-ROOT/
packaging_dir = packaging
#Current profile name which should match a profile section name
profile = profile.mobile
#tmpdir = /var/tmp
#work_dir = .


- upstream_branch = master

  $ gbs clone 명령어로 다운로드 받을 upstream branch를 지정할 수 있습니다.

  git에서 master는 기본으로 다운로드 받으니 위의 명령어는 주석처리해도 무방합니다.

  실질적으로 쓸모가 없고, 최신 gbs에서 에러를 뱉네요.


- packaging_branch

  $ gbs clone 명령어로 git을 클론 받을 수도 있습니다.

  clone을 받은 후에 checkout 되는 브랜치를 general에서 미리 지정할 수 있습니다.


- buildroot

   빌드를 수행하기 위해 필요한 환경은 buildroot 디렉토리에 구축됩니다.

   각 프로파일별로도 buildroot를 만들 수 있습니다.

   만약 프로파일에서 설정한 buildroot가 없다면 general 섹션을 참고하게 됩니다.


- packaging_dir

  rpm패키징을 위해 설정하는 spec파일의 위치를 지정할 수 있습니다.

  default는 root/packaging이니, packaging으로 설정해두면 됩니다.


- profile

   타이젠은 멀티 프로파일을 지향하는 플랫폼입니다.

   모바일/웨어러블/자동차 등을 타겟으로 하고 있죠.

   따라서 빌드도 각 프로파일별로 수행할 수 있습니다.

   Default로 빌드할 프로파일은 위의 프로파일에서 지정할 수 있습니다.

   하지만, 빌드타임에 프로파일을 변경하고자 하면,

   $ gbs build --profile=profile.wearable -A i586

   위와 같이 --profile 옵션을 사용해야 합니다.


- tmpdir / work_dir

  general에는 변수선언이 가능합니다.

  다른 섹션에서 ${tmpdir}이나 ${work_dir}과 같이 변수를 사용할 수 있습니다.


[profile.mobile]
obs = obs.tizen
repos = repo.tizen_latest
# If no buildroot for profile, the buildroot in general section will be used
#buildroot = ~/GBS-ROOT-profile.tizen/
# Specify build conf for a specific profile by using shell-style variable references
#buildconf = ${work_dir}/tizen-conf/build.conf
# Specify a list of packages that don't participate in the building, which
# can also be used to break dependency circle.
#exclude_packages=filesystem,aul,libmm-sound,libtool
# Common authentication information
#user = xxx
#passwd = xxx


- obs

  프로파일을 remote에서 빌드하고자 할 때 참고하고, 

  obs 섹션과 동일한 이름을 넣어야 합니다.


- repos

  타이젠 플랫폼 패키지들이 있는 위치가 명시되어 있는 repos 섹션을 넣습니다.


- buildroot

  프로파일마다 buildroot를 다르게 지정하고자 하는 경우 입력합니다.

  그렇지 않으면 [general]에서 설정한 값이 설정됩니다.


- exclude_packages

  다수의 패키지를 빌드하고자 할때 빌드풀에 포함시키지 않을 패키지를 넣습니다.


- user / passwd

  repo.에 접근할 때 권한이 필요한 경우 넣어줍니다.

  repo.별로도 설정할 수 있습니다.


[obs.tizen]
url = https://api.tizen.org
user = xxx
passwd = xxx
# set default base_prj for this obs
#base_prj=Tizen:Main
# set default target prj for this obs, default is home:<user>:gbs:<base_prj>
#target_prj=<specify target project>


- url

  remote 빌드를 하기 위한 주소를 입력합니다.


- user / passwd

  remote 서버에 권한이 필요하다면 입력해주어야 합니다.


- base_prj

  remote 서버에서 빌드하고자 하는 패키지가 속한 base 프로젝트를 선택해둡니다.


- target_prj

  패키지가 장차 체크인될 프로젝트를 선택할 수도 있습니다.

  통상 base 프로젝트와 동일한 프로젝트를 입력합니다만,

  베이스 따로 타겟 따로 지정할 수도 있습니다.


[repo.tizen_2.1]
url = http://download.tizen.org/releases/2.1/latest/
#Optional user and password, set if differ from profile's user and password
#user =
#passwd =


- url

   url은 빌드를 수행하기 위해 dependency가 있는 모든 rpm이 다운로드 받을 수 있는 위치를 지정해야 합니다.

   로컬의 절대경로일 수도 있고, 인터넷 주소일 수도 있습니다.


- user / passwd

   위의 url에 접근하기 위해 별도의 권한이 필요한 경우 지정할 수 있습니다.

   타이젠은 오픈이기 때문에 user / passwd를 설정해줄 필요가 없습니다.


이상으로 gbs에 대한 설명을 마치겠습니다.

gbs를 사용하는 분들께 도움이 되면 좋겠습니다. :)


끝_


* References

https://source.tizen.org/documentation/reference/git-build-system?langredirect=1

https://source.tizen.org/documentation/reference/git-build-system/configuration-file

https://source.tizen.org/documentation/reference/git-build-system/usage/gbs-build?langredirect=1



타이젠 SDK만으로는,

타이젠 플랫폼 자체를 개발하기에는 아무래도 어려움이 있습니다.

타이젠 SDK에서는 타이젠의 모든 피쳐를 사용할 수 없으니까요.

Public으로 제한된 피쳐만 사용할 수 있지요.


따라서 플랫폼 자체를 개발하기 위해서는,

SDK 환경에서 벗어나,

- Private 피쳐를 포함하여 소스를 빌드하고

- 타겟에 설치할 툴체인이 필요합니다.


타이젠 플랫폼은 그러한 개발툴마저 오픈하였기에,

누구나 다운로드 받아 사용할 수 있습니다.



안녕하세요, Tizen 개발자 윤진입니다.


본 포스팅은 타이젠 플랫폼을 개발하기 위한 개발자를 위한 포스팅입니다.

타이젠 앱을 개발하려면 타이젠 SDK만으로도 충분하죠~


우분투 15.04버전에서 gbs 설치시 발생하는 문제는 아래 포스팅을 참고해주세요.

[Tizen] 우분투 15.04에서 gbs 실행에러 처리


gbs에 대한 추가정보는 아래 포스팅을 참고해주세요.

[Tizen] 타이젠 gbs의 모든 것


타이젠 플랫폼의 툴체인은 아래 주소에서 받을 수 있습니다.

http://download.tizen.org/tools/latest-release/


- CentOS 6

- Debian 7

- Fedora 19

- Fedora 20

- Ubuntu 12.04

- Ubuntu 14.04

- Ubuntu 14.10

- openSUSE 12.3

- openSUSE 13.1

위의 리스트에서 자신에 맞는 OS를 선택하시면 여러 툴 파일을 보실 수 있습니다.


물론, 여기서 직접 다운로드 받아도 되겠지만,

(우분투의 경우) 우분투 패키징 시스템으로 관리하는게 낫겠지요?

다른 패키지들과 함께 업데이트도 하고 말이죠~


그렇게 하기 위해서는 APT 툴로 패키지를 설치할 수 있도록

APT 소스 리스트에 타이젠 다운로드 사이트를 추가해주어야 합니다.


- Cent OS 6

$ cat /etc/apt/sources.list.d/tizen.list
deb http://download.tizen.org/tools/latest-release/CentOS_6/ /


- Debian 7

$ cat /etc/apt/sources.list.d/tizen.list
deb http://download.tizen.org/tools/latest-release/Debian_7/ /


- Fedora 19

$ cat /etc/apt/sources.list.d/tizen.list
deb http://download.tizen.org/tools/latest-release/Fedora_19/ /


- Fedora 20

$ cat /etc/apt/sources.list.d/tizen.list
deb http://download.tizen.org/tools/latest-release/Fedora_20/ /


- Ubuntu 12.04

$ cat /etc/apt/sources.list.d/tizen.list
deb http://download.tizen.org/tools/latest-release/Ubuntu_12.04/ /


- Ubuntu 14.04

$ cat /etc/apt/sources.list.d/tizen.list
deb http://download.tizen.org/tools/latest-release/Ubuntu_14.04/ /


- Ubuntu 14.10

$ cat /etc/apt/sources.list.d/tizen.list
deb http://download.tizen.org/tools/latest-release/Ubuntu_14.10/ /


- openSUSE 12.3

$ cat /etc/apt/sources.list.d/tizen.list
deb http://download.tizen.org/tools/latest-release/openSUSE_12.3/ /


- openSUSE 13.1

$ cat /etc/apt/sources.list.d/tizen.list
deb http://download.tizen.org/tools/latest-release/openSUSE_13.1/ /


위와 같이 소스 리스트에 타이젠 다운로드 사이트를 추가해주면 됩니다.

혹은 아래 파일을 다운로드 받으셔서 /etc/apt/sources.list.d/ 에 설치해주세요.

tizen.list

그리고 소스 리스트를 아래처럼 갱신해보죠.


$ sudo apt-get update
무시http://kr.archive.ubuntu.com trusty InRelease
무시http://kr.archive.ubuntu.com trusty-updates InRelease                     
무시http://kr.archive.ubuntu.com trusty-backports InRelease                   
기존 http://kr.archive.ubuntu.com trusty Release.gpg                          
기존 http://kr.archive.ubuntu.com trusty-updates Release.gpg                  
기존 http://kr.archive.ubuntu.com trusty-backports Release.gpg                
기존 http://kr.archive.ubuntu.com trusty Release                              
기존 http://kr.archive.ubuntu.com trusty-updates Release                      
기존 http://kr.archive.ubuntu.com trusty-backports Release                    
기존 http://kr.archive.ubuntu.com trusty/main Sources                         
기존 http://kr.archive.ubuntu.com trusty/restricted Sources                   
기존 http://kr.archive.ubuntu.com trusty/universe Sources                     
기존 http://kr.archive.ubuntu.com trusty/multiverse Sources                   
기존 http://kr.archive.ubuntu.com trusty/main i386 Packages                   
기존 http://kr.archive.ubuntu.com trusty/restricted i386 Packages             
기존 http://kr.archive.ubuntu.com trusty/universe i386 Packages               
기존 http://kr.archive.ubuntu.com trusty/multiverse i386 Packages             
무시http://download.tizen.org  InRelease                                      
기존 http://kr.archive.ubuntu.com trusty/main Translation-ko                  
기존 http://kr.archive.ubuntu.com trusty/main Translation-en                  
무시http://security.ubuntu.com trusty-security InRelease                      
기존 http://kr.archive.ubuntu.com trusty/multiverse Translation-en            
기존 http://kr.archive.ubuntu.com trusty/restricted Translation-ko            
기존 http://kr.archive.ubuntu.com trusty/restricted Translation-en            
기존 http://kr.archive.ubuntu.com trusty/universe Translation-ko              
기존 http://kr.archive.ubuntu.com trusty/universe Translation-en              
기존 http://kr.archive.ubuntu.com trusty-updates/main Sources                 
무시http://download.tizen.org  Release.gpg                                    
기존 http://kr.archive.ubuntu.com trusty-updates/restricted Sources           
기존 http://kr.archive.ubuntu.com trusty-updates/universe Sources             
기존 http://kr.archive.ubuntu.com trusty-updates/multiverse Sources           
기존 http://kr.archive.ubuntu.com trusty-updates/main i386 Packages           
기존 http://kr.archive.ubuntu.com trusty-updates/restricted i386 Packages     
기존 http://kr.archive.ubuntu.com trusty-updates/universe i386 Packages       
기존 http://kr.archive.ubuntu.com trusty-updates/multiverse i386 Packages     
기존 http://kr.archive.ubuntu.com trusty-updates/main Translation-en          
기존 http://kr.archive.ubuntu.com trusty-updates/multiverse Translation-en    
받기:1 http://security.ubuntu.com trusty-security Release.gpg [933 B]         
기존 http://kr.archive.ubuntu.com trusty-updates/restricted Translation-en    
기존 http://kr.archive.ubuntu.com trusty-updates/universe Translation-en      
기존 http://kr.archive.ubuntu.com trusty-backports/main Sources               
기존 http://kr.archive.ubuntu.com trusty-backports/restricted Sources         
기존 http://kr.archive.ubuntu.com trusty-backports/universe Sources           
받기:2 http://download.tizen.org  Release [1,031 B]                           
기존 http://kr.archive.ubuntu.com trusty-backports/multiverse Sources         
기존 http://kr.archive.ubuntu.com trusty-backports/main i386 Packages         
무시http://extras.ubuntu.com trusty InRelease                                 
기존 http://kr.archive.ubuntu.com trusty-backports/restricted i386 Packages   
기존 http://kr.archive.ubuntu.com trusty-backports/universe i386 Packages     
기존 http://kr.archive.ubuntu.com trusty-backports/multiverse i386 Packages   
기존 http://kr.archive.ubuntu.com trusty-backports/main Translation-en        
기존 http://kr.archive.ubuntu.com trusty-backports/multiverse Translation-en  
기존 http://kr.archive.ubuntu.com trusty-backports/restricted Translation-en  
기존 http://kr.archive.ubuntu.com trusty-backports/universe Translation-en    
받기:3 http://security.ubuntu.com trusty-security Release [63.5 kB]           
무시http://kr.archive.ubuntu.com trusty/main Translation-ko_KR                
무시http://kr.archive.ubuntu.com trusty/multiverse Translation-ko_KR          
무시http://kr.archive.ubuntu.com trusty/multiverse Translation-ko             
무시http://kr.archive.ubuntu.com trusty/restricted Translation-ko_KR          
무시http://kr.archive.ubuntu.com trusty/universe Translation-ko_KR            
기존 http://extras.ubuntu.com trusty Release.gpg                              
기존 http://extras.ubuntu.com trusty Release                                  
받기:4 http://security.ubuntu.com trusty-security/main Sources [83.9 kB]      
기존 http://extras.ubuntu.com trusty/main Sources                             
기존 http://extras.ubuntu.com trusty/main i386 Packages                       
받기:5 http://security.ubuntu.com trusty-security/restricted Sources [2,061 B]
받기:6 http://security.ubuntu.com trusty-security/universe Sources [25.2 kB]  
받기:7 http://security.ubuntu.com trusty-security/multiverse Sources [2,333 B]
받기:8 http://security.ubuntu.com trusty-security/main i386 Packages [270 kB] 
받기:9 http://download.tizen.org  Packages [12.1 kB]                          
받기:10 http://security.ubuntu.com trusty-security/restricted i386 Packages [8,846 B]
받기:11 http://security.ubuntu.com trusty-security/universe i386 Packages [107 kB]
받기:12 http://security.ubuntu.com trusty-security/multiverse i386 Packages [3,840 B]
무시http://download.tizen.org  Translation-ko_KR                              
기존 http://security.ubuntu.com trusty-security/main Translation-en           
무시http://download.tizen.org  Translation-ko                                 
기존 http://security.ubuntu.com trusty-security/multiverse Translation-en     
무시http://download.tizen.org  Translation-en                                 
기존 http://security.ubuntu.com trusty-security/restricted Translation-en     
기존 http://security.ubuntu.com trusty-security/universe Translation-en       
무시http://extras.ubuntu.com trusty/main Translation-ko_KR                    
무시http://extras.ubuntu.com trusty/main Translation-ko           
무시http://extras.ubuntu.com trusty/main Translation-en           
내려받기 580 k바이트, 소요시간 7초 (80.6 k바이트/초)                          
패키지 목록을 읽는 중입니다... 완료


중간에 http://download.tizen.org도 보이네요.

업데이트가 완료되었다면,

이제 타이젠 플랫폼 툴인 gbs와 sdb를 설치할 수 있습니다.


$ sudo apt-get install gbs sdb
패키지 목록을 읽는 중입니다... 완료
의존성 트리를 만드는 중입니다      
상태 정보를 읽는 중입니다... 완료
다음 패키지가 자동으로 설치되었지만 더 이상 필요하지 않습니다:
  cli-common libicsharpcode-nrefactory-cecil5.0-cil
  libicsharpcode-nrefactory-csharp5.0-cil libicsharpcode-nrefactory5.0-cil
  libmono-cecil-private-cil libmono-corlib2.0-cil libmono-corlib4.5-cil
  libmono-i18n-west2.0-cil libmono-i18n-west4.0-cil libmono-i18n4.0-cil
  libmono-posix2.0-cil libmono-posix4.0-cil libmono-security2.0-cil
  libmono-security4.0-cil libmono-system-configuration4.0-cil
  libmono-system-core4.0-cil libmono-system-security4.0-cil
  libmono-system-xml4.0-cil libmono-system2.0-cil libmono-system4.0-cil
  mono-4.0-gac mono-gac mono-runtime mono-runtime-common mono-runtime-sgen
Use 'apt-get autoremove' to remove them.
다음 패키지를 더 설치할 것입니다:
  build createrepo debugedit deltarpm depanneur gbs-api gbs-export
  gbs-remotebuild git-buildpackage-common git-buildpackage-rpm
  libcommon-sense-perl libcrypt-ssleay-perl libencode-locale-perl
  libfile-listing-perl libfont-afm-perl libhtml-form-perl libhtml-format-perl
  libhtml-parser-perl libhtml-tagset-perl libhtml-template-perl
  libhtml-tree-perl libhttp-cookies-perl libhttp-daemon-perl libhttp-date-perl
  libhttp-message-perl libhttp-negotiate-perl libio-html-perl libjson-perl
  libjson-xs-perl liblwp-mediatypes-perl liblwp-protocol-https-perl
  libnet-http-perl librpm-tizen librpmbuild3 librpmsign1 libsqlite0
  libtext-unidecode-perl libwww-perl libwww-robotrules-perl libxdelta2
  libxml-parser-perl libyaml-libyaml-perl libyaml-perl osc pbzip2 pristine-tar
  python-deltarpm python-keyring python-lzma python-m2crypto python-pycurl
  python-rpm python-secretstorage python-sqlite python-sqlitecachec
  python-urlgrabber qemu-arm-static rpm texi2html xdelta yum
제안하는 패키지:
  rpm-i18n zipmerge libdata-dump-perl libipc-sharedcache-perl
  libauthen-ntlm-perl libyaml-shell-perl python-gdata python-keyczar
  python-kde4 libcurl4-gnutls-dev python-pycurl-dbg python-secretstorage-doc
  python-sqlite-dbg alien elfutils latex2html
다음 새 패키지를 설치할 것입니다:
  build createrepo debugedit deltarpm depanneur gbs gbs-api gbs-export
  gbs-remotebuild git-buildpackage-common git-buildpackage-rpm
  libcommon-sense-perl libcrypt-ssleay-perl libencode-locale-perl
  libfile-listing-perl libfont-afm-perl libhtml-form-perl libhtml-format-perl
  libhtml-parser-perl libhtml-tagset-perl libhtml-template-perl
  libhtml-tree-perl libhttp-cookies-perl libhttp-daemon-perl libhttp-date-perl
  libhttp-message-perl libhttp-negotiate-perl libio-html-perl libjson-perl
  libjson-xs-perl liblwp-mediatypes-perl liblwp-protocol-https-perl
  libnet-http-perl librpm-tizen librpmbuild3 librpmsign1 libsqlite0
  libtext-unidecode-perl libwww-perl libwww-robotrules-perl libxdelta2
  libxml-parser-perl libyaml-libyaml-perl libyaml-perl osc pbzip2 pristine-tar
  python-deltarpm python-keyring python-lzma python-m2crypto python-pycurl
  python-rpm python-secretstorage python-sqlite python-sqlitecachec
  python-urlgrabber qemu-arm-static rpm texi2html xdelta yum
다음 패키지를 업그레이드할 것입니다:
  sdb
1개 업그레이드, 62개 새로 설치, 0개 제거 및 231개 업그레이드 안 함.
6,431 k바이트 아카이브를 받아야 합니다.
이 작업 후 28.6 M바이트의 디스크 공간을 더 사용하게 됩니다.
계속 하시겠습니까? [Y/n] Y


설치가 완료되면 바로 gbs & sdb를 사용할 수 있습니다.

$ gbs --version
gbs 0.23.2

$ sdb version
Smart Development Bridge version 2.2.47


즐거운 개발하시길...


끝_


  1. rubric 2015.10.06 15:38

    gbs 빌드 중에 아래 에러를 만나면,
    error: <gbs>Maybe you are using new designed repo, and please specify real RPM repo with repodata under it.
    https://lists.tizen.org/pipermail/dev/2014-June/003224.html
    에서 얘기하는 것처럼 build repo 를 더 정확하게 입력하면 해결되네요

    • Using gbs (>=0.16), if you still specify the top directory of repository like:
      http://download.tizen.org/snapshots/tizen/common/tizen_20140618.1/

      GBS will report error as follow:

      info: generate repositories ...
      error: <gbs>Maybe you are using new designed repo, and please specify real RPM
      repo with repodata under it.

      So the real standard repository should be used now, for example:
      http://download.tizen.org/snapshots/tizen/common/tizen_20140618.1/repos/ia32-wayland/packages/

      이런 내용이 있군요~!
      굿 정보 감사합니다!

  2. 김현호 2018.10.01 18:08

    리스트를 추가하고 update를 했는데
    홈페이지의 repository가 잘못되었다고 나오네요 ㅠㅠ
    홈페이지 문제인가요?

    the repository '주소' is not signed.

  3. ffff 2018.11.01 14:34

    sdb 설치하니까 다른 패키지가 설치되는것 같은데요

+ Recent posts