Added internal property for retry text and text input
[platform/core/uifw/widget-viewer-dali.git] / internal / widget_view / widget_view_impl.cpp
1 /*
2  * Samsung API
3  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
4  *
5  * Licensed under the Flora License, Version 1.1 (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 // CLASS HEADER
19 #include <internal/widget_view/widget_view_impl.h>
20
21 // INTERNAL INCLUDES
22
23 // EXTERNAL INCLUDES
24 #include <dali/public-api/common/stage.h>
25 #include <dali/public-api/events/touch-data.h>
26 #include <dali/public-api/events/wheel-event.h>
27 #include <dali/public-api/images/native-image.h>
28 #include <dali/public-api/object/type-registry.h>
29 #include <dali/public-api/object/type-registry-helper.h>
30 #include <dali-toolkit/public-api/visuals/visual-properties.h>
31 #include <dali-toolkit/devel-api/visual-factory/visual-factory.h>
32 #include <dali/integration-api/debug.h>
33 #include <string.h>
34 #include <Ecore_Input.h>
35 #include <widget_service.h>
36 #include <widget_instance.h>
37 #include <tzplatform_config.h>
38 #include <wayland-extension/tizen-extension-client-protocol.h>
39 #include <unistd.h>
40 #include <libintl.h>
41
42 namespace Dali
43 {
44
45 namespace WidgetView
46 {
47
48 namespace Internal
49 {
50
51 namespace
52 {
53
54 const int DEFAULT_FONT_PIXEL_SIZE = 30; // Referred platform widget viewer evas
55
56 #define GET_LOCALE_TEXT(string) dgettext(PKGNAME, string)
57
58 #if defined(DEBUG_ENABLED)
59 Integration::Log::Filter* gWidgetViewLogging  = Integration::Log::Filter::New( Debug::Verbose, false, "LOG_WIDGET_VIEW" );
60 #endif
61
62 BaseHandle Create()
63 {
64   return Dali::BaseHandle();
65 }
66
67 // Setup properties, signals and actions using the type-registry.
68 DALI_TYPE_REGISTRATION_BEGIN( Dali::WidgetView::WidgetView, Toolkit::Control, Create );
69 DALI_PROPERTY_REGISTRATION( Dali::WidgetView, WidgetView, "widgetId", BOOLEAN, WIDGET_ID )
70 DALI_PROPERTY_REGISTRATION( Dali::WidgetView, WidgetView, "instanceId", BOOLEAN, INSTANCE_ID )
71 DALI_PROPERTY_REGISTRATION( Dali::WidgetView, WidgetView, "contentInfo", BOOLEAN, CONTENT_INFO )
72 DALI_PROPERTY_REGISTRATION( Dali::WidgetView, WidgetView, "title", BOOLEAN, TITLE )
73 DALI_PROPERTY_REGISTRATION( Dali::WidgetView, WidgetView, "updatePeriod", BOOLEAN, UPDATE_PERIOD )
74 DALI_PROPERTY_REGISTRATION( Dali::WidgetView, WidgetView, "preview", MAP, PREVIEW )
75 DALI_PROPERTY_REGISTRATION( Dali::WidgetView, WidgetView, "loadingText", MAP, LOADING_TEXT )
76 DALI_PROPERTY_REGISTRATION( Dali::WidgetView, WidgetView, "widgetStateFaulted", BOOLEAN, WIDGET_STATE_FAULTED )
77 DALI_PROPERTY_REGISTRATION( Dali::WidgetView, WidgetView, "permanentDelete", BOOLEAN, PERMANENT_DELETE )
78
79 // Internal property
80 // ToDo it should be changed public property.
81 const int TERMINATE_WIDGET = Dali::WidgetView::WidgetView::Property::PERMANENT_DELETE+1;
82 const int RETRY_TEXT = TERMINATE_WIDGET+1;
83
84 Dali::PropertyRegistration internalProperty1( typeRegistration, "terminateWidget", TERMINATE_WIDGET, Property::BOOLEAN, Dali::WidgetView::Internal::WidgetView::SetProperty, Dali::WidgetView::Internal::WidgetView::GetProperty );
85 Dali::PropertyRegistration internalProperty2( typeRegistration, "retryText", RETRY_TEXT, Property::MAP, Dali::WidgetView::Internal::WidgetView::SetProperty, Dali::WidgetView::Internal::WidgetView::GetProperty );
86
87 // Signals
88 DALI_SIGNAL_REGISTRATION( Dali::WidgetView, WidgetView, "widgetAdded", SIGNAL_WIDGET_ADDED )
89 DALI_SIGNAL_REGISTRATION( Dali::WidgetView, WidgetView, "widgetDeleted", SIGNAL_WIDGET_DELETED )
90 DALI_SIGNAL_REGISTRATION( Dali::WidgetView, WidgetView, "widgetCreationAborted", SIGNAL_WIDGET_CREATION_ABORTED )
91 DALI_SIGNAL_REGISTRATION( Dali::WidgetView, WidgetView, "widgetContentUpdated", SIGNAL_WIDGET_CONTENT_UPDATED )
92 DALI_SIGNAL_REGISTRATION( Dali::WidgetView, WidgetView, "widgetUpdatePeriodChanged", SIGNAL_WIDGET_UPDATE_PERIOD_CHANGED )
93 DALI_SIGNAL_REGISTRATION( Dali::WidgetView, WidgetView, "widgetFaulted", SIGNAL_WIDGET_FAULTED )
94 DALI_SIGNAL_REGISTRATION( Dali::WidgetView, WidgetView, "widgetTerminated", SIGNAL_WIDGET_TERMINATED )
95
96 // Actions
97 DALI_ACTION_REGISTRATION( Dali::WidgetView, WidgetView, "pauseWidget", ACTION_WIDGETVIEW_PAUSE_WIDGET );
98 DALI_ACTION_REGISTRATION( Dali::WidgetView, WidgetView, "resumeWidget", ACTION_WIDGETVIEW_RESUME_WIDGET );
99 DALI_ACTION_REGISTRATION( Dali::WidgetView, WidgetView, "cancelTouchEvent", ACTION_WIDGETVIEW_CANCEL_TOUCH_EVENT );
100 DALI_ACTION_REGISTRATION( Dali::WidgetView, WidgetView, "activateFaultedWidget", ACTION_WIDGETVIEW_ACTIVATE_FAULTED_WIDGET );
101
102 DALI_TYPE_REGISTRATION_END()
103
104 struct wl_buffer* preBuffer;
105
106 const char* const STATE_TEXT( "stateText" );
107 const char* const FONT_STYLE( "fontStyle" );
108 const char* const TEXT_POINT_SIZE( "textPointSize" );
109 const char* const TEXT_COLOR( "textColor" );
110 const char* const TEXT_VISIBLE( "textVisible" ); //ToDo: it should be removed after retry text property is public one
111
112 static void OnBufferUpdated( struct tizen_remote_surface *surface, uint32_t type, struct wl_buffer *buffer,
113                               int32_t img_file_fd, uint32_t img_file_size, uint32_t time, struct wl_array *keys,
114                               const char *appid, const char *instance_id, const int pid, void *data)
115 {
116   Dali::WidgetView::Internal::WidgetView* widgetView = static_cast< Dali::WidgetView::Internal::WidgetView* >( data );
117
118   if( widgetView )
119   {
120     if( !widgetView->IsWidgetImageView() )
121     {
122       tizen_remote_surface_transfer_visibility( surface, TIZEN_REMOTE_SURFACE_VISIBILITY_TYPE_VISIBLE);
123
124       widgetView->CreateWidgetImageView();
125       widgetView->ConnectSignal( surface );
126     }
127
128     //get tbm surface from buffer
129     tbm_surface_h tbmSurface = static_cast< tbm_surface_h >( wl_buffer_get_user_data( buffer ) );
130     widgetView->UpdateImageSource( tbmSurface );
131   }
132
133   if( preBuffer != NULL && tizen_remote_surface_get_version( surface ) >= TIZEN_REMOTE_SURFACE_RELEASE_SINCE_VERSION )
134   {
135     tizen_remote_surface_release( surface, preBuffer );
136   }
137
138   preBuffer = buffer;
139
140   close( img_file_fd );
141 }
142
143 static void OnBufferAdded( const char *appid, const char *instance_id, const int pid, void *data )
144 {
145 }
146
147 static void OnSurfaceRemoved( const char *appid, const char *instance_id, const int pid, void *data )
148 {
149   Dali::WidgetView::Internal::WidgetView* widgetView = static_cast< Dali::WidgetView::Internal::WidgetView* >( data );
150
151   if( widgetView && !widgetView->IsWidgetFaulted() )
152   {
153     widgetView->CloseRemoteSurface();
154     widgetView->RemoveWidgetImage();
155   }
156 }
157
158 } // unnamed namespace
159
160 Dali::WidgetView::WidgetView WidgetView::New( const std::string& widgetId, const std::string& contentInfo, int width, int height, float updatePeriod )
161 {
162   // Create the implementation, temporarily owned on stack
163   IntrusivePtr< WidgetView > internalWidgetView = new WidgetView( widgetId, contentInfo, width, height, updatePeriod );
164
165   // Pass ownership to CustomActor
166   Dali::WidgetView::WidgetView widgetView( *internalWidgetView );
167
168   // Second-phase init of the implementation
169   // This can only be done after the CustomActor connection has been made...
170   internalWidgetView->Initialize();
171
172   return widgetView;
173 }
174
175 WidgetView::WidgetView()
176 : Control( ControlBehaviour( REQUIRES_TOUCH_EVENTS ) ),
177   mWidgetId(),
178   mInstanceId(),
179   mContentInfo(),
180   mTitle(),
181   mWidth( 0 ),
182   mHeight( 0 ),
183   mPid( 0 ),
184   mUpdatePeriod( 0.0 ),
185   mPreviewVisible( true ),
186   mLoadingTextVisible( true ),
187   mLoadingTextString(),
188   mRetryTextVisible( true ),
189   mRetryTextString(),
190   mRetryState( false ),
191   mPermanentDelete( false ),
192   mWatcherHandle( NULL ),
193   mRemoteSurface( NULL )
194 {
195 }
196
197 WidgetView::WidgetView( const std::string& widgetId, const std::string& contentInfo, int width, int height, float updatePeriod )
198 : Control( ControlBehaviour( REQUIRES_TOUCH_EVENTS ) ),
199   mWidgetId( widgetId ),
200   mInstanceId(),
201   mContentInfo( contentInfo ),
202   mTitle(),
203   mWidth( width ),
204   mHeight( height ),
205   mPid( 0 ),
206   mUpdatePeriod( updatePeriod ),
207   mPreviewVisible( true ),
208   mLoadingTextVisible( true ),
209   mLoadingTextString(),
210   mRetryTextVisible( true ),
211   mRetryTextString(),
212   mRetryState( false ),
213   mPermanentDelete( false ),
214   mWatcherHandle( NULL ),
215   mRemoteSurface( NULL )
216 {
217 }
218
219 WidgetView::~WidgetView()
220 {
221   TerminateWidget();
222 }
223
224 bool WidgetView::PauseWidget()
225 {
226   int ret = widget_instance_pause( mInstanceId.c_str() );
227   if( ret < 0 )
228   {
229     DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::PauseWidget: Fail to pause widget(%s, %s) [%d]\n", mWidgetId.c_str(), mInstanceId.c_str(), ret );
230     return false;
231   }
232
233   DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::PauseWidget: Widget is paused (%s, %s)\n", mWidgetId.c_str(), mInstanceId.c_str() );
234
235   return true;
236 }
237
238 bool WidgetView::ResumeWidget()
239 {
240   int ret = widget_instance_resume( mInstanceId.c_str() );
241   if( ret < 0 )
242   {
243     DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::ResumeWidget: Fail to resume widget(%s, %s) [%d]\n", mWidgetId.c_str(), mInstanceId.c_str(), ret );
244     return false;
245   }
246
247   DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::ResumeWidget: Widget is resumed (%s, %s)\n", mWidgetId.c_str(), mInstanceId.c_str() );
248
249   return true;
250 }
251
252 const std::string& WidgetView::GetWidgetId() const
253 {
254   return mWidgetId;
255 }
256
257 const std::string& WidgetView::GetInstanceId() const
258 {
259   return mInstanceId;
260 }
261
262 const std::string& WidgetView::GetContentInfo()
263 {
264   widget_instance_h instance;
265   char* contentInfo = NULL;
266
267   mContentInfo.clear();
268
269   if( mWidgetId.empty() || mInstanceId.empty() )
270   {
271     DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::GetContentInfo: Widget id (%s) or instance id (%s) is invalid.\n", mWidgetId.c_str(), mInstanceId.c_str() );
272     return mContentInfo;
273   }
274
275   instance = widget_instance_get_instance( mWidgetId.c_str(), mInstanceId.c_str() );
276   if( !instance )
277   {
278     DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::GetContentInfo: widget_instance_get_instance is failed. [%s]\n", mInstanceId.c_str() );
279     return mContentInfo;
280   }
281
282   if( widget_instance_get_content( instance, &contentInfo ) < 0 )
283   {
284     DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::GetContentInfo: Failed to get content of widget. [%s]\n", mInstanceId.c_str() );
285     return mContentInfo;
286   }
287
288   mContentInfo = reinterpret_cast< char* >( contentInfo );
289
290   return mContentInfo;
291 }
292
293 const std::string& WidgetView::GetTitle()
294 {
295   //ToDo: We should add some codes by considering widget_viewer_evas
296   if( mTitle.empty() )
297   {
298     mTitle = widget_service_get_name( mWidgetId.c_str(), NULL );
299   }
300
301   DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::GetTitle: title = %s\n", mTitle.c_str() );
302
303   return mTitle;
304 }
305
306 float WidgetView::GetUpdatePeriod() const
307 {
308   return mUpdatePeriod;
309 }
310
311 bool WidgetView::CancelTouchEvent()
312 {
313   if( mRemoteSurface )
314   {
315     tizen_remote_surface_transfer_touch_cancel( mRemoteSurface );
316     return true;
317   }
318
319   return false;
320 }
321
322 void WidgetView::SetPreviewVisible( bool visible )
323 {
324   if( mPreviewImage && mPreviewVisible != visible )
325   {
326     mPreviewVisible = visible;
327     mPreviewImage.SetVisible( visible );
328   }
329 }
330
331 bool WidgetView::IsPreviewVisible()
332 {
333   return mPreviewVisible;
334 }
335
336 void WidgetView::SetLoadingTextVisible( bool visible )
337 {
338   if( mLoadingText && mLoadingTextVisible != visible )
339   {
340     mLoadingTextVisible = visible;
341
342     if( visible )
343     {
344       mLoadingText.SetProperty( Toolkit::TextLabel::Property::TEXT, 
345                                 ( mLoadingTextString.empty() )? GET_LOCALE_TEXT( "IDS_ST_POP_LOADING_ING" ) : mLoadingTextString );
346     }
347     mLoadingText.SetVisible( visible );
348   }
349 }
350
351 void WidgetView::SetRetryTextVisible( bool visible )
352 {
353   if( mRetryText && mRetryTextVisible != visible )
354   {
355     mRetryTextVisible = visible;
356
357     if( visible )
358     {
359       mRetryText.SetProperty( Toolkit::TextLabel::Property::TEXT,
360                               ( mRetryTextString.empty() )? GET_LOCALE_TEXT( "IDS_HS_BODY_UNABLE_TO_LOAD_DATA_TAP_TO_RETRY" ) : mRetryTextString );
361     }
362     mRetryText.SetVisible( visible );
363   }
364 }
365
366 bool WidgetView::IsLoadingTextVisible()
367 {
368   return mLoadingTextVisible;
369 }
370
371 bool WidgetView::IsRetryTextVisible()
372 {
373   return mRetryTextVisible;
374 }
375
376 void WidgetView::ActivateFaultedWidget()
377 {
378   if( mPid < 0 )
379   {
380     // Enable preview and loading text
381     ShowRetryState( false );
382     ShowLoadingState( true );
383
384     // launch widget again
385     mPid = widget_instance_launch( mInstanceId.c_str(), (char *)mContentInfo.c_str(), mWidth, mHeight );
386     if( mPid < 0)
387     {
388       DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::ActivateFaultedWidget: widget_instance_launch is failed. [%s]\n", mWidgetId.c_str() );
389
390       ShowLoadingState( false );
391       ShowRetryState( true );
392
393       // Emit signal
394       Dali::WidgetView::WidgetView handle( GetOwner() );
395       mWidgetCreationAbortedSignal.Emit( handle );
396
397       return;
398     }
399
400     screen_connector_toolkit_ops ops;
401     ops.updated_cb = OnBufferUpdated;
402     ops.removed_cb = OnSurfaceRemoved;
403     ops.added_cb = OnBufferAdded;
404     mWatcherHandle = screen_connector_toolkit_add(&ops, (char *)mInstanceId.c_str(), SCREEN_CONNECTOR_SCREEEN_TYPE_WIDGET, this);
405
406     DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::ActivateFaultedWidget: widget_instance_launch is called. [%s, mPid = %d]\n", mWidgetId.c_str(), mPid );
407   }
408 }
409
410 bool WidgetView::IsWidgetFaulted()
411 {
412   return mPid < 0 ? true : false;
413 }
414
415 void WidgetView::SetPermanentDelete( bool permanentDelete )
416 {
417   mPermanentDelete = permanentDelete;
418 }
419
420 bool WidgetView::IsPermanentDelete()
421 {
422   return mPermanentDelete;
423 }
424
425 void WidgetView::CreateWidgetImageView()
426 {
427   Any source;
428   mImageSource = Dali::NativeImageSource::New( source );
429   Dali::NativeImage image = Dali::NativeImage::New( *mImageSource );
430
431   mWidgetImageView = Dali::Toolkit::ImageView::New( image );
432
433   mWidgetImageView.SetParentOrigin( ParentOrigin::CENTER );
434   mWidgetImageView.SetAnchorPoint( AnchorPoint::CENTER );
435   mWidgetImageView.SetSize( mWidth, mHeight );
436
437   Self().Add( mWidgetImageView );
438
439   //EFL app should be pre multiplied image.
440   mWidgetImageView.SetProperty( Toolkit::ImageView::Property::PRE_MULTIPLIED_ALPHA, true );
441
442   // Disable preview and text
443   ShowLoadingState( false );
444
445   // Emit signal
446   Dali::WidgetView::WidgetView handle( GetOwner() );
447   mWidgetAddedSignal.Emit( handle );
448
449   DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::CreateWidgetImageView: Widget image is added.\n" );
450 }
451
452 void WidgetView::RemoveWidgetImage()
453 {
454   mWidgetImageView.SetVisible( false );
455   mWidgetImageView.Reset();
456
457   Dali::WidgetView::WidgetView handle( GetOwner() );
458   mWidgetDeletedSignal.Emit( handle );
459
460   DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::RemoveWidgetImage: Widget image is removed.\n" );
461 }
462
463 void WidgetView::TerminateWidget()
464 {
465   if( !mWidgetId.empty() && !mInstanceId.empty() )
466   {
467     widget_instance_terminate( mInstanceId.c_str() );
468
469     if( mPermanentDelete )
470     {
471       widget_instance_destroy( mInstanceId.c_str() );
472     }
473
474     Dali::WidgetView::WidgetView handle( GetOwner() );
475     mWidgetTerminatedSignal.Emit( handle );
476     mWidgetDeletedSignal.Emit( handle );
477
478     mWidgetId.clear();
479     mInstanceId.clear();
480
481     CloseRemoteSurface();
482   }
483
484   DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::TerminateWidget: Widget is terminated/destroyed and deleted signal is emitted.\n" );
485
486 }
487
488 void WidgetView::SendWidgetEvent( int event )
489 {
490   Dali::WidgetView::WidgetView handle( GetOwner() );
491
492   DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::SendWidgetEvent: event = %d widget = %s\n", event,  mWidgetId.c_str() );
493
494   // Emit signal
495   switch( event )
496   {
497     case WIDGET_INSTANCE_EVENT_UPDATE:
498     case WIDGET_INSTANCE_EVENT_EXTRA_UPDATED:
499     {
500       mWidgetContentUpdatedSignal.Emit( handle );
501       break;
502     }
503     case WIDGET_INSTANCE_EVENT_PERIOD_CHANGED:
504     {
505       mWidgetUpdatePeriodChangedSignal.Emit( handle );
506       break;
507     }
508     case WIDGET_INSTANCE_EVENT_FAULT:
509     {
510       mPid = -1;
511       ShowRetryState( true );
512       mWidgetFaultedSignal.Emit( handle );
513       break;
514     }
515     default:
516     {
517       break;
518     }
519   }
520 }
521
522 bool WidgetView::DoConnectSignal( BaseObject* object, ConnectionTrackerInterface* tracker, const std::string& signalName, FunctorDelegate* functor )
523 {
524   Dali::BaseHandle handle( object );
525
526   bool connected( true );
527   Dali::WidgetView::WidgetView widgetView = Dali::WidgetView::WidgetView::DownCast( handle );
528
529   if( strcmp( signalName.c_str(), SIGNAL_WIDGET_ADDED ) == 0 )
530   {
531     widgetView.WidgetAddedSignal().Connect( tracker, functor );
532   }
533   else if( strcmp( signalName.c_str(), SIGNAL_WIDGET_DELETED ) == 0 )
534   {
535     widgetView.WidgetDeletedSignal().Connect( tracker, functor );
536   }
537   else if( strcmp( signalName.c_str(), SIGNAL_WIDGET_CREATION_ABORTED ) == 0 )
538   {
539     widgetView.WidgetCreationAbortedSignal().Connect( tracker, functor );
540   }
541   else if( strcmp( signalName.c_str(), SIGNAL_WIDGET_CONTENT_UPDATED ) == 0 )
542   {
543     widgetView.WidgetContentUpdatedSignal().Connect( tracker, functor );
544   }
545   else if( strcmp( signalName.c_str(), SIGNAL_WIDGET_UPDATE_PERIOD_CHANGED ) == 0 )
546   {
547     widgetView.WidgetUpdatePeriodChangedSignal().Connect( tracker, functor );
548   }
549   else if( strcmp( signalName.c_str(), SIGNAL_WIDGET_FAULTED ) == 0 )
550   {
551     widgetView.WidgetFaultedSignal().Connect( tracker, functor );
552   }
553   else
554   {
555     // signalName does not match any signal
556     connected = false;
557   }
558
559   return connected;
560 }
561
562 bool WidgetView::DoAction( BaseObject* object, const std::string& actionName, const Property::Map& attributes )
563 {
564   bool ret = true;
565
566   Dali::BaseHandle handle( object );
567   Dali::WidgetView::WidgetView widgetView = Dali::WidgetView::WidgetView::DownCast( handle );
568
569   if( !widgetView )
570   {
571     return false;
572   }
573
574   WidgetView& impl = GetImplementation( widgetView );
575
576   if( strcmp( actionName.c_str(), ACTION_WIDGETVIEW_PAUSE_WIDGET ) == 0 )
577   {
578     impl.PauseWidget();
579   }
580   else if( strcmp( actionName.c_str(), ACTION_WIDGETVIEW_RESUME_WIDGET ) == 0 )
581   {
582     impl.ResumeWidget();
583   }
584   else if( strcmp( actionName.c_str(), ACTION_WIDGETVIEW_CANCEL_TOUCH_EVENT ) == 0 )
585   {
586     impl.CancelTouchEvent();
587   }
588   else if( strcmp( actionName.c_str(), ACTION_WIDGETVIEW_ACTIVATE_FAULTED_WIDGET ) == 0 )
589   {
590     impl.ActivateFaultedWidget();
591   }
592   else
593   {
594     ret = false;
595   }
596
597   return ret;
598 }
599
600 void WidgetView::SetProperty( BaseObject* object, Property::Index index, const Property::Value& value )
601 {
602   Dali::WidgetView::WidgetView widgetView = Dali::WidgetView::WidgetView::DownCast( Dali::BaseHandle( object ) );
603
604   if( widgetView )
605   {
606     WidgetView& impl = GetImplementation( widgetView );
607
608     switch( index )
609     {
610       case Dali::WidgetView::WidgetView::Property::PREVIEW:
611       {
612         bool previewEnabled;
613
614         if( value.Get( previewEnabled ) )
615         {
616           impl.SetPreviewVisible( previewEnabled );
617         }
618         break;
619       }
620       case Dali::WidgetView::WidgetView::Property::LOADING_TEXT:
621       {
622         bool textEnabled;
623         Property::Map map;
624
625         if( value.Get( textEnabled ) )
626         {
627           impl.SetLoadingTextVisible( textEnabled );
628         }
629         else if( value.Get( map ) )
630         {
631           impl.SetLoadingTextPropertyMap( map );
632         }
633         break;
634       }
635       case Dali::WidgetView::WidgetView::Property::PERMANENT_DELETE:
636       {
637         bool permanent;
638         if( value.Get( permanent ) )
639         {
640           impl.SetPermanentDelete( permanent );
641         }
642         break;
643       }
644       case TERMINATE_WIDGET:
645       {
646         bool del = false;
647         if( value.Get( del ) && del )
648         {
649           impl.TerminateWidget();
650         }
651       }
652       case RETRY_TEXT:
653       {
654         Property::Map map;
655
656         if( value.Get( map ) )
657         {
658           impl.SetRetryTextPropertyMap( map );
659         }
660         break;
661       }
662     }
663   }
664 }
665
666 Property::Value WidgetView::GetProperty( BaseObject* object, Property::Index index )
667 {
668   Property::Value value;
669   Dali::WidgetView::WidgetView widgetView = Dali::WidgetView::WidgetView::DownCast( Dali::BaseHandle( object ) );
670
671   if( widgetView )
672   {
673     WidgetView& impl = GetImplementation( widgetView );
674
675     switch( index )
676     {
677       case Dali::WidgetView::WidgetView::Property::WIDGET_ID:
678       {
679         value = impl.GetWidgetId();
680         break;
681       }
682       case Dali::WidgetView::WidgetView::Property::INSTANCE_ID:
683       {
684         value = impl.GetInstanceId();
685         break;
686       }
687       case Dali::WidgetView::WidgetView::Property::CONTENT_INFO:
688       {
689         value = impl.GetContentInfo();
690         break;
691       }
692       case Dali::WidgetView::WidgetView::Property::TITLE:
693       {
694         value = impl.GetTitle();
695         break;
696       }
697       case Dali::WidgetView::WidgetView::Property::UPDATE_PERIOD:
698       {
699         value = impl.GetUpdatePeriod();
700         break;
701       }
702       case Dali::WidgetView::WidgetView::Property::PREVIEW:
703       {
704         value = impl.IsPreviewVisible();
705         break;
706       }
707       case Dali::WidgetView::WidgetView::Property::LOADING_TEXT:
708       {
709         value = impl.IsLoadingTextVisible();
710         break;
711       }
712       case Dali::WidgetView::WidgetView::Property::WIDGET_STATE_FAULTED:
713       {
714         value = impl.IsWidgetFaulted();
715         break;
716       }
717       case Dali::WidgetView::WidgetView::Property::PERMANENT_DELETE:
718       {
719         value = impl.IsPermanentDelete();
720         break;
721       }
722     }
723   }
724
725   return value;
726 }
727
728 Dali::WidgetView::WidgetView::WidgetViewSignalType& WidgetView::WidgetAddedSignal()
729 {
730   return mWidgetAddedSignal;
731 }
732
733 Dali::WidgetView::WidgetView::WidgetViewSignalType& WidgetView::WidgetDeletedSignal()
734 {
735   return mWidgetDeletedSignal;
736 }
737
738 Dali::WidgetView::WidgetView::WidgetViewSignalType& WidgetView::WidgetCreationAbortedSignal()
739 {
740   return mWidgetCreationAbortedSignal;
741 }
742
743 Dali::WidgetView::WidgetView::WidgetViewSignalType& WidgetView::WidgetContentUpdatedSignal()
744 {
745   return mWidgetContentUpdatedSignal;
746 }
747
748 Dali::WidgetView::WidgetView::WidgetViewSignalType& WidgetView::WidgetUpdatePeriodChangedSignal()
749 {
750   return mWidgetUpdatePeriodChangedSignal;
751 }
752
753 Dali::WidgetView::WidgetView::WidgetViewSignalType& WidgetView::WidgetFaultedSignal()
754 {
755   return mWidgetFaultedSignal;
756 }
757
758 Dali::WidgetView::WidgetView::WidgetViewSignalType& WidgetView::WidgetTerminatedSignal()
759 {
760   return mWidgetTerminatedSignal;
761 }
762
763 void WidgetView::OnInitialize()
764 {
765   char* instanceId = NULL;
766   char* previewPath = NULL;
767   std::string previewImage;
768   widget_size_type_e sizeType;
769   screen_connector_toolkit_ops ops;
770
771   int ret = widget_instance_create( mWidgetId.c_str(), &instanceId );
772   if( ret < 0 || !instanceId )
773   {
774     DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::OnInitialize: widget_instance_create is failed [%s].\n", mWidgetId.c_str() );
775     return;
776   }
777
778   DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::OnInitialize: widget_instance_create is called. [widget id = %s, instance id = %s]\n",
779                  mWidgetId.c_str(), instanceId );
780
781   mInstanceId = instanceId;
782
783   // Preview image
784   widget_service_get_size_type( mWidth, mHeight, &sizeType );
785
786   previewPath = widget_service_get_preview_image_path( mWidgetId.c_str(), sizeType );
787   if( previewPath )
788   {
789     previewImage = previewPath;
790     free( previewPath );
791   }
792   else
793   {
794     previewImage = WIDGET_VIEW_RESOURCE_DEFAULT_IMG;
795   }
796
797   DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::OnInitialize: preview image path = %s\n", previewImage.c_str() );
798
799
800   mPreviewActor = Dali::Actor::New();
801   mPreviewActor.SetParentOrigin( ParentOrigin::CENTER );
802   mPreviewActor.SetAnchorPoint( AnchorPoint::CENTER );
803   mPreviewActor.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
804
805   mPreviewImage = Toolkit::ImageView::New( previewImage );
806   mPreviewImage.SetParentOrigin( ParentOrigin::CENTER );
807   mPreviewImage.SetAnchorPoint( AnchorPoint::CENTER );
808   mPreviewImage.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
809
810   Self().SetResizePolicy( ResizePolicy::FIXED, Dimension::ALL_DIMENSIONS );
811   Self().SetSize( mWidth, mHeight );
812
813   Self().Add( mPreviewActor );
814   mPreviewActor.Add( mPreviewImage );
815
816   mStateTextActor = Dali::Actor::New();
817   mStateTextActor.SetParentOrigin( ParentOrigin::CENTER );
818   mStateTextActor.SetAnchorPoint( AnchorPoint::CENTER );
819   mStateTextActor.SetResizePolicy( ResizePolicy::FILL_TO_PARENT, Dimension::ALL_DIMENSIONS );
820
821   // Loading text
822   mLoadingText = Toolkit::TextLabel::New( ( mLoadingTextString.empty() )? GET_LOCALE_TEXT( "IDS_ST_POP_LOADING_ING" ) : mLoadingTextString );
823   mLoadingText.SetParentOrigin( ParentOrigin::CENTER );
824   mLoadingText.SetAnchorPoint( AnchorPoint::CENTER );
825   mLoadingText.SetProperty( Toolkit::TextLabel::Property::HORIZONTAL_ALIGNMENT, "CENTER" );
826   mLoadingText.SetProperty( Toolkit::TextLabel::Property::VERTICAL_ALIGNMENT, "CENTER" );
827   mLoadingText.SetProperty( Toolkit::TextLabel::Property::TEXT_COLOR, Dali::Color::WHITE );
828   mLoadingText.SetProperty( Toolkit::TextLabel::Property::FONT_STYLE, "Bold" );
829   mLoadingText.SetProperty( Toolkit::TextLabel::Property::POINT_SIZE, TextPixelToPointSize( DEFAULT_FONT_PIXEL_SIZE ) );
830
831   mPreviewActor.Add( mStateTextActor );
832   mStateTextActor.Add( mLoadingText );
833
834   // Retry text
835   mRetryText = Toolkit::TextLabel::New( ( mRetryTextString.empty() )? GET_LOCALE_TEXT( "IDS_HS_BODY_UNABLE_TO_LOAD_DATA_TAP_TO_RETRY" ) : mRetryTextString );
836   mRetryText.SetParentOrigin( ParentOrigin::CENTER );
837   mRetryText.SetAnchorPoint( AnchorPoint::CENTER );
838   mRetryText.SetProperty( Toolkit::TextLabel::Property::HORIZONTAL_ALIGNMENT, "CENTER" );
839   mRetryText.SetProperty( Toolkit::TextLabel::Property::VERTICAL_ALIGNMENT, "CENTER" );
840   mRetryText.SetProperty( Toolkit::TextLabel::Property::TEXT_COLOR, Dali::Color::WHITE );
841   mRetryText.SetProperty( Toolkit::TextLabel::Property::FONT_STYLE, "Bold" );
842   mRetryText.SetProperty( Toolkit::TextLabel::Property::POINT_SIZE, TextPixelToPointSize( DEFAULT_FONT_PIXEL_SIZE ) );
843
844   mStateTextActor.Add( mRetryText );
845   mRetryText.SetVisible( false );
846
847   // launch widget
848   mPid = widget_instance_launch( instanceId, (char *)mContentInfo.c_str(), mWidth, mHeight );
849   if( mPid < 0)
850   {
851
852     ShowLoadingState( false );
853     ShowRetryState( true );
854
855     DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::OnInitialize: widget_instance_launch is failed. [%s]\n", mWidgetId.c_str() );
856
857     // Emit signal
858     Dali::WidgetView::WidgetView handle( GetOwner() );
859     mWidgetCreationAbortedSignal.Emit( handle );
860
861     return;
862   }
863
864   ops.updated_cb = OnBufferUpdated;
865   ops.removed_cb = OnSurfaceRemoved;
866   ops.added_cb = OnBufferAdded;
867   mWatcherHandle = screen_connector_toolkit_add(&ops, (char *)instanceId, SCREEN_CONNECTOR_SCREEEN_TYPE_WIDGET, this);
868   DALI_LOG_INFO( gWidgetViewLogging, Debug::Verbose, "WidgetView::OnInitialize: widget_instance_launch is called. [%s, mPid = %d]\n", mWidgetId.c_str(), mPid );
869
870 }
871
872 void WidgetView::OnStageConnection( int depth )
873 {
874   Control::OnStageConnection( depth );
875 }
876
877 void WidgetView::OnStageDisconnection()
878 {
879   Control::OnStageDisconnection();
880 }
881
882 void WidgetView::OnSizeSet( const Vector3& targetSize )
883 {
884   if( mWidgetImageView )
885   {
886     mWidgetImageView.SetSize( targetSize );
887   }
888 }
889
890 bool WidgetView::IsWidgetImageView()
891 {
892   return ( mWidgetImageView )? true: false;
893 }
894
895 void WidgetView::UpdateImageSource( tbm_surface_h source )
896 {
897   mImageSource->SetSource( source );
898   Dali::Stage::GetCurrent().KeepRendering( 0.0f );
899 }
900
901 void WidgetView::ConnectSignal( tizen_remote_surface* surface )
902 {
903   if( mWidgetImageView && surface )
904   {
905     mRemoteSurface = surface;
906
907     Self().TouchSignal().Connect( this, &WidgetView::OnTouch );
908     Self().WheelEventSignal().Connect( this, &WidgetView::OnWheelEvent );
909   }
910
911 }
912
913 bool WidgetView::OnTouch( Dali::Actor actor, const Dali::TouchData& event )
914 {
915   tizen_remote_surface_event_type type = TIZEN_REMOTE_SURFACE_EVENT_TYPE_NONE;
916
917   if( event.GetPointCount() == 0 )
918   {
919     return false;
920   }
921
922   switch( event.GetState( 0 ) )
923   {
924     case Dali::PointState::UP:
925     {
926       type = TIZEN_REMOTE_SURFACE_EVENT_TYPE_MOUSE_UP;
927
928       if( mRetryState )
929       {
930         ActivateFaultedWidget();
931         return false;
932       }
933
934       break;
935     }
936     case Dali::PointState::DOWN:
937     {
938       type = TIZEN_REMOTE_SURFACE_EVENT_TYPE_MOUSE_DOWN;
939       break;
940     }
941     case Dali::PointState::MOTION:
942     {
943       type = TIZEN_REMOTE_SURFACE_EVENT_TYPE_MOUSE_MOVE;
944       break;
945     }
946     default:
947     {
948       return false;
949     }
950   }
951
952   if( mRemoteSurface == NULL )
953   {
954     return false;
955   }
956
957   int button = 1;
958
959   if( type == TIZEN_REMOTE_SURFACE_EVENT_TYPE_MOUSE_MOVE )
960   {
961     button = 0 ;
962   }
963
964   Vector2 localPos = event.GetLocalPosition( 0 );
965
966   tizen_remote_surface_transfer_mouse_event( mRemoteSurface,
967                                              type,
968                                              0,
969                                              button,
970                                              (int)localPos.x,
971                                              (int)localPos.y,
972                                              wl_fixed_from_double( event.GetEllipseRadius( 0 ).x ),
973                                              wl_fixed_from_double( event.GetEllipseRadius( 0 ).y ),
974                                              wl_fixed_from_double( event.GetPressure( 0 ) ),
975                                              wl_fixed_from_double( event.GetAngle( 0 ).degree ),
976                                              TIZEN_INPUT_DEVICE_CLAS_TOUCHSCREEN,
977                                              TIZEN_INPUT_DEVICE_SUBCLAS_NONE,
978                                              "",
979                                              event.GetTime()
980                                            );
981   return true;
982 }
983
984 bool WidgetView::OnWheelEvent( Dali::Actor actor, const Dali::WheelEvent& event )
985 {
986   if( mRemoteSurface == NULL )
987   {
988     return false;
989   }
990   //ToDo: We should check TIZEN_INPUT_DEVICE_CLAS_MOUSE
991   tizen_remote_surface_transfer_mouse_wheel( mRemoteSurface,
992                                              event.direction,
993                                              event.z,
994                                              TIZEN_INPUT_DEVICE_CLAS_MOUSE,
995                                              TIZEN_INPUT_DEVICE_SUBCLAS_NONE,
996                                              "",
997                                              event.timeStamp
998                                            );
999   return true;
1000 }
1001
1002 Vector3 WidgetView::GetNaturalSize()
1003 {
1004   Vector3 size;
1005   size.x = mWidth;
1006   size.y = mHeight;
1007
1008   if( size.x > 0 && size.y > 0 )
1009   {
1010     size.z = std::min( size.x, size.y );
1011     return size;
1012   }
1013   else
1014   {
1015     return Control::GetNaturalSize();
1016   }
1017 }
1018
1019 float WidgetView::GetHeightForWidth( float width )
1020 {
1021   if( mWidth > 0 && mHeight > 0 )
1022   {
1023     return GetHeightForWidthBase( width );
1024   }
1025   else
1026   {
1027     return Control::GetHeightForWidthBase( width );
1028   }
1029 }
1030
1031 float WidgetView::GetWidthForHeight( float height )
1032 {
1033   if( mWidth > 0 && mHeight > 0 )
1034   {
1035     return GetWidthForHeightBase( height );
1036   }
1037   else
1038   {
1039     return Control::GetWidthForHeightBase( height );
1040   }
1041 }
1042
1043 void WidgetView::CloseRemoteSurface()
1044 {
1045   if( mWatcherHandle != NULL )
1046   {
1047     screen_connector_toolkit_remove( mWatcherHandle );
1048     mWatcherHandle = NULL;
1049   }
1050   mRemoteSurface = NULL;
1051   mPid = -1;
1052 }
1053
1054 void WidgetView::ShowLoadingState( bool show )
1055 {
1056   if( mPreviewImage && mPreviewVisible )
1057   {
1058     mPreviewImage.SetVisible( show );
1059   }
1060
1061   if( mLoadingText && mLoadingTextVisible )
1062   {
1063     mLoadingText.SetProperty( Toolkit::TextLabel::Property::TEXT,
1064                               ( mLoadingTextString.empty() )? GET_LOCALE_TEXT( "IDS_ST_POP_LOADING_ING" ) : mLoadingTextString );
1065     mLoadingText.SetVisible( show );
1066   }
1067 }
1068
1069 void WidgetView::ShowRetryState( bool show )
1070 {
1071   if( mPreviewImage && mPreviewVisible )
1072   {
1073     mPreviewImage.SetVisible( false );
1074   }
1075
1076   if( mRetryText && mRetryTextVisible )
1077   {
1078     mRetryText.SetProperty( Toolkit::TextLabel::Property::TEXT,
1079                             ( mRetryTextString.empty() )? GET_LOCALE_TEXT( "IDS_HS_BODY_UNABLE_TO_LOAD_DATA_TAP_TO_RETRY" ) : mRetryTextString );
1080     mRetryText.SetVisible( show );
1081     mRetryState = show;
1082   }
1083 }
1084
1085 void WidgetView::SetLoadingTextPropertyMap( Property::Map map )
1086 {
1087   if( mLoadingText )
1088   {
1089     Property::Value* loadingText = map.Find( STATE_TEXT );
1090     std::string text;
1091     if( loadingText && loadingText->Get( text ) )
1092     {
1093       mLoadingText.SetProperty( Toolkit::TextLabel::Property::TEXT, text );
1094       mLoadingTextString = text;
1095     }
1096
1097     Property::Value* fontStyle = map.Find( FONT_STYLE );
1098     std::string style;
1099
1100     if( fontStyle && fontStyle->Get( style ) )
1101     {
1102       mLoadingText.SetProperty( Toolkit::TextLabel::Property::FONT_STYLE, style );
1103     }
1104
1105     Property::Value* textPointSize = map.Find( TEXT_POINT_SIZE );
1106     float size = 0.f;
1107
1108     if( textPointSize && textPointSize->Get( size ) )
1109     {
1110       mLoadingText.SetProperty( Toolkit::TextLabel::Property::POINT_SIZE, size );
1111     }
1112
1113     Property::Value* textColor = map.Find( TEXT_COLOR );
1114     Vector4 color;
1115
1116     if( textColor && textColor->Get( color ) )
1117     {
1118       mLoadingText.SetProperty( Toolkit::TextLabel::Property::TEXT_COLOR, color );
1119     }
1120   }
1121 }
1122
1123 void WidgetView::SetRetryTextPropertyMap( Property::Map map )
1124 {
1125   if( mRetryText )
1126   {
1127     Property::Value* retryText = map.Find( STATE_TEXT );
1128     std::string text;
1129     if( retryText && retryText->Get( text ) )
1130     {
1131       mRetryText.SetProperty( Toolkit::TextLabel::Property::TEXT, text );
1132       mRetryTextString = text;
1133     }
1134
1135     Property::Value* fontStyle = map.Find( FONT_STYLE );
1136     std::string style;
1137
1138     if( fontStyle && fontStyle->Get( style ) )
1139     {
1140       mRetryText.SetProperty( Toolkit::TextLabel::Property::FONT_STYLE, style );
1141     }
1142
1143     Property::Value* textPointSize = map.Find( TEXT_POINT_SIZE );
1144     float size = 0.f;
1145
1146     if( textPointSize && textPointSize->Get( size ) )
1147     {
1148       mRetryText.SetProperty( Toolkit::TextLabel::Property::POINT_SIZE, size );
1149     }
1150
1151     Property::Value* textColor = map.Find( TEXT_COLOR );
1152     Vector4 color;
1153
1154     if( textColor && textColor->Get( color ) )
1155     {
1156       mRetryText.SetProperty( Toolkit::TextLabel::Property::TEXT_COLOR, color );
1157     }
1158
1159     Property::Value* textVisible = map.Find( TEXT_VISIBLE );
1160     bool visible = true;
1161     if( textVisible && textVisible->Get( visible ) )
1162     {
1163       SetRetryTextVisible( visible );
1164     }
1165   }
1166 }
1167
1168 float WidgetView::TextPixelToPointSize( int pixelSize )
1169 {
1170   Dali::Vector2 dpi = Dali::Stage::GetCurrent().GetDpi();
1171   float meanDpi = (dpi.height + dpi.width) / 2.0f;
1172
1173   return (pixelSize * 72.0f) / meanDpi;
1174 }
1175
1176 } // namespace Internal
1177
1178 } // namespace WidgetView
1179
1180 } // namespace Dali