[Tizen] Apply modified interface of SurfaceResized
[platform/core/uifw/dali-extension.git] / dali-extension / internal / evas-plugin / scene-impl.cpp
1 /*
2  * Copyright (c) 2020 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *
16  */
17
18 // EXTERNAL INCLUDES
19 #include <dali/devel-api/adaptor-framework/clipboard.h>
20 #include <dali/devel-api/adaptor-framework/accessibility-adaptor.h>
21 #include <dali/integration-api/adaptor-framework/adaptor.h>
22 #include <dali/integration-api/adaptor-framework/native-render-surface.h>
23 #include <dali/integration-api/adaptor-framework/native-render-surface-factory.h>
24 #include <dali/integration-api/adaptor-framework/trigger-event-factory.h>
25 #include <dali/integration-api/debug.h>
26 #include <dali/public-api/actors/layer.h>
27 #include <dali-toolkit/public-api/accessibility-manager/accessibility-manager.h>
28 #include <dali-toolkit/devel-api/focus-manager/keyinput-focus-manager.h>
29
30 // INTERNAL INCLUDES
31 #include <dali-extension/internal/evas-plugin/evas-event-handler.h>
32 #include <dali-extension/internal/evas-plugin/evas-plugin-impl.h>
33 #include <dali-extension/internal/evas-plugin/evas-wrapper.h>
34
35 // CLASS HEADER
36 #include <dali-extension/internal/evas-plugin/scene-impl.h>
37
38 namespace Dali
39 {
40
41 namespace Extension
42 {
43
44 namespace Internal
45 {
46
47 IntrusivePtr< Scene > Scene::New( Evas_Object* parentEvasObject, uint16_t width, uint16_t height, bool isTranslucent )
48 {
49   IntrusivePtr< Scene > scene = new Scene( parentEvasObject, width, height, isTranslucent );
50   return scene;
51 }
52
53 Scene::Scene( Evas_Object* parentEvasObject, uint16_t width, uint16_t height, bool isTranslucent )
54 : mAdaptor( nullptr ),
55   mEvasWrapper( new EvasWrapper( parentEvasObject, width, height, isTranslucent ) ),
56   mEvasEventHandler(),
57   mRenderNotification(),
58   mIsFocus( false ),
59   mIsTranslucent( isTranslucent )
60 {
61   DALI_ASSERT_ALWAYS( parentEvasObject && "No parent object for the scene" );
62
63   // Create surface
64   mSurface = std::unique_ptr< RenderSurfaceInterface >( CreateNativeSurface( PositionSize( 0, 0, static_cast<int>( width ), static_cast<int>( height ) ), isTranslucent ) );
65 }
66
67 void Scene::Initialize( EvasPlugin* evasPlugin, bool isDefaultScene )
68 {
69   mAdaptor = evasPlugin->GetAdaptor();
70
71   DALI_ASSERT_ALWAYS( mAdaptor && "Scene can not be created when the Adaptor is null" );
72
73   if( isDefaultScene )
74   {
75     Initialize();
76     return;
77   }
78
79   if( evasPlugin->GetState() != EvasPlugin::RUNNING )
80   {
81     evasPlugin->PreInitSignal().Connect( this, &Scene::OnPreInitEvasPlugin );
82
83     return;
84   }
85
86   Dali::Integration::SceneHolder sceneHolderHandler = Dali::Integration::SceneHolder( this );
87   mAdaptor->AddWindow( sceneHolderHandler, "", "", mIsTranslucent );
88
89   Initialize();
90 }
91
92 void Scene::Initialize()
93 {
94   // Connect callback to be notified when the surface is rendered
95   TriggerEventFactory triggerEventFactory;
96
97   mRenderNotification = std::unique_ptr< TriggerEventInterface >( triggerEventFactory.CreateTriggerEvent( MakeCallback( this, &Scene::OnPostRender ), TriggerEventInterface::KEEP_ALIVE_AFTER_TRIGGER ) );
98
99   NativeRenderSurface* surface = GetNativeRenderSurface();
100
101   if( !surface )
102   {
103     return;
104   }
105
106   surface->SetRenderNotification( mRenderNotification.get() );
107
108   if( !mEvasEventHandler )
109   {
110     mEvasEventHandler = std::unique_ptr< EvasEventHandler >( new EvasEventHandler( *this ) );
111   }
112 }
113
114 void Scene::OnPreInitEvasPlugin()
115 {
116   Dali::Integration::SceneHolder sceneHolderHandler = Dali::Integration::SceneHolder( this );
117   mAdaptor->AddWindow( sceneHolderHandler, "", "", mIsTranslucent );
118
119   Initialize();
120 }
121
122 Scene::~Scene()
123 {
124   NativeRenderSurface* surface = GetNativeRenderSurface();
125
126   if( surface )
127   {
128     // To prevent notification triggering in NativeRenderSurface::PostRender while deleting SceneHolder
129     surface->SetRenderNotification( nullptr );
130   }
131 }
132
133 uint32_t Scene::GetLayerCount() const
134 {
135   return mScene.GetLayerCount();
136 }
137
138 Layer Scene::GetLayer( uint32_t depth ) const
139 {
140   return mScene.GetLayer( depth );
141 }
142
143 Scene::SceneSize Scene::GetSize() const
144 {
145   Size size = mScene.GetSize();
146
147   return Scene::SceneSize( static_cast<uint16_t>( size.width ), static_cast<uint16_t>( size.height ) );
148 }
149
150 Dali::Any Scene::GetNativeHandle() const
151 {
152   return mEvasWrapper->GetNativeWindow();
153 }
154
155 NativeRenderSurface* Scene::GetNativeRenderSurface() const
156 {
157   return dynamic_cast< NativeRenderSurface* >( mSurface.get() );
158 }
159
160 Evas_Object* Scene::GetAccessEvasObject()
161 {
162   return mEvasWrapper->GetAccessibilityTarget();
163 }
164
165 Evas_Object* Scene::GetDaliEvasObject()
166 {
167   return mEvasWrapper->GetFocusTarget();
168 }
169
170 void Scene::ResizeSurface( uint16_t width, uint16_t height )
171 {
172   if( !mSurface || !mAdaptor || width <= 1 || height <= 1 )
173   {
174     return;
175   }
176
177   int intWidth = static_cast<int>( width );
178   int intHeight = static_cast<int>( height );
179
180   PositionSize currentSize = mSurface->GetPositionSize();
181   if( currentSize.width == intWidth && currentSize.height == intHeight )
182   {
183     return;
184   }
185
186   mSurface->MoveResize( PositionSize( 0, 0, intWidth, intHeight ) );
187
188   SurfaceResized( true );
189
190   Adaptor::SurfaceSize newSize( width, height );
191
192   // When surface size is updated, inform adaptor of resizing and emit ResizedSignal
193   mAdaptor->SurfaceResizePrepare( mSurface.get(), newSize );
194
195   mResizedSignal.Emit( Extension::Scene( this ), width, height );
196
197   mAdaptor->SurfaceResizeComplete( mSurface.get(), newSize );
198 }
199
200 void Scene::OnPostRender()
201 {
202   // Bind offscreen surface to the evas object
203   NativeRenderSurface* surface = GetNativeRenderSurface();
204
205   if( !surface )
206   {
207     return;
208   }
209
210   tbm_surface_h tbmSurface = AnyCast<tbm_surface_h>( surface->GetDrawable() );
211
212   if( !tbmSurface )
213   {
214     return;
215   }
216
217   mEvasWrapper->BindTBMSurface( tbmSurface );
218
219   mEvasWrapper->RequestRender();
220
221   surface->ReleaseLock();
222 }
223
224 EvasWrapper* Scene::GetEvasWrapper() const
225 {
226   return mEvasWrapper.get();
227 }
228
229 void Scene::OnEvasObjectTouchEvent( Dali::Integration::Point& touchPoint, unsigned long timeStamp )
230 {
231   FeedTouchPoint( touchPoint, timeStamp );
232 }
233
234 void Scene::OnEvasObjectWheelEvent( Dali::Integration::WheelEvent& wheelEvent )
235 {
236   FeedWheelEvent( wheelEvent );
237 }
238
239 void Scene::OnEvasObjectKeyEvent( Dali::Integration::KeyEvent& keyEvent )
240 {
241   FeedKeyEvent( keyEvent );
242 }
243
244 void Scene::OnEvasObjectMove( const Rect<int>& geometry )
245 {
246 }
247
248 void Scene::OnEvasObjectResize( const Rect<int>& geometry )
249 {
250   ResizeSurface( static_cast<uint16_t>( geometry.width ), static_cast<uint16_t>( geometry.height ) );
251 }
252
253 void Scene::OnEvasObjectVisiblityChanged( bool visible )
254 {
255   if( mVisible == visible )
256   {
257     return;
258   }
259   DALI_LOG_RELEASE_INFO( "Scene::OnEvasObjectVisiblityChanged( %s )", visible ? "T" : "F" );
260
261   SetVisibility( visible );
262 }
263
264 void Scene::OnEvasObjectFocusIn()
265 {
266   if( !mIsFocus )
267   {
268     mFocusChangedSignal.Emit( Extension::Scene( this ), true );
269
270     mIsFocus = true;
271   }
272 }
273
274 void Scene::OnEvasObjectFocusOut()
275 {
276   if( mIsFocus )
277   {
278     mIsFocus = false;
279
280     Toolkit::KeyInputFocusManager focusManager = Toolkit::KeyInputFocusManager::Get();
281     Toolkit::Control currentFocused = focusManager.GetCurrentFocusControl();
282     if( currentFocused )
283     {
284       focusManager.RemoveFocus( currentFocused );
285     }
286
287     Clipboard::Get().HideClipboard();
288
289     mFocusChangedSignal.Emit( Extension::Scene( this ), false );
290   }
291 }
292
293 bool Scene::OnElmAccessibilityActionEvent( AccessActionInfo& accessActionInfo )
294 {
295   bool ret = false;
296
297   if( mAdaptor == nullptr )
298   {
299     return ret;
300   }
301
302   Dali::AccessibilityAdaptor accessibilityAdaptor = Dali::AccessibilityAdaptor::Get();
303   if( accessibilityAdaptor )
304   {
305     switch( accessActionInfo.actionBy )
306     {
307       case Dali::Extension::Internal::ACCESS_ACTION_HIGHLIGHT:
308       case Dali::Extension::Internal::ACCESS_ACTION_READ:
309       {
310         ret = accessibilityAdaptor.HandleActionReadEvent( (unsigned int)accessActionInfo.x, (unsigned int)accessActionInfo.y, true );
311       }
312       break;
313
314       case Dali::Extension::Internal::ACCESS_ACTION_HIGHLIGHT_PREV:
315       {
316         // if accessActionInfo.highlight_end is true, need to handle end_of_list sound feedback
317         ret = accessibilityAdaptor.HandleActionPreviousEvent( accessActionInfo.highlightCycle );
318         if(!ret)
319         {
320           // when focus moving was failed, clear the focus
321           accessibilityAdaptor.HandleActionClearFocusEvent();
322         }
323       }
324       break;
325
326       case Dali::Extension::Internal::ACCESS_ACTION_HIGHLIGHT_NEXT:
327       {
328         // if accessActionInfo.highlight_cycle is true, need to handle end_of_list sound feedback
329         ret = accessibilityAdaptor.HandleActionNextEvent( accessActionInfo.highlightCycle );
330         if(!ret)
331         {
332           // when focus moving was failed, clear the focus
333           accessibilityAdaptor.HandleActionClearFocusEvent();
334         }
335       }
336       break;
337
338       case Dali::Extension::Internal::ACCESS_ACTION_ACTIVATE:
339       {
340         ret = accessibilityAdaptor.HandleActionActivateEvent();
341       }
342       break;
343
344       case Dali::Extension::Internal::ACCESS_ACTION_UNHIGHLIGHT:
345       {
346         ret = accessibilityAdaptor.HandleActionClearFocusEvent();
347       }
348       break;
349
350       case Dali::Extension::Internal::ACCESS_ACTION_SCROLL:
351       {
352         Evas_Object* eo = mEvasWrapper->GetAccessibilityTarget();
353
354         if( eo )
355         {
356           int touchType = accessActionInfo.mouseType;
357
358           TouchPoint::State state( TouchPoint::Down );
359
360           if( touchType == 0 )
361           {
362             state = TouchPoint::Down; // mouse down
363           }
364           else if( touchType == 1 )
365           {
366             state = TouchPoint::Motion; // mouse move
367           }
368           else if( touchType == 2 )
369           {
370             state = TouchPoint::Up; // mouse up
371           }
372           else
373           {
374             state = TouchPoint::Interrupted; // error
375           }
376
377           // Send touch event to accessibility manager.
378           Evas_Coord rel_x, rel_y, obj_x,  obj_y, obj_w, obj_h;
379
380           evas_object_geometry_get( eo, &obj_x,  &obj_y, &obj_w, &obj_h );
381
382           rel_x = accessActionInfo.x - obj_x;
383           rel_y = accessActionInfo.y - obj_y;
384
385           TouchPoint point( 0, state, (float)rel_x, (float)rel_y );
386
387           ret = accessibilityAdaptor.HandleActionScrollEvent( point, accessActionInfo.timeStamp );
388         }
389       }
390       break;
391
392       case Dali::Extension::Internal::ACCESS_ACTION_UP:
393       {
394         ret = accessibilityAdaptor.HandleActionUpEvent();
395       }
396       break;
397
398       case Dali::Extension::Internal::ACCESS_ACTION_DOWN:
399       {
400         ret = accessibilityAdaptor.HandleActionDownEvent();
401       }
402       break;
403
404       case Dali::Extension::Internal::ACCESS_ACTION_BACK:
405       default:
406       {
407         DALI_LOG_WARNING( "[%s:%d]\n", __FUNCTION__, __LINE__ );
408       }
409
410       break;
411     }
412   }
413   else
414   {
415     DALI_LOG_WARNING( "[%s:%d]\n", __FUNCTION__, __LINE__ );
416   }
417
418   return ret;
419 }
420
421 void Scene::OnEcoreWl2VisibilityChange( bool visible )
422 {
423   DALI_LOG_RELEASE_INFO( "Scene::OnEcoreWl2VisibilityChange( %s )", visible ? "T" : "F" );
424
425   SetVisibility( visible );
426 }
427
428 void Scene::SetVisibility( bool visible )
429 {
430   if( mVisible == visible )
431   {
432     return;
433   }
434
435   mVisible = visible;
436
437   if( !mAdaptor )
438   {
439     return;
440   }
441
442   if( mVisible )
443   {
444     mAdaptor->OnWindowShown();
445   }
446   else
447   {
448     mAdaptor->OnWindowHidden();
449
450     mSurface->ReleaseLock();
451   }
452
453   mVisibilityChangedSignal.Emit( Extension::Scene( this ), mVisible );
454 }
455
456 } // namespace Internal
457
458 } // namespace Extension
459
460 } // namespace Dali