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