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