-
Notifications
You must be signed in to change notification settings - Fork 0
/
B4XDrawer.bas
374 lines (341 loc) · 11.4 KB
/
B4XDrawer.bas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
B4A=true
Group=Default Group
ModulesStructureVersion=1
Type=Class
Version=8.5
@EndOfDesignText@
'version 1.52*
Sub Class_Globals
Private mEventName As String 'ignore
Private mCallBack As Object 'ignore
Private xui As XUI 'ignore
Private mSideWidth As Int
Private mLeftPanel As B4XView
Private mRightPanel As B4XView
Private mDarkPanel As B4XView
Private mBasePanel As B4XView
Private mCenterPanel As B4XView
Private ExtraWidth As Int = 50dip
Private TouchXStart, TouchYStart As Float 'ignore
Private IsOpenLeft As Boolean
Private IsOpenRight As Boolean
Private HandlingLSwipe As Boolean
Private HandlingRSwipe As Boolean
Private StartAtScrim As Boolean 'ignore
Private mEnabled As Boolean = True
Private mRightPanelEnabled As Boolean = False
End Sub
Public Sub Initialize (Callback As Object, EventName As String, Parent As B4XView, SideWidth As Int)
mEventName = EventName
mCallBack = Callback
mSideWidth = SideWidth
#if B4A
Dim creator As TouchPanelCreator
mBasePanel = creator.CreateTouchPanel("base")
#else if B4i
mBasePanel = xui.CreatePanel("")
Dim nme As NativeObject = Me
Dim no As NativeObject = mBasePanel
no.RunMethod("addGestureRecognizer:", Array(nme.RunMethod("CreateRecognizer", Null)))
#End If
Parent.AddView(mBasePanel, 0, 0, Parent.Width, Parent.Height)
mCenterPanel = xui.CreatePanel("")
mBasePanel.AddView(mCenterPanel, 0, 0, mBasePanel.Width, mBasePanel.Height)
mDarkPanel = xui.CreatePanel("dark")
mBasePanel.AddView(mDarkPanel, 0, 0, mBasePanel.Width, mBasePanel.Height)
mLeftPanel = xui.CreatePanel("LeftPanel")
mBasePanel.AddView(mLeftPanel, -SideWidth, 0, SideWidth, mBasePanel.Height)
mLeftPanel.Color = xui.Color_Red
mRightPanel = xui.CreatePanel("RightPanel")
mBasePanel.AddView(mRightPanel, mBasePanel.Width, 0, SideWidth, mBasePanel.Height)
mRightPanel.Color = xui.Color_Red
#if B4A
Dim pL As Panel = mLeftPanel
pL.Elevation = 4dip
Dim pR As Panel = mRightPanel
pR.Elevation = 4dip
#Else If B4i
Dim p As Panel = mDarkPanel
p.UserInteractionEnabled = False
p.SetBorder(0, 0, 0)
p = mLeftPanel
p = mCenterPanel
p.SetBorder(0, 0, 0)
p = mBasePanel
p.SetBorder(0, 0, 0)
#End If
End Sub
Private Sub LeftPanel_Click
End Sub
#if B4A
Private Sub Base_OnTouchEvent (Action As Int, X As Float, Y As Float, MotionEvent As Object) As Boolean
If mEnabled = False Then Return False
Dim LeftPanelRightSide As Int = mLeftPanel.Left + mLeftPanel.Width
Dim RightPanelLeftSide As Int = mRightPanel.Left
If HandlingLSwipe = False And HandlingRSwipe = False Then
If LeftPanelRightSide < x And x < RightPanelLeftSide Then
If IsOpenLeft Then
TouchXStart = X
If Action = mBasePanel.TOUCH_ACTION_UP Then setLeftOpen(False)
Return True
End If
If IsOpenRight Then
TouchXStart = X
If Action = mBasePanel.TOUCH_ACTION_UP Then setRightOpen(False)
Return True
End If
If IsOpenLeft = False And x > LeftPanelRightSide + ExtraWidth And IsOpenRight = False And x < RightPanelLeftSide - ExtraWidth Then
Return False
End If
End If
End If
Select Action
Case mBasePanel.TOUCH_ACTION_MOVE
Dim dx As Float = x - TouchXStart
TouchXStart = X
If HandlingLSwipe Or ( x <= ExtraWidth And Abs(dx) > 3dip And Not(IsOpenRight) ) Then
HandlingLSwipe = True
LeftChangeOffset(mLeftPanel.Left + dx, True, False)
End If
If HandlingRSwipe Or ( x >= mBasePanel.Width - ExtraWidth And Abs(dx) > 3dip And Not(IsOpenLeft) ) Then
HandlingRSwipe = True
RightChangeOffset(mRightPanel.Left + dx, True, False)
End If
Case mBasePanel.TOUCH_ACTION_UP
If HandlingLSwipe Then
LeftChangeOffset(mLeftPanel.Left, False, False)
End If
If HandlingRSwipe Then
RightChangeOffset(mRightPanel.Left, False, False)
End If
HandlingLSwipe = False
HandlingRSwipe = False
End Select
Return True
End Sub
'Return True to "steal" the event from the child views
Private Sub Base_OnInterceptTouchEvent (Action As Int, X As Float, Y As Float, MotionEvent As Object) As Boolean
If mEnabled = False Then Return False
If IsOpenLeft = False And IsOpenRight = False And mLeftPanel.Left + mLeftPanel.Width + ExtraWidth < x And x < mRightPanel.Left - ExtraWidth Then
HandlingLSwipe = False
HandlingRSwipe = False
Return False
End If
If IsOpenLeft And x > mLeftPanel.Left + mLeftPanel.Width Then
'handle all touch events right of the opened side menu
Return True
End If
If IsOpenRight And x < mRightPanel.Left Then
'handle all touch events left of the opened side menu
Return True
End If
If HandlingLSwipe Or HandlingRSwipe Then Return True
Select Action
Case mBasePanel.TOUCH_ACTION_DOWN
TouchXStart = X
TouchYStart = Y
HandlingLSwipe = False
HandlingRSwipe = False
Case mBasePanel.TOUCH_ACTION_MOVE
Dim dx As Float = Abs(x - TouchXStart)
Dim dy As Float = Abs(y - TouchYStart)
If dy < 20dip And dx > 10dip Then
If (( x <= ExtraWidth And IsOpenRight = False ) Or IsOpenLeft ) Then
HandlingLSwipe = True
End If
If (( x >= mBasePanel.Width - ExtraWidth And IsOpenLeft = False ) Or IsOpenRight ) Then
HandlingRSwipe = True
End If
End If
End Select
Return HandlingLSwipe Or HandlingRSwipe
End Sub
#End If
#if B4i
Private Sub Pan_Event (pan As Object)
Dim rec As NativeObject = pan
Dim points() As Float = rec.ArrayFromPoint(rec.RunMethod("locationInView:", Array(mBasePanel)))
Dim x As Float = points(0)
Dim state As Int = rec.GetField("state").AsNumber
Dim LeftPanelRightSide As Int = mLeftPanel.Left + mLeftPanel.Width
Select state
Case 1 'began
If mEnabled = False Then
CancelGesture(rec)
Return
End If
If x > LeftPanelRightSide Then
If IsOpenLeft = False And x > LeftPanelRightSide + ExtraWidth Then
CancelGesture(rec)
HandlingSwipe = False
Return
End If
End If
StartAtScrim = x > LeftPanelRightSide
HandlingSwipe = True
TouchXStart = x
Case 2 'changed
If mLeftPanel.Left < 0 Or x <= LeftPanelRightSide Then
Dim dx As Float = x - TouchXStart
ChangeOffset(mLeftPanel.Left + dx, True, False)
StartAtScrim = False
End If
TouchXStart = X
Case 3
HandlingSwipe = False
If IsOpenLeft And StartAtScrim And x > LeftPanelRightSide Then
setLeftOpen(False)
Else
ChangeOffset(mLeftPanel.Left, False, False)
End If
End Select
End Sub
Private Sub CancelGesture (rec As NativeObject)
rec.SetField("enabled", False)
rec.SetField("enabled", True)
End Sub
Private Sub Dark_Touch(Action As Int, X As Float, Y As Float)
If HandlingSwipe = False And Action = mDarkPanel.TOUCH_ACTION_UP Then
setLeftOpen(False)
End If
End Sub
#end if
Private Sub LeftChangeOffset (x As Float, CurrentlyTouching As Boolean, NoAnimation As Boolean)
x = Max(-mSideWidth, Min(0, x))
Dim VisibleOffset As Int = mSideWidth + x
#if B4i
Dim p As Panel = getLeftPanel
If mLeftPanel.Left = -mSideWidth And x > -mSideWidth Then
p.SetShadow(xui.Color_Black, 2, 0, 0.5, True)
Else If x = -mSideWidth Then
p.SetShadow(0, 0, 0, 0, True)
End If
#End If
If CurrentlyTouching = False Then
If (IsOpenLeft And VisibleOffset < 0.8 * mSideWidth) Or (IsOpenLeft = False And VisibleOffset < 0.2 * mSideWidth) Then
x = -mSideWidth
IsOpenLeft = False
Else
x = 0
IsOpenLeft = True
End If
VisibleOffset = mSideWidth + x
Dim dx As Int = Abs(mLeftPanel.Left - x)
Dim duration As Int = Max(0, 200 * dx / mSideWidth)
If NoAnimation Then duration = 0
mLeftPanel.SetLayoutAnimated(duration, x, 0, mLeftPanel.Width, mLeftPanel.Height)
mDarkPanel.SetColorAnimated(duration, mDarkPanel.Color, OffsetToColor(VisibleOffset))
#if B4i
Dim p As Panel = mDarkPanel
p.UserInteractionEnabled = IsOpenLeft
p = getLeftPanel
#End If
Else
mDarkPanel.Color = OffsetToColor(VisibleOffset)
mLeftPanel.Left = x
End If
End Sub
Private Sub RightChangeOffset (x As Float, CurrentlyTouching As Boolean, NoAnimation As Boolean)
If mRightPanelEnabled Then
x = Max(mBasePanel.Width-mSideWidth, Min(mBasePanel.Width, x))
Dim VisibleOffset As Int = mBasePanel.Width - x
#if B4i
Dim p As Panel = getRightPanel
If mRightPanel.Right = -mSideWidth And x > -mSideWidth Then
p.SetShadow(xui.Color_Black, 2, 0, 0.5, True)
Else If x = -mSideWidth Then
p.SetShadow(0, 0, 0, 0, True)
End If
#End If
If CurrentlyTouching = False Then
If (IsOpenRight And VisibleOffset < 0.8 * mSideWidth) Or (IsOpenRight = False And VisibleOffset < 0.2 * mSideWidth) Then
x = mBasePanel.Width
IsOpenRight = False
Else
x = mBasePanel.Width-mSideWidth
IsOpenRight = True
End If
VisibleOffset = mBasePanel.Width - x
Dim dx As Int = Abs(mRightPanel.Left - x)
Dim duration As Int = Max(0, 200 * dx / mSideWidth)
If NoAnimation Then duration = 0
mRightPanel.SetLayoutAnimated(duration, x, 0, mRightPanel.Width, mRightPanel.Height)
mDarkPanel.SetColorAnimated(duration, mDarkPanel.Color, OffsetToColor(VisibleOffset))
#if B4i
Dim p As Panel = mDarkPanel
p.UserInteractionEnabled = IsOpenRight
p = getRightPanel
#End If
Else
mDarkPanel.Color = OffsetToColor(VisibleOffset)
mRightPanel.Left = x
End If
End If
End Sub
Private Sub OffsetToColor (x As Int) As Int
Dim Visible As Float = x / mSideWidth
Return xui.Color_ARGB(100 * Visible, 0, 0, 0)
End Sub
Public Sub getLeftOpen As Boolean
Return IsOpenLeft
End Sub
Public Sub setLeftOpen (b As Boolean)
If b = IsOpenLeft Then Return
If b Then setRightOpen(False)
Dim x As Float
If b Then x = 0 Else x = -mSideWidth
LeftChangeOffset(x, False, False)
End Sub
Public Sub getLeftPanel As B4XView
Return mLeftPanel
End Sub
Public Sub getRightOpen As Boolean
Return IsOpenRight
End Sub
Public Sub setRightOpen (b As Boolean)
If mRightPanelEnabled Then
If b = IsOpenRight Then Return
If b Then setLeftOpen(False)
Dim x As Float
If b Then x = mBasePanel.Width-mSideWidth Else x = mBasePanel.Width
RightChangeOffset(x, False, False)
End If
End Sub
Public Sub getRightPanel As B4XView
Return mRightPanel
End Sub
Public Sub getCenterPanel As B4XView
Return mCenterPanel
End Sub
Public Sub Resize(Width As Int, Height As Int)
If IsOpenLeft Then LeftChangeOffset(-mSideWidth, False, True)
If IsOpenRight Then RightChangeOffset(Width, False, True)
mBasePanel.SetLayoutAnimated(0, 0, 0, Width, Height)
mLeftPanel.SetLayoutAnimated(0, mLeftPanel.Left, 0, mLeftPanel.Width, mBasePanel.Height)
mRightPanel.SetLayoutAnimated(0, mRightPanel.Left, 0, mRightPanel.Width, mBasePanel.Height)
mDarkPanel.SetLayoutAnimated(0, 0, 0, Width, Height)
mCenterPanel.SetLayoutAnimated(0, 0, 0, Width, Height)
End Sub
Public Sub getGestureEnabled As Boolean
Return mEnabled
End Sub
Public Sub setGestureEnabled (b As Boolean)
mEnabled = b
End Sub
Public Sub getRightPanelEnabled As Boolean
Return mRightPanelEnabled
End Sub
Public Sub setRightPanelEnabled(b As Boolean)
mRightPanelEnabled = b
End Sub
#if OBJC
- (NSObject*) CreateRecognizer{
UIPanGestureRecognizer *rec = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(action:)];
[rec setMinimumNumberOfTouches:1];
[rec setMaximumNumberOfTouches:1];
return rec;
}
-(void) action:(UIPanGestureRecognizer*)rec {
[self.bi raiseEvent:nil event:@"pan_event:" params:@[rec]];
}
#End If