Tizen 2.1 base
[framework/osp/uifw.git] / src / ui / FUi_UiBuilder.cpp
1 //
2 // Open Service Platform
3 // Copyright (c) 2012-2013 Samsung Electronics Co., Ltd.
4 //
5 // Licensed under the Flora License, Version 1.0 (the License);
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://floralicense.org/license/
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an AS IS BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17
18 /**
19 * @file         FUi_UiBuilder.cpp
20 * @brief                This is the implementation file for _UiBuilder class.
21 */
22
23 #include <new>
24 #include <FAppApp.h>
25 #include <FUiIOrientationEventListener.h>
26 #include <FUi_ControlImplManager.h>
27 #include <FBaseSysLog.h>
28 #include "FUiCtrl_FrameImpl.h"
29 #include "FUi_UiBuilder.h"
30 #include "FUi_UiBuilderXmlHandler.h"
31 #include "FUi_ControlManager.h"
32
33 using namespace Tizen::Base;
34 using namespace Tizen::Base::Collection;
35 using namespace Tizen::Io;
36 using namespace Tizen::Ui;
37 using namespace Tizen::Ui::Controls;
38 using namespace Tizen::Media;
39 using namespace Tizen::Graphics;
40
41 namespace Tizen { namespace Ui
42 {
43 _UiBuilder::_UiBuilder(void)
44         : __version(0)
45         , __lastIndex(0)
46         , __logicalResolution(0)
47         , __pUiBuilderControlList(null)
48         , __pContainer(null)
49         , __rotate(UIBUIDER_SCREEN_NONE)
50         , __pTransform(null)
51         , __xmlFile(L"")
52 {
53 }
54
55 _UiBuilder::~_UiBuilder(void)
56 {
57         if (__pUiBuilderControlList)
58         {
59                 _UiBuilderControl* pUiBuilderControl = null;
60                 int controlCount = __pUiBuilderControlList->GetCount();
61                 for (int i = 0; i < controlCount; i++)
62                 {
63                         __pUiBuilderControlList->GetAt(i, pUiBuilderControl);
64                         delete pUiBuilderControl;
65                 }
66                 __pUiBuilderControlList->RemoveAll();
67                 delete __pUiBuilderControlList;
68                 __pUiBuilderControlList = null;
69         }
70 }
71
72 _UiBuilderControl*
73 _UiBuilder::GetControl(int index) const
74 {
75         SysTryReturn(NID_UI, index >= 0 && index < UIBUILDER_CONTROL_MAX_COUNT, null, E_INVALID_ARG,
76                                 "[E_INVALID_ARG] Index is over than max control count");
77
78         _UiBuilderControl* pUiBuilderControl = null;
79         __pUiBuilderControlList->GetAt(index, pUiBuilderControl);
80         if (pUiBuilderControl == null)
81         {
82                 SysLogException(NID_UI, GetLastResult(), "Failed to GetControl()");
83                 return null;
84         }
85
86         return pUiBuilderControl;
87 }
88
89 _UiBuilderControl*
90 _UiBuilder::GetControl(const Tizen::Base::String& id) const
91 {
92         IEnumeratorT<_UiBuilderControl*>* pEnum = __pUiBuilderControlList->GetEnumeratorN();
93         SysTryReturn(NID_UI, pEnum != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Unable to get IEnumeratorT.");
94         _UiBuilderControl* pUiBuilderControl = null;
95
96         while (pEnum->MoveNext() == E_SUCCESS)
97         {
98                 pEnum->GetCurrent(pUiBuilderControl);
99                 String controlId = pUiBuilderControl->GetId();
100
101                 if (controlId.Equals(id, false))
102                 {
103                         delete pEnum;
104                         return pUiBuilderControl;
105                 }
106         }
107         delete pEnum;
108         return null;
109
110 }
111
112 void
113 _UiBuilder::SetVersion(int xmlVersion)
114 {
115         __version = xmlVersion;
116 }
117
118 int
119 _UiBuilder::GetVersion(void) const
120 {
121         return __version;
122 }
123
124 result
125 _UiBuilder::Construct(const String& xmlFile, Container* pContainer)
126 {
127         result r = E_SUCCESS;
128
129         __pContainer =  pContainer;
130         __xmlFile = xmlFile;
131         __pUiBuilderControlList = new (std::nothrow) ArrayListT<_UiBuilderControl*>;
132         SysTryCatch(NID_UI, __pUiBuilderControlList != null, r = E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Unable to create __pUiBuilderControlList.");
133
134         return r;
135
136         CATCH:
137
138         delete __pUiBuilderControlList;
139         return r;
140 }
141
142 result
143 _UiBuilder::MakeUI(_UiBuilderControl* pControl)
144 {
145         result r = E_SUCCESS;
146
147         _UiBuilderControlTableManager* pUiBuilderControlTableManager = _UiBuilderControlTableManager::GetInstance();
148         if(pUiBuilderControlTableManager == null)
149         {
150                 return E_OUT_OF_MEMORY;
151         }
152
153         for (int i = 0; i < UIBUILDER_CONTROL_MAX_COUNT; i++)
154         {
155                 if (pUiBuilderControlTableManager->GetName(i).IsEmpty())
156                 {
157                         break;
158                 }
159
160                 if (pControl->GetType().Equals(pUiBuilderControlTableManager->GetName(i), false))
161                 {
162                         _UiBuilderControlMakerFunctionPointer pControlMakerFunctionPointer = pUiBuilderControlTableManager->GetControlMaker(i);
163                         if (pControlMakerFunctionPointer != null)
164                         {
165                                 _UiBuilderControlMaker* pMaker = pControlMakerFunctionPointer(this);
166                                 r = pMaker->MakeControl(pControl);
167
168                                 delete pMaker;
169                                 return r;
170                         }
171                 }
172
173         }
174
175         return E_OPERATION_FAILED;
176 }
177
178 result
179 _UiBuilder::Parse(void)
180 {
181         File file;
182         ByteBuffer buffer;
183         FileAttributes attrib;
184         int readCount = 0;
185         byte* pXmlContents = null;
186         result r = E_SUCCESS;
187         bool findPath = false;
188         int size = 0;
189         String xmlFilePath(L"");
190         String temp;
191         String homePath;
192
193         __logicalResolution = _CoordinateSystem::GetInstance()->GetLogicalResolutionInt();
194
195         xmlFilePath.Append(__xmlFile);
196         xmlFilePath.Append(L".xml");
197
198         _ControlManager* pControlManager = _ControlManager::GetInstance();
199         SysTryReturn(NID_UI, pControlManager != null, E_OPERATION_FAILED, E_OPERATION_FAILED, "[E_OPERATION_FAILED] Unable to get the control manager");
200
201         Dimension screenSize = pControlManager->GetScreenSize();
202
203         // find xml file with device deviceResolution
204
205         temp = xmlFilePath;
206         r = temp.Insert("/", 0);
207         SysTryReturn(NID_UI, r == E_SUCCESS, E_OPERATION_FAILED, E_OPERATION_FAILED, "[%s] Propagated.", GetErrorMessage(r));
208         r = temp.Insert(screenSize.height, 0);
209         SysTryReturn(NID_UI, r == E_SUCCESS, E_OPERATION_FAILED, E_OPERATION_FAILED, "[%s] Propagated.", GetErrorMessage(r));
210         r = temp.Insert("x", 0);
211         SysTryReturn(NID_UI, r == E_SUCCESS, E_OPERATION_FAILED, E_OPERATION_FAILED, "[%s] Propagated.", GetErrorMessage(r));
212         r = temp.Insert(screenSize.width, 0);
213         SysTryReturn(NID_UI, r == E_SUCCESS, E_OPERATION_FAILED, E_OPERATION_FAILED, "[%s] Propagated.", GetErrorMessage(r));
214         r = temp.Insert("res/", 0);
215         SysTryReturn(NID_UI, r == E_SUCCESS, E_OPERATION_FAILED, E_OPERATION_FAILED, "[%s] Propagated.", GetErrorMessage(r));
216
217         homePath = Tizen::App::App::GetInstance()->GetAppRootPath();
218         r = temp.Insert(homePath, 0);
219         SysTryReturn(NID_UI, r == E_SUCCESS, E_OPERATION_FAILED, E_OPERATION_FAILED, "[%s] Propagated.", GetErrorMessage(r));
220         SysLog(NID_IO, "[UiBuilder] ui builder res path: %ls", temp.GetPointer());
221
222         // find device deviceResolution directory
223         if (!File::IsFileExist(temp))
224         {
225                 temp = xmlFilePath;
226                 r = temp.Insert("res/screen-size-normal/", 0);
227                 SysTryReturn(NID_UI, r == E_SUCCESS, E_OPERATION_FAILED, E_OPERATION_FAILED, "[%s] Propagated.", GetErrorMessage(r));
228
229                 homePath = Tizen::App::App::GetInstance()->GetAppRootPath();
230                 r = temp.Insert(homePath, 0);
231                 SysTryReturn(NID_UI, r == E_SUCCESS, E_OPERATION_FAILED, E_OPERATION_FAILED, "[%s] Propagated.", GetErrorMessage(r));
232                 SysLog(NID_IO, "[UiBuilder] ui builder home path: %ls, res path: %ls", homePath.GetPointer(), temp.GetPointer());
233
234                 if (!pControlManager->IsCoordinateSystemLogical() || !File::IsFileExist(temp))         // if autoscale on, find ScreenSize normal
235                 {
236                         findPath = false;
237                         SysLogException(NID_UI, E_FILE_NOT_FOUND, "[E_FILE_NOT_FOUND] Parse failed -- %ls file not found.", temp.GetPointer());
238                         return E_FILE_NOT_FOUND;
239                 }
240         }
241
242         findPath = true;
243         xmlFilePath = temp;
244         r = file.Construct(xmlFilePath, L"r");
245         if (IsFailed(r))
246         {
247                 SysLogException(NID_UI, E_OPERATION_FAILED, "[E_OPERATION_FAILED] Parse Failed -- XML file Construct.");
248                 return E_OPERATION_FAILED;
249         }
250
251         r = Tizen::Io::File::GetAttributes(xmlFilePath, attrib);
252         if (IsFailed(r))
253         {
254                 SysLogException(NID_UI, E_OPERATION_FAILED, "[E_OPERATION_FAILED] Parse Failed -- XML file GetAttributes.");
255                 return E_OPERATION_FAILED;
256         }
257         size = (int) attrib.GetFileSize();
258
259         r = buffer.Construct(size);
260         if (IsFailed(r))
261         {
262                 SysLogException(NID_UI, E_OPERATION_FAILED, "[E_OPERATION_FAILED] Parse Failed - Buffer Construct Failed.");
263                 return E_OPERATION_FAILED;
264         }
265
266         r = file.Read(buffer);
267         if (IsFailed(r))
268         {
269                 SysLogException(NID_UI, E_OPERATION_FAILED, "[E_OPERATION_FAILED] Parse Failed -- can't read the file.");
270                 return E_OPERATION_FAILED;
271         }
272
273         readCount = buffer.GetPosition();
274         pXmlContents = new (std::nothrow) byte[readCount];
275         SysTryReturn(NID_UI, pXmlContents != null, E_OUT_OF_MEMORY, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Unable to create XmlContents.");
276         buffer.Flip();
277
278         r = buffer.GetArray(pXmlContents, 0, readCount);
279         if (IsFailed(r))
280         {
281                 SysLogException(NID_UI, E_OPERATION_FAILED, "[E_OPERATION_FAILED] Parse Failed -- buffer.GetArray is Failed.");
282                 delete[] pXmlContents;
283                 return E_OPERATION_FAILED;
284         }
285
286         _UiBuilderXmlHandler xmlHandler;
287         bool returnValue = false;
288         char* pXmlBuffer = (char*) pXmlContents;
289
290
291         returnValue = xmlHandler.Construct(this);
292         SysTryReturn(NID_UI, returnValue == true, E_OPERATION_FAILED, E_OPERATION_FAILED, "[E_OPERATION_FAILED] Parse Failed - xmlHandler Construct Failed.");
293
294         r = xmlHandler.ParseXml(pXmlBuffer, readCount);
295         if (r != E_SUCCESS)
296         {
297                 SysLogException(NID_UI, r, "[%s] Propagation.", GetErrorMessage(r));
298                 return r;
299         }
300
301         if (__pTransform != null)
302         {
303                 _UiBuilderControl* pUiBuilderControl;
304                 for (int i = 0; i < UIBUILDER_CONTROL_MAX_COUNT; i++)
305                 {
306                         pUiBuilderControl = GetControl(i);
307                         if (pUiBuilderControl != null)
308                         {
309                                 _UiBuilderControlLayout* pUiBuilderControlLayoutPortrait;
310                                 _UiBuilderControlLayout* pUiBuilderControlLayoutLandscape;
311
312                                 pUiBuilderControlLayoutPortrait = pUiBuilderControl->GetAttribute(UIBUILDER_ATTRIBUTE_PORTRAIT);
313                                 Rectangle rect =        pUiBuilderControlLayoutPortrait->GetRect();
314                                 Rectangle realBounds = __pTransform->Transform(rect);
315                                 pUiBuilderControlLayoutPortrait->SetRect(realBounds.x, realBounds.y, realBounds.width, realBounds.height);
316
317                                 pUiBuilderControlLayoutLandscape = pUiBuilderControl->GetAttribute(UIBUILDER_ATTRIBUTE_LANDSCAPE);
318                                 rect = pUiBuilderControlLayoutLandscape->GetRect();
319                                 realBounds = __pTransform->Transform(rect);
320                                 pUiBuilderControlLayoutLandscape->SetRect(realBounds.x, realBounds.y, realBounds.width,         realBounds.height);
321                         }
322                         else
323                         {
324                                 break;
325                         }
326                 }
327
328         }
329
330         //Make UiControls with UiBuilderControls
331         IEnumeratorT<_UiBuilderControl*>* pEnum = __pUiBuilderControlList->GetEnumeratorN();
332         SysTryCatch(NID_UI, pEnum != null, , E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Unable to get IEnumeratorT.");
333
334         while (pEnum->MoveNext() == E_SUCCESS)
335         {
336                 _UiBuilderControl* pUiBuilderControl = null;
337                 pEnum->GetCurrent(pUiBuilderControl);
338                 if (pUiBuilderControl != null)
339                 {
340                         r = MakeUI(pUiBuilderControl);
341                         SysTryCatch(NID_UI, r == E_SUCCESS, , r, "[UiBuilder] Failed to create control %ls", pUiBuilderControl->GetType().GetPointer());
342                         delete pUiBuilderControl;
343                 }
344         }
345
346         if (__pUiBuilderControlList)
347         {
348                 __pUiBuilderControlList->RemoveAll();
349                 delete __pUiBuilderControlList;
350                 __pUiBuilderControlList = null;
351         }
352
353         if (__pTransform)
354         {
355                 delete __pTransform;
356                 __pTransform = null;
357         }
358         delete[] pXmlContents;
359         delete pEnum;
360         return E_SUCCESS;
361
362         CATCH:
363         if (__pTransform)
364         {
365                 delete __pTransform;
366                 __pTransform = null;
367         }
368         delete[] pXmlContents;
369         delete pEnum;
370         return r;
371
372 }
373
374 _UiBuilderControl*
375 _UiBuilder::CreateControl(void)
376 {
377         if (__pUiBuilderControlList == null)
378         {
379                 __pUiBuilderControlList = new (std::nothrow) ArrayListT<_UiBuilderControl*>;
380                 SysTryReturn(NID_UI, __pUiBuilderControlList != null, null, E_OUT_OF_MEMORY, "[E_OUT_OF_MEMORY] Unable to create __pUiBuilderControlList.");
381         }
382
383         _UiBuilderControl* pUiBuilderControl = null;
384         pUiBuilderControl = new (std::nothrow) _UiBuilderControl;
385         if (pUiBuilderControl != null)
386         {
387                 __pUiBuilderControlList->Add(pUiBuilderControl);
388         }
389         else
390         {
391                 SysLogException(NID_UI, E_OUT_OF_MEMORY, "Failed to CreateControl()");
392                 return null;
393         }
394
395         return  pUiBuilderControl;
396 }
397
398 Tizen::Ui::Container*
399 _UiBuilder::GetContainer() const
400 {
401         return __pContainer;
402 }
403
404 void
405 _UiBuilder::SetUiBuilderRotateState(_UiBuilderScreenRotate rotate)
406 {
407         __rotate = rotate;
408 }
409
410 _UiBuilderScreenRotate
411 _UiBuilder::GetUiBuilderRotateState() const
412 {
413         return __rotate;
414 }
415
416 result
417 _UiBuilder::SetFormXmlResolution(_LogicalResolution formXmlResoluton)
418 {
419         result r = E_SUCCESS;
420
421         if (__pTransform == null)
422         {
423                 if (formXmlResoluton == RESOLUTION_LOGICAL_720 && __logicalResolution == 480)
424                 {
425                         __pTransform = _CoordinateSystem::GetTransformerN(RESOLUTION_LOGICAL_720, RESOLUTION_LOGICAL_480);
426                                 SysTryReturn(NID_UI, __pTransform != null, null, GetLastResult(),
427                                                         "Failed to get Transformer");
428                 }
429                 if (formXmlResoluton == RESOLUTION_LOGICAL_480 && __logicalResolution == 720)
430                 {
431                         __pTransform = _CoordinateSystem::GetTransformerN(RESOLUTION_LOGICAL_480, RESOLUTION_LOGICAL_720);
432                         SysTryReturn(NID_UI, __pTransform != null, GetLastResult(), GetLastResult(),
433                                                         "Failed to get Transformer");
434                 }
435         }
436         else
437         {
438                 SysLog(NID_UI, "__pTransform is already exists");
439                 r = E_SYSTEM;
440         }
441         return r;
442 }
443
444 void
445 _UiBuilder::SetLayoutOrientation(_UiBuilderControl* pUiBuilderControl, Tizen::Ui::Control* pControl)
446 {
447         _ControlImpl* pControlImpl = _ControlImpl::GetInstance(*pControl);
448         _UiBuilderControlLayout* pLayout = null;
449         Rectangle rect;
450
451         pLayout = pUiBuilderControl->GetAttribute(UIBUILDER_ATTRIBUTE_PORTRAIT);
452         rect = pLayout->GetRect();
453         pControlImpl->SetBuilderBounds(_CONTROL_ORIENTATION_PORTRAIT, rect);
454
455         pLayout = pUiBuilderControl->GetAttribute(UIBUILDER_ATTRIBUTE_LANDSCAPE);
456         rect = pLayout->GetRect();
457         pControlImpl->SetBuilderBounds(_CONTROL_ORIENTATION_LANDSCAPE, rect);
458 }
459
460 _ICoordinateSystemTransformer*
461 _UiBuilder::GetTransformer() const
462 {
463         return __pTransform;
464 }
465
466 } }  // Tizen::Ui