[widget-viewer-dali] Add WidgetView::CancelTouchEvent()
[platform/core/uifw/widget-viewer-dali.git] / internal / widget_view / widget_view_impl.cpp
1 /*
2  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // CLASS HEADER
19 #include <internal/widget_view/widget_view_impl.h>
20
21 // INTERNAL INCLUDES
22
23 // EXTERNAL INCLUDES
24 #include <dali/integration-api/debug.h>
25 #include <string.h>
26 #include <widget_service.h>
27 #include <widget_instance.h>
28 #include <tzplatform_config.h>
29
30 namespace Dali
31 {
32
33 namespace WidgetView
34 {
35
36 namespace Internal
37 {
38
39 namespace
40 {
41
42 #define WIDGET_VIEW_RESOURCE_DEFAULT_IMG "/widget_viewer_dali/images/unknown.png"
43
44 #if defined(DEBUG_ENABLED)
45 Integration::Log::Filter* gWidgetViewLogging  = Integration::Log::Filter::New( Debug::Verbose, false, "LOG_WIDGET_VIEW" );
46 #endif
47
48 } // unnamed namespace
49
50 Dali::WidgetView::WidgetView WidgetView::New( const std::string& widgetId, const std::string& contentInfo, int width, int height, double period )
51 {
52   // Create the implementation, temporarily owned on stack
53   IntrusivePtr< WidgetView > internalWidgetView = new WidgetView( widgetId, contentInfo, width, height, period );
54
55   // Pass ownership to CustomActor
56   Dali::WidgetView::WidgetView widgetView( *internalWidgetView );
57
58   // Second-phase init of the implementation
59   // This can only be done after the CustomActor connection has been made...
60   internalWidgetView->Initialize();
61
62   return widgetView;
63 }
64
65 WidgetView::WidgetView()
66 : Control( ControlBehaviour( REQUIRES_TOUCH_EVENTS ) ),
67   mWidgetId(),
68   mInstanceId(),
69   mContentInfo(),
70   mTitle(),
71   mBundle( NULL ),
72   mWidth( 0 ),
73   mHeight( 0 ),
74   mPid( 0 ),
75   mPeriod( 0.0 ),
76   mPreviewEnabled( true ),
77   mStateTextEnabled( true ),
78   mPermanentDelete( true )
79 {
80 }
81
82 WidgetView::WidgetView( const std::string& widgetId, const std::string& contentInfo, int width, int height, double period )
83 : Control( ControlBehaviour( REQUIRES_TOUCH_EVENTS ) ),
84   mWidgetId( widgetId ),
85   mInstanceId(),
86   mContentInfo( contentInfo ),
87   mTitle(),
88   mBundle( NULL ),
89   mWidth( width ),
90   mHeight( height ),
91   mPid( 0 ),
92   mPeriod( period ),
93   mPreviewEnabled( true ),
94   mStateTextEnabled( true ),
95   mPermanentDelete( true )
96 {
97 }
98
99 WidgetView::~WidgetView()
100 {
101   if( !mWidgetId.empty() && !mInstanceId.empty() )
102   {
103     widget_instance_terminate( mWidgetId.c_str(), mInstanceId.c_str() );
104
105     if( mPermanentDelete )
106     {
107       widget_instance_destroy( mWidgetId.c_str(), mInstanceId.c_str() );
108     }
109   }
110
111   if( mBundle )
112   {
113     bundle_free( mBundle );
114   }
115 }
116
117 const std::string& WidgetView::GetWidgetId() const
118 {
119   return mWidgetId;
120 }
121
122 const std::string& WidgetView::GetInstanceId() const
123 {
124   return mInstanceId;
125 }
126
127 const std::string& WidgetView::GetContentInfo()
128 {
129   widget_instance_h instance;
130   bundle* bundle = NULL;
131   bundle_raw* contentInfo = NULL;
132   int contentLength = 0;
133
134   mContentInfo.clear();
135
136   if( mWidgetId.empty() || mInstanceId.empty() )
137   {
138     DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::GetContentInfo: Widget id (%s) or instance id (%s) is invalid.\n", mWidgetId.c_str(), mInstanceId.c_str() );
139     return mContentInfo;
140   }
141
142   instance = widget_instance_get_instance( mWidgetId.c_str(), mInstanceId.c_str() );
143   if( !instance )
144   {
145     DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::GetContentInfo: widget_instance_get_instance is failed. [%s]\n", mInstanceId.c_str() );
146     return mContentInfo;
147   }
148
149   if( widget_instance_get_content( instance, &bundle ) < 0 )
150   {
151     DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::GetContentInfo: Failed to get content of widget. [%s]\n", mInstanceId.c_str() );
152     return mContentInfo;
153   }
154
155   if( !bundle )
156   {
157     DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::GetContentInfo: Cotent of widget [%s] is invalid.\n", mInstanceId.c_str() );
158     return mContentInfo;
159   }
160
161   if( bundle_encode( bundle, &contentInfo, &contentLength ) < 0 )
162   {
163     DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::GetContentInfo: bundle_encode is failed. [%s]\n", mInstanceId.c_str() );
164     return mContentInfo;
165   }
166
167   mContentInfo = reinterpret_cast< char* >( contentInfo );
168
169   return mContentInfo;
170 }
171
172 const std::string& WidgetView::GetTitle()
173 {
174   if( mObjectView )
175   {
176     mTitle = mObjectView.GetTitle();
177     if( mTitle.empty() )
178     {
179       mTitle = widget_service_get_name( mWidgetId.c_str(), NULL );
180     }
181   }
182
183   DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::GetTitle: title = %s\n", mTitle.c_str() );
184
185   return mTitle;
186 }
187
188 double WidgetView::GetPeriod() const
189 {
190   return mPeriod;
191 }
192
193 bool WidgetView::CancelTouchEvent()
194 {
195   if( mObjectView )
196   {
197     return mObjectView.CancelTouchEvent();
198   }
199
200   return false;
201 }
202
203 void WidgetView::SetPreviewEnabled( bool enabled )
204 {
205   mPreviewEnabled = enabled;
206
207   if( mPreviewImage )
208   {
209     mPreviewImage.SetVisible( enabled );
210   }
211 }
212
213 bool WidgetView::GetPreviewEnabled() const
214 {
215   return mPreviewEnabled;
216 }
217
218 void WidgetView::SetStateTextEnabled( bool enabled )
219 {
220   mStateTextEnabled = enabled;
221
222   if( mStateText )
223   {
224     mStateText.SetVisible( enabled );
225   }
226 }
227
228 bool WidgetView::GetStateTextEnabled() const
229 {
230   return mStateTextEnabled;
231 }
232
233 void WidgetView::ActivateFaultedWidget()
234 {
235   if( mPid < 0 )
236   {
237     // Esable preview and text
238     if( mPreviewEnabled )
239     {
240       mPreviewImage.SetVisible( true );
241     }
242
243     if( mStateTextEnabled )
244     {
245       mStateText.SetVisible( true );
246     }
247
248     // launch widget again
249     mPid = widget_instance_launch( mWidgetId.c_str(), mInstanceId.c_str(), mBundle, mWidth, mHeight );
250     if( mPid < 0)
251     {
252       DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::ActivateFaultedWidget: widget_instance_launch is failed. [%s]\n", mWidgetId.c_str() );
253       return;
254     }
255
256     DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::ActivateFaultedWidget: widget_instance_launch is called. [%s, mPid = %d]\n", mWidgetId.c_str(), mPid );
257   }
258 }
259
260 bool WidgetView::IsWidgetFaulted()
261 {
262   return mPid < 0 ? true : false;
263 }
264
265 void WidgetView::SetPermanentDelete( bool permanentDelete )
266 {
267   mPermanentDelete = permanentDelete;
268 }
269
270 void WidgetView::AddObjectView( Pepper::ObjectView objectView )
271 {
272   mObjectView = objectView;
273
274   mObjectView.SetParentOrigin( ParentOrigin::CENTER );
275   mObjectView.SetAnchorPoint( AnchorPoint::CENTER );
276
277   Self().Add( mObjectView );
278
279   // Disable preview and text
280   if( mPreviewEnabled )
281   {
282     mPreviewImage.SetVisible( false );
283   }
284
285   if( mStateTextEnabled )
286   {
287     mStateText.SetVisible( false );
288   }
289
290   // Emit signal
291   Dali::WidgetView::WidgetView handle( GetOwner() );
292   mWidgetAddedSignal.Emit( handle );
293 }
294
295 void WidgetView::RemoveObjectView()
296 {
297   // Emit signal
298   Dali::WidgetView::WidgetView handle( GetOwner() );
299   mWidgetDeletedSignal.Emit( handle );
300
301   mObjectView.Reset();
302 }
303
304 Dali::WidgetView::WidgetView::WidgetViewSignalType& WidgetView::WidgetAddedSignal()
305 {
306   return mWidgetAddedSignal;
307 }
308
309 Dali::WidgetView::WidgetView::WidgetViewSignalType& WidgetView::WidgetDeletedSignal()
310 {
311   return mWidgetDeletedSignal;
312 }
313
314 void WidgetView::OnInitialize()
315 {
316   char* instanceId = NULL;
317   char* previewPath = NULL;
318   std::string previewImage;
319   widget_size_type_e sizeType;
320
321   if( !mContentInfo.empty() )
322   {
323     DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::OnInitialize: decode bundle\n" );
324
325     mBundle = bundle_decode( reinterpret_cast< const bundle_raw* >( mContentInfo.c_str() ), mContentInfo.length() );
326     if( !mBundle )
327     {
328       DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::OnInitialize: Invalid bundle data.\n" );
329       return;
330     }
331
332     bundle_get_str( mBundle, WIDGET_K_INSTANCE, &instanceId );
333   }
334
335   if( !instanceId )
336   {
337     int ret = widget_instance_create( mWidgetId.c_str(), &instanceId );
338     if( ret < 0 || !instanceId )
339     {
340       DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::OnInitialize: widget_instance_create is failed [%s].\n", mWidgetId.c_str() );
341       return;
342     }
343
344     DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::OnInitialize: widget_instance_create is called. [widget id = %s, instance id = %s]\n",
345                    mWidgetId.c_str(), instanceId );
346   }
347
348   mInstanceId = instanceId;
349
350   // Preview image
351   widget_service_get_size_type( mWidth, mHeight, &sizeType );
352
353   previewPath = widget_service_get_preview_image_path( mWidgetId.c_str(), sizeType );
354   if( previewPath )
355   {
356     previewImage = previewPath;
357     free( previewPath );
358   }
359   else
360   {
361     previewImage = tzplatform_getenv( TZ_SYS_SHARE );
362     previewImage.append( WIDGET_VIEW_RESOURCE_DEFAULT_IMG );
363   }
364
365   DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::OnInitialize: preview image path = %s\n", previewImage.c_str() );
366
367   mPreviewImage = Toolkit::ImageView::New( previewImage );
368
369   mPreviewImage.SetParentOrigin( ParentOrigin::CENTER );
370   mPreviewImage.SetAnchorPoint( AnchorPoint::CENTER );
371
372   if( !previewPath )
373   {
374     mPreviewImage.SetSize( mWidth, mHeight );
375   }
376
377   Self().SetResizePolicy( ResizePolicy::FIT_TO_CHILDREN, Dimension::ALL_DIMENSIONS );
378   Self().Add( mPreviewImage );
379
380   // State text
381   // TODO: use po files
382   mStateText = Toolkit::TextLabel::New( "Loading..." );
383
384   mStateText.SetParentOrigin( ParentOrigin::CENTER );
385   mStateText.SetAnchorPoint( AnchorPoint::CENTER );
386   mStateText.SetProperty( Toolkit::TextLabel::Property::HORIZONTAL_ALIGNMENT, "CENTER" );
387   mStateText.SetProperty( Toolkit::TextLabel::Property::VERTICAL_ALIGNMENT, "CENTER" );
388
389   mPreviewImage.Add( mStateText );
390
391   // launch widget
392   mPid = widget_instance_launch( mWidgetId.c_str(), instanceId, mBundle, mWidth, mHeight );
393   if( mPid < 0)
394   {
395     DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::OnInitialize: widget_instance_launch is failed. [%s]\n", mWidgetId.c_str() );
396     return;
397   }
398
399   DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::OnInitialize: widget_instance_launch is called. [%s, mPid = %d]\n", mWidgetId.c_str(), mPid );
400 }
401
402 } // namespace Internal
403
404 } // namespace WidgetView
405
406 } // namespace Dali