-
Notifications
You must be signed in to change notification settings - Fork 0
/
DemoWAM.pb
568 lines (438 loc) · 15.3 KB
/
DemoWAM.pb
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
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
;DemoWAM.pb
IncludeFile "PBDirect2D.pb"
EnableExplicit
#ANIM_DOTS_COUNT = 3
Enumeration
#MENU_ID_START_STOP
EndEnumeration
;- _ANIM_DOT
Structure _ANIM_DOT
yPos.IUIAnimationVariable
EndStructure
;- _ANIM
Structure _ANIM
Array dots._ANIM_DOT(#ANIM_DOTS_COUNT - 1)
opacity.IUIAnimationVariable
EndStructure
;- _APP
Structure _APP
win.i
menu.i
oldProc.i
anim._ANIM
;D2D Device independent resources
d2dFactory.ID2D1Factory
dWriteFactory.IDWriteFactory
txtFormat.IDWriteTextFormat
;D2D Device dependent resources
renderTarget.ID2D1HwndRenderTarget
dotBrush.ID2D1SolidColorBrush
rectBrush.ID2D1SolidColorBrush
;WAM
animManager.IUIAnimationManager
animTimer.IUIAnimationTimer;
animTransitionLib.IUIAnimationTransitionLibrary
storyBoard.IUIAnimationStoryboard
EndStructure
Global._APP app
;- ANIM_MANAGER_EVENT_HANDLER
Structure ANIM_MANAGER_EVENT_HANDLER
vt.i
refCount.l
EndStructure
;- ANIM_MANAGER_EVENT_HANDLER_VTABLE
Structure ANIM_MANAGER_EVENT_HANDLER_VTABLE
QueryInterface.i
AddRef.i
Release.i
OnManagerStatusChanged.i
EndStructure
Global.ANIM_MANAGER_EVENT_HANDLER_VTABLE g_ANIM_MANAGER_EVENT_HANDLER_VTABLE
Procedure.i animManagerEvHandler_New()
Protected.ANIM_MANAGER_EVENT_HANDLER *this
*this = AllocateMemory(SizeOf(ANIM_MANAGER_EVENT_HANDLER))
*this\vt = @g_ANIM_MANAGER_EVENT_HANDLER_VTABLE
*this\refCount = 1
ProcedureReturn *this
EndProcedure
Procedure.l animManagerEvHandler_Free(*this.ANIM_MANAGER_EVENT_HANDLER)
Debug #PB_Compiler_Procedure
If *this
FreeMemory(*this)
EndIf
EndProcedure
Procedure.l animManagerEvHandler_QueryInterface(*this.ANIM_MANAGER_EVENT_HANDLER, *iid.IID, *obj.Integer)
If CompareMemory(*iid, ?IID_IUIAnimationManagerEventHandler, SizeOf(IID))
*obj\i = *this
*this\refCount + 1
ProcedureReturn #S_OK
Else
*obj\i = #Null
ProcedureReturn #E_NOINTERFACE
EndIf
EndProcedure
Procedure.l animManagerEvHandler_AddRef(*this.ANIM_MANAGER_EVENT_HANDLER)
*this\refCount = *this\refCount + 1
ProcedureReturn *this\refCount
EndProcedure
Procedure.l animManagerEvHandler_Release(*this.ANIM_MANAGER_EVENT_HANDLER)
Protected.l refCount
*this\refCount = *this\refCount - 1
refCount = *this\refCount
If *this\refCount = 0
animManagerEvHandler_Free(*this)
EndIf
ProcedureReturn refCount
EndProcedure
Procedure.l animManagerEvHandler_OnManagerStatusChanged(*this.ANIM_MANAGER_EVENT_HANDLER, newStatus.l, previousStatus.l)
Protected.l hr
hr = #S_OK
If newStatus = #UI_ANIMATION_MANAGER_BUSY
InvalidateRect_(WindowID(app\win), #Null, #False)
EndIf
ProcedureReturn hr
EndProcedure
g_ANIM_MANAGER_EVENT_HANDLER_VTABLE\QueryInterface = @animManagerEvHandler_QueryInterface()
g_ANIM_MANAGER_EVENT_HANDLER_VTABLE\AddRef = @animManagerEvHandler_AddRef()
g_ANIM_MANAGER_EVENT_HANDLER_VTABLE\Release = @animManagerEvHandler_Release()
g_ANIM_MANAGER_EVENT_HANDLER_VTABLE\OnManagerStatusChanged = @animManagerEvHandler_OnManagerStatusChanged()
;- ANIM_STORYBOARD_EVENT_HANDLER
Structure ANIM_STORYBOARD_EVENT_HANDLER
vt.i
refCount.l
EndStructure
;- ANIM_STORYBOARD_EVENT_HANDLER_VTABLE
Structure ANIM_STORYBOARD_EVENT_HANDLER_VTABLE
QueryInterface.i
AddRef.i
Release.i
OnStoryboardStatusChanged.i
OnStoryboardUpdated.i
EndStructure
Global.ANIM_STORYBOARD_EVENT_HANDLER_VTABLE g_ANIM_STORYBOARD_EVENT_HANDLER_VTABLE
Procedure.i animStoryBoardEvHandler_New()
Protected.ANIM_STORYBOARD_EVENT_HANDLER *this
*this = AllocateMemory(SizeOf(ANIM_STORYBOARD_EVENT_HANDLER))
*this\vt = @g_ANIM_STORYBOARD_EVENT_HANDLER_VTABLE
*this\refCount = 1
ProcedureReturn *this
EndProcedure
Procedure.l animStoryBoardEvHandler_Free(*this.ANIM_STORYBOARD_EVENT_HANDLER)
Debug #PB_Compiler_Procedure
If *this
FreeMemory(*this)
EndIf
EndProcedure
Procedure.l animStoryBoardEvHandler_QueryInterface(*this.ANIM_STORYBOARD_EVENT_HANDLER, *iid.IID, *obj.Integer)
If CompareMemory(*iid, ?IID_IUIAnimationStoryboardEventHandler, SizeOf(IID))
*obj\i = *this
*this\refCount + 1
ProcedureReturn #S_OK
Else
*obj\i = #Null
ProcedureReturn #E_NOINTERFACE
EndIf
EndProcedure
Procedure.l animStoryBoardEvHandler_AddRef(*this.ANIM_STORYBOARD_EVENT_HANDLER)
*this\refCount = *this\refCount + 1
ProcedureReturn *this\refCount
EndProcedure
Procedure.l animStoryBoardEvHandler_Release(*this.ANIM_STORYBOARD_EVENT_HANDLER)
Protected.l refCount
*this\refCount = *this\refCount - 1
refCount = *this\refCount
If *this\refCount = 0
animStoryBoardEvHandler_Free(*this)
EndIf
ProcedureReturn refCount
EndProcedure
Procedure.l animStoryBoardEvHandler_OnStoryboardStatusChanged(*this.ANIM_STORYBOARD_EVENT_HANDLER, storyboard.IUIAnimationStoryboard, newStatus.l, previousStatus.l)
If newStatus = #UI_ANIMATION_STORYBOARD_FINISHED
Debug #PB_Compiler_Procedure + " FINISHED"
EndIf
EndProcedure
Procedure.l animStoryBoardEvHandler_OnStoryboardUpdated(*this.ANIM_STORYBOARD_EVENT_HANDLER, storyboard.IUIAnimationStoryboard)
EndProcedure
g_ANIM_STORYBOARD_EVENT_HANDLER_VTABLE\QueryInterface = @animStoryBoardEvHandler_QueryInterface()
g_ANIM_STORYBOARD_EVENT_HANDLER_VTABLE\AddRef = @animStoryBoardEvHandler_AddRef()
g_ANIM_STORYBOARD_EVENT_HANDLER_VTABLE\Release = @animStoryBoardEvHandler_Release()
g_ANIM_STORYBOARD_EVENT_HANDLER_VTABLE\OnStoryboardStatusChanged = @animStoryBoardEvHandler_OnStoryboardStatusChanged()
g_ANIM_STORYBOARD_EVENT_HANDLER_VTABLE\OnStoryboardUpdated = @animStoryBoardEvHandler_OnStoryboardUpdated()
Procedure app_createDeviceIndependentResources()
Protected.l hr
Protected.D2D1_FACTORY_OPTIONS fOpts
Protected.D2D1_STROKE_STYLE_PROPERTIES props
fOpts\DebugLevel = #D2D1_DEBUG_LEVEL_NONE
hr = D2D1CreateFactory_(#D2D1_FACTORY_TYPE_SINGLE_THREADED, ?IID_ID2D1Factory, @fOpts, @app\d2dFactory)
hr = DWriteCreateFactory_(#DWRITE_FACTORY_TYPE_SHARED, ?IID_IDWriteFactory, @app\dWriteFactory)
If hr = #S_OK
;Text format
hr = app\dWriteFactory\CreateTextFormat("Segoe UI", #Null, #DWRITE_FONT_WEIGHT_REGULAR,
#DWRITE_FONT_STYLE_NORMAL, #DWRITE_FONT_STRETCH_NORMAL, 18.0,
"en-us", @app\txtFormat)
If hr = #S_OK
app\txtFormat\SetTextAlignment(#DWRITE_TEXT_ALIGNMENT_LEADING)
EndIf
EndIf
ProcedureReturn hr
EndProcedure
Procedure app_discardDeviceIndependentResources()
If app\d2dFactory
app\d2dFactory\Release() : app\d2dFactory = 0
EndIf
If app\dWriteFactory
app\dWriteFactory\Release() : app\dWriteFactory = 0
EndIf
If app\txtFormat
app\txtFormat\Release() : app\txtFormat = 0
EndIf
EndProcedure
Procedure app_createDeviceResources()
Protected.l hr
Protected.RECT rc
Protected.i hwnd
Protected.D2D1_SIZE_U sz
Protected.D2D1_RENDER_TARGET_PROPERTIES rtProps
Protected.D2D1_HWND_RENDER_TARGET_PROPERTIES hwndProps
Protected.D2D1_COLOR_F color
Protected.D2D1_BRUSH_PROPERTIES bProp
hr = #S_OK
If app\renderTarget = 0
hwnd = WindowID(app\win)
GetClientRect_(hwnd, @rc)
sz\width = rc\right - rc\left
sz\height = rc\bottom - rc\top
;Create a Direct2D render target.
rtProps\type = #D2D1_RENDER_TARGET_TYPE_DEFAULT
;Enable alpha channel
rtProps\pixelFormat\format = #DXGI_FORMAT_B8G8R8A8_UNORM
rtProps\pixelFormat\alphaMode = #D2D1_ALPHA_MODE_PREMULTIPLIED
rtProps\dpiX = 0.0
rtProps\dpiY = 0.0
rtProps\usage = #D2D1_RENDER_TARGET_USAGE_NONE
rtProps\minLevel = #D2D1_FEATURE_LEVEL_DEFAULT
hwndProps\hwnd = hwnd
hwndProps\pixelSize\height = sz\height
hwndProps\pixelSize\width = sz\width
hwndProps\presentOptions = #D2D1_PRESENT_OPTIONS_NONE
hr = app\d2dFactory\CreateHwndRenderTarget(@rtProps, @hwndProps, @app\renderTarget)
If hr = #S_OK
;Brushes
bProp\opacity = 1.0
color\r = 0 : color\g = 162/255 : color\b = 232/255 : color\a = 1.0
app\renderTarget\CreateSolidColorBrush(@color, @bProp, @app\rectBrush)
color\r = 0.0 : color\g = 1.0 : color\b = 0.0 : color\a = 0.5
app\renderTarget\CreateSolidColorBrush(@color, @bProp, @app\dotBrush)
EndIf
EndIf
ProcedureReturn hr
EndProcedure
Procedure app_discardDeviceResources()
If app\renderTarget
app\renderTarget\Release() : app\renderTarget = 0
EndIf
If app\dotBrush
app\dotBrush\Release() : app\dotBrush = 0
EndIf
If app\rectBrush
app\rectBrush\Release() : app\rectBrush = 0
EndIf
EndProcedure
Procedure app_initWAM()
Protected.l i, hr
Protected.d sinDuration
Protected.IUIAnimationManagerEventHandler animEventHandler
Protected.IUIAnimationTransition transYPos, transOpacity
Protected.IUIAnimationStoryboardEventHandler storyBoardEvHandler
Protected.i keyFrame1, keyFrame2, endKeyFrame
;No error checking
hr = CoCreateInstance_(?CLSID_UIAnimationManager, #Null, #CLSCTX_INPROC_SERVER, ?IID_IUIAnimationManager, @app\animManager)
hr = CoCreateInstance_(?CLSID_UIAnimationTimer, #Null, #CLSCTX_INPROC_SERVER, ?IID_IUIAnimationTimer, @app\animTimer)
hr = CoCreateInstance_(?CLSID_UIAnimationTransitionLibrary, #Null, #CLSCTX_INPROC_SERVER, ?IID_IUIAnimationTransitionLibrary, @app\animTransitionLib)
animEventHandler = animManagerEvHandler_New()
hr = app\animManager\SetManagerEventHandler(animEventHandler)
animEventHandler\Release()
sinDuration = 6
app\animManager\CreateStoryboard(@app\storyBoard)
storyBoardEvHandler = animStoryBoardEvHandler_New()
app\storyBoard\SetStoryboardEventHandler(storyBoardEvHandler)
storyBoardEvHandler\Release()
;Keyframes for dots 1, 2 start time and animation end
app\storyBoard\AddKeyframeAtOffset(#UI_ANIMATION_KEYFRAME_STORYBOARD_START, 0.5, @keyFrame1)
app\storyBoard\AddKeyframeAtOffset(#UI_ANIMATION_KEYFRAME_STORYBOARD_START, 1.0, @keyFrame2)
app\storyBoard\AddKeyframeAtOffset(#UI_ANIMATION_KEYFRAME_STORYBOARD_START, sinDuration + 0.5 + 1.0, @endKeyFrame)
app\storyBoard\RepeatBetweenKeyframes(#UI_ANIMATION_KEYFRAME_STORYBOARD_START, endKeyFrame, #UI_ANIMATION_REPEAT_INDEFINITELY)
app\animManager\CreateAnimationVariable(1.0, @app\anim\opacity)
app\anim\opacity\SetLowerBound(0.0)
app\anim\opacity\SetUpperBound(1.0)
app\animTransitionLib\CreateSinusoidalTransitionFromRange(sinDuration, 0.0, 1.0, 3, #UI_ANIMATION_SLOPE_INCREASING, @transOpacity)
app\storyBoard\AddTransition(app\anim\opacity, transOpacity)
app\anim\opacity\Release()
transOpacity\Release()
For i = 0 To #ANIM_DOTS_COUNT -1
;Create variables
app\animManager\CreateAnimationVariable(0.0, @app\anim\dots(i)\yPos)
app\anim\dots(i)\yPos\SetLowerBound(-40.0)
app\anim\dots(i)\yPos\SetUpperBound(40.0)
;Add transitions to variables
app\animTransitionLib\CreateSinusoidalTransitionFromRange(sinDuration, -40.0, 40.0, 1.5, #UI_ANIMATION_SLOPE_INCREASING, @transYPos)
If i = 1
app\storyBoard\AddTransitionAtKeyframe(app\anim\dots(i)\yPos, transYPos, keyFrame1)
ElseIf i = 2
app\storyBoard\AddTransitionAtKeyframe(app\anim\dots(i)\yPos, transYPos, keyFrame2)
Else
app\storyBoard\AddTransition(app\anim\dots(i)\yPos, transYPos)
EndIf
app\anim\dots(i)\yPos\Release()
transYPos\Release()
Next
EndProcedure
Procedure app_ReleaseWAM()
Protected.l i
If app\animManager : app\animManager\Release() : EndIf
If app\animTimer : app\animTimer\Release() : EndIf
If app\animTransitionLib : app\animTransitionLib\Release() : EndIf
If app\storyBoard : app\storyBoard\Release() : EndIf
EndProcedure
Procedure app_init()
Protected.l hr
InitializeStructure(@app, _APP)
;Direct2D
hr = app_createDeviceIndependentResources()
If hr <> #S_OK
Debug "Failded to initialize Direct2D"
ProcedureReturn hr
EndIf
app_initWAM()
EndProcedure
Procedure app_release()
app_discardDeviceResources()
app_discardDeviceIndependentResources()
app_ReleaseWAM()
EndProcedure
Procedure app_onSize(width.w, height.w)
Protected.D2D1_SIZE_U sz
If app\renderTarget
sz\width = width
sz\height = height
app\renderTarget\Resize(@sz)
EndIf
EndProcedure
Procedure app_render()
Protected.l hr, i, status
Protected.q tag1, tag2
Protected.D2D1_COLOR_F color
Protected.D2D1_ROUNDED_RECT dotsRect
Protected.D2D1_RECT_F rtRect
Protected.D2D1_SIZE_F rtSize
Protected.D2D1_ELLIPSE dot
Protected.f dotRectSize
Protected.s text
Protected.d yPos, opacity
hr = #S_OK
hr = app_createDeviceResources()
If hr = #S_OK
app\renderTarget\BeginDraw()
color\r = 1.0 : color\g = 1.0 : color\b = 1.0 : color\a = 1.0
app\renderTarget\Clear(@color)
app\renderTarget\GetSize(@rtSize)
rtRect\right = rtSize\width
rtRect\bottom = rtSize\height
;Round Rectangle
dotRectSize = 200.0
dotsRect\rect\left = (rtSize\width / 2) - dotRectSize / 2
dotsRect\rect\top = (rtSize\height / 2) - dotRectSize / 2
dotsRect\rect\right = (rtSize\width / 2) + dotRectSize / 2
dotsRect\rect\bottom = dotsRect\rect\top + dotRectSize
dotsRect\radiusX = 20.0
dotsRect\radiusY = 20.0
app\anim\opacity\GetValue(@opacity)
app\rectBrush\SetOpacity(opacity)
app\renderTarget\FillRoundedRectangle(@dotsRect, app\rectBrush)
;Dots
app\storyBoard\GetStatus(@status)
dot\point\x = (rtSize\width / 2) - 40
dot\radiusX = 10.0
dot\radiusY = 10.0
For i = 0 To #ANIM_DOTS_COUNT - 1
app\anim\dots(i)\yPos\GetValue(@yPos)
dot\point\y = (rtSize\height / 2) + yPos
app\renderTarget\FillEllipse(@dot, app\dotBrush)
dot\point\x + 40.0
Next
;Text
text = "Press F1 to Start / Stop"
app\renderTarget\DrawText(text, Len(text), app\txtFormat, @rtRect, app\rectBrush, #D2D1_DRAW_TEXT_OPTIONS_NONE, #DWRITE_MEASURING_MODE_NATURAL)
hr = app\renderTarget\EndDraw(@tag1, @tag2)
EndIf
If (hr = #D2DERR_RECREATE_TARGET)
hr = #S_OK
app_discardDeviceResources()
EndIf
ProcedureReturn hr
EndProcedure
Procedure app_onPaint(hwnd.i)
Protected.l hr, status
Protected.d secondsNow
app\animTimer\GetTime(@secondsNow)
app\animManager\Update(secondsNow, #Null)
hr = app_render()
If hr = #S_OK
app\animManager\GetStatus(@status)
If status = #UI_ANIMATION_MANAGER_BUSY
InvalidateRect_(hwnd, #Null, #False)
EndIf
EndIf
EndProcedure
Procedure.i win_proc(hwnd.i, msg.l, wparam.i, lparam.i)
Select msg
Case #WM_SIZE
app_onSize(PeekW(@lparam), PeekW(@lparam + SizeOf(Word)))
Case #WM_ERASEBKGND
Protected.RECT rc
GetClientRect_(hwnd, @rc)
app_onSize(rc\right, rc\bottom)
app_render()
ProcedureReturn 1
Case #WM_PAINT, #WM_DISPLAYCHANGE
Protected.PAINTSTRUCT ps
BeginPaint_(hwnd, @ps)
app_onPaint(hwnd)
EndPaint_(hwnd, @ps)
ProcedureReturn 0
EndSelect
ProcedureReturn CallWindowProc_(app\oldProc, hwnd, msg, wparam, lparam)
EndProcedure
Procedure main()
Protected.l ev, status
Protected.d secondsNow
If app_init() <> #S_OK
MessageRequester("Error" , "Failed to initialize application")
End
EndIf
app\win = OpenWindow(#PB_Any, 10, 10, 600, 400, "DemoWAM", #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget | #PB_Window_SizeGadget)
app\menu = CreateMenu(#PB_Any, WindowID(app\win))
AddKeyboardShortcut(app\win, #PB_Shortcut_F1, #MENU_ID_START_STOP)
app\oldProc = SetWindowLongPtr_(WindowID(app\win), #GWLP_WNDPROC, @win_proc())
app\animTimer\GetTime(@secondsNow)
app\storyBoard\Schedule(secondsNow, 0)
Repeat
ev = WaitWindowEvent()
Select ev
Case #PB_Event_Menu
Select EventMenu()
Case #MENU_ID_START_STOP
app\storyBoard\GetStatus(@status)
If status = #UI_ANIMATION_STORYBOARD_BUILDING Or status = #UI_ANIMATION_STORYBOARD_READY
app\animTimer\GetTime(@secondsNow)
app\storyBoard\Schedule(secondsNow, #Null)
Else
app\storyBoard\Finish(0)
EndIf
EndSelect
EndSelect
Until ev = #PB_Event_CloseWindow
app\storyBoard\Finish(0)
app_release()
EndProcedure
main()