1
+ using System ;
2
+ using System . Threading ;
3
+ using ElmSharp ;
4
+ using Tizen . Common ;
5
+ using Xamarin . Forms . Platform . Tizen . SkiaSharp ;
6
+ using EGestureType = ElmSharp . GestureLayer . GestureType ;
7
+
8
+ namespace Xamarin . Forms . Platform . Tizen
9
+ {
10
+ public class DragGestureHandler : GestureHandler
11
+ {
12
+ bool _isApi4 ;
13
+
14
+ DragDropExtensions . Interop . DragIconCreateCallback _iconCallback ;
15
+ DragDropExtensions . Interop . DragStateCallback _dragDoneCallback ;
16
+
17
+ static bool s_isDragging ;
18
+ static CustomDragStateData s_currentDragStateData ;
19
+
20
+ public DragGestureHandler ( IGestureRecognizer recognizer , IVisualElementRenderer renderer ) : base ( recognizer )
21
+ {
22
+ _iconCallback = OnIconCallback ;
23
+ _dragDoneCallback = OnDragDoneCallback ;
24
+ _isApi4 = DotnetUtil . TizenAPIVersion <= 4 ;
25
+ Renderer = renderer ;
26
+ }
27
+
28
+ public override EGestureType Type => EGestureType . LongTap ;
29
+
30
+ public IVisualElementRenderer Renderer { get ; }
31
+
32
+ public static CustomDragStateData CurrentStateData
33
+ {
34
+ get
35
+ {
36
+ return s_currentDragStateData ;
37
+ }
38
+ }
39
+
40
+ EvasObject NativeView
41
+ {
42
+ get
43
+ {
44
+ var native = Renderer . NativeView ;
45
+ if ( Renderer is SkiaSharp . ICanvasRenderer canvasRenderer )
46
+ {
47
+ native = canvasRenderer . RealNativeView ;
48
+ }
49
+ return native ;
50
+ }
51
+ }
52
+
53
+ public void ResetCurrentStateData ( )
54
+ {
55
+ s_currentDragStateData = null ;
56
+ }
57
+
58
+ protected override void OnStarted ( View sender , object data )
59
+ {
60
+ }
61
+
62
+ protected override void OnMoved ( View sender , object data )
63
+ {
64
+ //Workaround to prevent an error occuring by multiple StartDrag calling in Tizen 6.5
65
+ if ( ! s_isDragging )
66
+ {
67
+ ResetCurrentStateData ( ) ;
68
+ StartDrag ( ) ;
69
+ }
70
+ }
71
+
72
+ protected override void OnCompleted ( View sender , object data )
73
+ {
74
+ }
75
+
76
+ protected override void OnCanceled ( View sender , object data )
77
+ {
78
+ }
79
+
80
+ void StartDrag ( )
81
+ {
82
+ if ( Recognizer is DragGestureRecognizer dragGestureRecognizer && dragGestureRecognizer . CanDrag )
83
+ {
84
+ if ( Renderer == null )
85
+ return ;
86
+
87
+ var arg = dragGestureRecognizer . SendDragStarting ( Renderer . Element ) ;
88
+
89
+ if ( arg . Cancel )
90
+ return ;
91
+
92
+ s_currentDragStateData = new CustomDragStateData ( ) ;
93
+ s_currentDragStateData . DataPackage = arg . Data ;
94
+
95
+ var target = DragDropExtensions . DragDropContentType . Text ;
96
+ var strData = string . IsNullOrEmpty ( arg . Data . Text ) ? " " : arg . Data . Text ;
97
+
98
+ s_isDragging = true ;
99
+
100
+ DragDropExtensions . StartDrag ( NativeView ,
101
+ target ,
102
+ strData ,
103
+ DragDropExtensions . DragDropActionType . Move ,
104
+ _iconCallback ,
105
+ null ,
106
+ null ,
107
+ _dragDoneCallback ) ;
108
+ }
109
+ }
110
+
111
+ IntPtr OnIconCallback ( IntPtr data , IntPtr window , ref int xoff , ref int yoff )
112
+ {
113
+ EvasObject icon = null ;
114
+ EvasObject parent = new CustomWindow ( NativeView , window ) ;
115
+
116
+ if ( s_currentDragStateData . DataPackage . Image != null )
117
+ {
118
+ icon = GetImageIcon ( parent ) ;
119
+ }
120
+ else if ( NativeView is ShapeView )
121
+ {
122
+ icon = GetShapeView ( parent ) ;
123
+ }
124
+ else
125
+ {
126
+ icon = GetDefaultIcon ( parent ) ;
127
+ }
128
+ var bound = NativeView . Geometry ;
129
+ bound . X = 0 ;
130
+ bound . Y = 0 ;
131
+ icon . Geometry = bound ;
132
+
133
+ if ( icon is Native . Label )
134
+ {
135
+ icon . Resized += ( s , e ) =>
136
+ {
137
+ var map = new EvasMap ( 4 ) ;
138
+ map . PopulatePoints ( icon . Geometry , 0 ) ;
139
+ map . Zoom ( 0.5 , 0.5 , 0 , 0 ) ;
140
+ icon . IsMapEnabled = true ;
141
+ icon . EvasMap = map ;
142
+ } ;
143
+ }
144
+ else
145
+ {
146
+ var map = new EvasMap ( 4 ) ;
147
+ map . PopulatePoints ( icon . Geometry , 0 ) ;
148
+ map . Zoom ( 0.5 , 0.5 , 0 , 0 ) ;
149
+ icon . IsMapEnabled = true ;
150
+ icon . EvasMap = map ;
151
+ }
152
+
153
+
154
+ return icon ;
155
+ }
156
+
157
+ EvasObject GetDefaultIcon ( EvasObject parent )
158
+ {
159
+ if ( ! string . IsNullOrEmpty ( s_currentDragStateData . DataPackage . Text ) )
160
+ {
161
+ var label = new Native . Label ( parent ) ;
162
+ label . Text = s_currentDragStateData . DataPackage . Text ;
163
+
164
+ if ( Renderer . Element is Label lb )
165
+ label . FontSize = lb . FontSize ;
166
+ else if ( Renderer . Element is Entry et )
167
+ label . FontSize = et . FontSize ;
168
+ else if ( Renderer . Element is Editor ed )
169
+ label . FontSize = ed . FontSize ;
170
+
171
+ return label ;
172
+ }
173
+ else
174
+ {
175
+ var box = new ElmSharp . Rectangle ( parent ) ;
176
+ box . Color = new ElmSharp . Color ( 128 , 128 , 128 , 128 ) ;
177
+ return box ;
178
+ }
179
+ }
180
+
181
+ EvasObject GetImageIcon ( EvasObject parent )
182
+ {
183
+ var image = new Native . Image ( parent ) ;
184
+ _ = image . LoadFromImageSourceAsync ( s_currentDragStateData . DataPackage . Image ) ;
185
+ return image ;
186
+ }
187
+
188
+ EvasObject GetShapeView ( EvasObject parent )
189
+ {
190
+ var copiedImg = new EvasImage ( parent ) ;
191
+ copiedImg . IsFilled = true ;
192
+
193
+ if ( NativeView is ShapeView shapeView )
194
+ {
195
+ var canvas = shapeView . SKCanvasView ;
196
+ var realHandle = DragDropExtensions . Interop . elm_object_part_content_get ( canvas , "elm.swallow.content" ) ;
197
+
198
+ DragDropExtensions . Interop . evas_object_image_size_get ( realHandle , out int w , out int h ) ;
199
+ DragDropExtensions . Interop . evas_object_image_size_set ( copiedImg , w , h ) ;
200
+
201
+ var imgData = DragDropExtensions . Interop . evas_object_image_data_get ( realHandle , false ) ;
202
+ DragDropExtensions . Interop . evas_object_image_data_set ( copiedImg , imgData ) ;
203
+ }
204
+
205
+ return copiedImg ;
206
+ }
207
+
208
+ void OnDragDoneCallback ( IntPtr data , IntPtr obj )
209
+ {
210
+ s_isDragging = false ;
211
+ if ( Recognizer is DragGestureRecognizer dragGestureRecognizer && dragGestureRecognizer . CanDrag )
212
+ {
213
+ dragGestureRecognizer . SendDropCompleted ( new DropCompletedEventArgs ( ) ) ;
214
+ }
215
+ }
216
+
217
+ public class CustomWindow : EvasObject
218
+ {
219
+ IntPtr _handle ;
220
+
221
+ public CustomWindow ( EvasObject parent , IntPtr handle ) : base ( )
222
+ {
223
+ _handle = handle ;
224
+ Realize ( parent ) ;
225
+ }
226
+
227
+ public CustomWindow ( EvasObject handle ) : base ( handle )
228
+ {
229
+ }
230
+
231
+ protected override IntPtr CreateHandle ( EvasObject parent )
232
+ {
233
+ return _handle ;
234
+ }
235
+ }
236
+
237
+ public class CustomDragStateData
238
+ {
239
+ public DataPackage DataPackage { get ; set ; }
240
+ public DataPackageOperation AcceptedOperation { get ; set ; } = DataPackageOperation . Copy ;
241
+ }
242
+ }
243
+ }
0 commit comments