1
1
Fork 0
mirror of https://github.com/FellippeHeitor/InForm.git synced 2024-05-12 06:50:12 +00:00

Cleanup GIFPlay API and update documentation

This commit is contained in:
Samuel Gomes 2023-11-20 08:48:12 +05:30
parent e576210b9e
commit b5bb8a6f5c
6 changed files with 151 additions and 113 deletions

76
InForm/docs/GIFPlay.md Normal file
View file

@ -0,0 +1,76 @@
# Animated GIF Decoder
`By Zom-B` ([QB64-PE Wiki](https://qb64phoenix.com/qb64wiki/index.php/GIF_Images))
`Adapted for use with InForm's PictureBox controls by @FellippeHeitor`
`Refactored and enhanced by a740g to use include guards, conditional compiles and cleaner API`
## Usage instructions
Your form must contain a PictureBox control that'll serve as a container for
the GIF file you'll load with this library.
In the *External modules* section of the .bas file generated by InForm,
`$INCLUDE` both `GIFPlay.bi` and `GIFPlay.bas`. The first must come before the
line that includes `InForm.ui` and the second must come after that, as in
the sample below:
```vb
': External modules: --------------------------------
'$INCLUDE:'InForm\extensions\GIFPlay.bi'
'$INCLUDE:'InForm\InForm.ui'
'$INCLUDE:'InForm\xp.uitheme'
'$INCLUDE:'gifplaySample.frm'
'$INCLUDE:'InForm\extensions\GIFPlay.bm'
```
## API
```vb
FUNCTION GIF_Open%% (ID AS LONG, fileName AS STRING)
```
GIF_Open is a function that takes a PictureBox control ID and a GIF file name and returns True if loading the animation is successful.
```vb
FUNCTION GIF_GetTotalFrames~& (ID AS LONG)
```
GIF_GetTotalFrames returns the total number of frames in a loaded gif. If not an animated GIF, returns 1.
```vb
SUB GIF_Update(ID AS LONG)
```
GIF_Update must be called from within the __UI_BeforeUpdateDisplay event. That's where the frames will be updated in your PictureBox control.
```vb
FUNCTION GIF_IsPlaying%% (ID AS LONG)
```
Returns True is the PictureBox control contains a GIF that's currently being played.
```vb
SUB GIF_Play(ID AS LONG), SUB GIF_Pause(ID AS LONG), SUB GIF_Stop(ID AS LONGD)
```
Starts, pauses or stops playback of a GIF file loaded into the specified PictureBox control.
```vb
SUB GIF_Close(ID AS LONG)
```
Closes the GIF file loaded in the specified PictureBox control and frees the memory used by the frame data buffer attached to it.
```vb
FUNCTION GIF_GetGeight~% (ID AS LONG)
```
Returns the height of the GIF in pixes.
```vb
FUNCTION GIF_GetWidth~% (ID AS LONG)
```
Returns the width of the GIF in pixels.

View file

@ -1,51 +0,0 @@
Animated GIF decoder v1.0
By Zom-B
http://www.qb64.org/wiki/GIF_Images
Adapted for use with InForm's PictureBox controls by @FellippeHeitor
* Usage instructions:
Your form must contain a PictureBox control that'll serve as a container for
the GIF file you'll load with this library.
In the "External modules" section of the .bas file generated by InForm,
$INCLUDE both GIFPlay.bi and GIFPlay.bas. The first must come before the
line that includes InForm.ui and the second must come after that, as in
the sample below:
': External modules: --------------------------------
'$INCLUDE:'InForm\extensions\GIFPlay.bi'
'$INCLUDE:'InForm\InForm.ui'
'$INCLUDE:'InForm\xp.uitheme'
'$INCLUDE:'gifplaySample.frm'
'$INCLUDE:'InForm\extensions\GIFPlay.bm'
* Methods:
- FUNCTION OpenGif(ID, file$)
OpenGif is a function that takes a PictureBox control ID and a GIF
file name and returns True if loading the animation is successful.
- FUNCTION TotalFrames(ID AS LONG)
TotalFrames returns the total number of frames in a loaded gif.
If not an animated GIF, returns 1.
- SUB UpdateGif(ID)
UpdateGif must be called from within the __UI_BeforeUpdateDisplay event.
That's where the frames will be updated in your PictureBox control.
- FUNCTION IsPlaying(ID)
Returns True is the PictureBox control contains a GIF that's currently
being played.
- SUB PlayGif(ID), SUB PauseGif(ID), SUB StopGif(ID)
Starts, pauses or stops playback of a GIF file loaded into the specified
PictureBox control.
- SUB CloseGif(ID)
Closes the GIF file loaded in the specified PictureBox control and frees
the memory used by the frame data buffer attached to it.

View file

@ -4,27 +4,29 @@
'# #
'# https://qb64phoenix.com/qb64wiki/index.php/GIF_Images #
'#######################################################################################
'
' Adapted for use with InForm's PictureBox controls by @FellippeHeitor
' Refactored by a740g to use include guards and conditional compiles
'
' Refactored and enhanced by a740g to use include guards, conditional compiles and cleaner API
$IF GIFPLAY_BAS = UNDEFINED THEN
$LET GIFPLAY_BAS = TRUE
'$INCLUDE:'GIFPlay.bi'
SUB UpdateGif (ID AS LONG)
SUB GIF_Update (ID AS LONG)
SHARED __GIFData() AS __GIFDataType
STATIC GifOverlay AS LONG
DIM i AS LONG, newFrame AS LONG
i = GetGifIndex(ID)
i = __GIF_GetIndex(ID)
IF i = 0 THEN EXIT SUB
IF GifOverlay = 0 THEN
GifOverlay = LoadGIFOverlayImage
GifOverlay = __GIF_LoadOverlayImage
END IF
IF __GIFData(i).IsPlaying OR __GIFData(i).LastFrameServed = 0 THEN
@ -41,7 +43,7 @@ $IF GIFPLAY_BAS = UNDEFINED THEN
BeginDraw ID
$END IF
newFrame = GetGifFrame&(i)
newFrame = __GIF_GetFrame(i)
IF newFrame THEN _PUTIMAGE , newFrame
IF __GIFData(i).IsPlaying = FALSE AND __GIFData(i).HideOverlay = FALSE AND __GIFData(i).totalFrames > 1 THEN
_PUTIMAGE (_WIDTH / 2 - _WIDTH(GifOverlay) / 2, _HEIGHT / 2 - _HEIGHT(GifOverlay) / 2), GifOverlay
@ -53,79 +55,79 @@ $IF GIFPLAY_BAS = UNDEFINED THEN
END SUB
FUNCTION GifIsPlaying%% (ID AS LONG)
FUNCTION GIF_IsPlaying%% (ID AS LONG)
SHARED __GIFData() AS __GIFDataType
DIM i AS LONG: i = GetGifIndex(ID)
DIM i AS LONG: i = __GIF_GetIndex(ID)
GifIsPlaying = __GIFData(i).IsPlaying
GIF_IsPlaying = __GIFData(i).IsPlaying
END FUNCTION
FUNCTION GifWidth% (ID AS LONG)
FUNCTION GIF_GetWidth~% (ID AS LONG)
SHARED __GIFData() AS __GIFDataType
DIM i AS LONG: i = GetGifIndex(ID)
DIM i AS LONG: i = __GIF_GetIndex(ID)
GifWidth = __GIFData(i).width
GIF_GetWidth = __GIFData(i).width
END FUNCTION
FUNCTION GifHeight% (ID AS LONG)
FUNCTION GIF_GetHeight~% (ID AS LONG)
SHARED __GIFData() AS __GIFDataType
DIM i AS LONG: i = GetGifIndex(ID)
DIM i AS LONG: i = __GIF_GetIndex(ID)
GifHeight = __GIFData(i).height
GIF_GetHeight = __GIFData(i).height
END FUNCTION
FUNCTION TotalFrames& (ID AS LONG)
FUNCTION GIF_GetTotalFrames~& (ID AS LONG)
SHARED __GIFData() AS __GIFDataType
DIM i AS LONG: i = GetGifIndex(ID)
TotalFrames = __GIFData(i).totalFrames
DIM i AS LONG: i = __GIF_GetIndex(ID)
GIF_GetTotalFrames = __GIFData(i).totalFrames
END FUNCTION
SUB HideGifOverlay (ID AS LONG)
SUB GIF_HideOverlay (ID AS LONG)
SHARED __GIFData() AS __GIFDataType
DIM i AS LONG: i = GetGifIndex(ID)
DIM i AS LONG: i = __GIF_GetIndex(ID)
__GIFData(i).HideOverlay = TRUE
END SUB
SUB PlayGif (ID AS LONG)
SUB GIF_Play (ID AS LONG)
SHARED __GIFData() AS __GIFDataType
DIM i AS LONG: i = GetGifIndex(ID)
DIM i AS LONG: i = __GIF_GetIndex(ID)
__GIFData(i).IsPlaying = TRUE
END SUB
SUB PauseGif (ID AS LONG)
SUB GIF_Pause (ID AS LONG)
SHARED __GIFData() AS __GIFDataType
DIM i AS LONG: i = GetGifIndex(ID)
DIM i AS LONG: i = __GIF_GetIndex(ID)
__GIFData(i).IsPlaying = FALSE
END SUB
SUB StopGif (ID AS LONG)
SUB GIF_Stop (ID AS LONG)
SHARED __GIFData() AS __GIFDataType
DIM i AS LONG: i = GetGifIndex(ID)
DIM i AS LONG: i = __GIF_GetIndex(ID)
__GIFData(i).IsPlaying = FALSE
__GIFData(i).Frame = 1
END SUB
FUNCTION OpenGif%% (ID AS LONG, filename$)
FUNCTION GIF_Open%% (ID AS LONG, filename$)
SHARED __GIFData() AS __GIFDataType
SHARED __GIFFrameData() AS __GIFFrameDataType
SHARED __TotalGIFLoaded AS LONG, __TotalGIFFrames AS LONG
@ -137,14 +139,14 @@ $IF GIFPLAY_BAS = UNDEFINED THEN
IF Control(ID).Type <> __UI_Type_PictureBox THEN ERROR 5: EXIT FUNCTION
$END IF
Index = GetGifIndex&(ID)
Index = __GIF_GetIndex(ID)
IF Index = 0 THEN
__TotalGIFLoaded = __TotalGIFLoaded + 1
Index = __TotalGIFLoaded
REDIM _PRESERVE __GIFData(1 TO __TotalGIFLoaded) AS __GIFDataType
ELSE
CloseGif ID
GIF_Close ID
END IF
__GIFData(Index).ID = ID
@ -215,14 +217,14 @@ $IF GIFPLAY_BAS = UNDEFINED THEN
'Unsupported disposalMethod
GOTO LoadError
END IF
SkipGIFBlocks __GIFData(Index).file
__GIF_SkipBlocks __GIFData(Index).file
CASE &H3B ' Trailer
EXIT DO
CASE &H21 ' Extension Introducer
GET __GIFData(Index).file, , byte~%% ' Extension Label
SELECT CASE byte~%%
CASE &HFF, &HFE ' Application Extension, Comment Extension
SkipGIFBlocks __GIFData(Index).file
__GIF_SkipBlocks __GIFData(Index).file
CASE &HF9
IF __TotalGIFFrames > UBOUND(__GIFFrameData) THEN
REDIM _PRESERVE __GIFFrameData(0 TO __TotalGIFFrames * 2) AS __GIFFrameDataType
@ -237,7 +239,7 @@ $IF GIFPLAY_BAS = UNDEFINED THEN
GET __GIFData(Index).file, , delay~%
IF delay~% = 0 THEN __GIFFrameData(__TotalGIFFrames).delay = 0.1 ELSE __GIFFrameData(__TotalGIFFrames).delay = delay~% / 100
GET __GIFData(Index).file, , __GIFFrameData(__TotalGIFFrames).transColor
SkipGIFBlocks __GIFData(Index).file
__GIF_SkipBlocks __GIFData(Index).file
CASE ELSE
'Unsupported extension Label
GOTO LoadError
@ -251,7 +253,7 @@ $IF GIFPLAY_BAS = UNDEFINED THEN
REDIM _PRESERVE __GIFFrameData(0 TO __TotalGIFFrames) AS __GIFFrameDataType
__GIFData(Index).IsPlaying = FALSE
OpenGif = TRUE
GIF_Open = TRUE
EXIT FUNCTION
LoadError:
@ -265,26 +267,26 @@ $IF GIFPLAY_BAS = UNDEFINED THEN
END FUNCTION
FUNCTION GetGifIndex& (ID AS LONG)
FUNCTION __GIF_GetIndex& (ID AS LONG)
SHARED __GIFData() AS __GIFDataType
SHARED __TotalGIFLoaded AS LONG
DIM i AS LONG: FOR i = 1 TO __TotalGIFLoaded
IF __GIFData(i).ID = ID THEN
GetGifIndex = i
__GIF_GetIndex = i
EXIT FOR
END IF
NEXT i
END FUNCTION
SUB CloseGif (ID AS LONG)
SUB GIF_Close (ID AS LONG)
SHARED __GIFData() AS __GIFDataType
SHARED __GIFFrameData() AS __GIFFrameDataType
DIM i AS LONG, Index AS LONG
Index = GetGifIndex(ID)
Index = __GIF_GetIndex(ID)
IF Index = 0 THEN EXIT SUB
@ -303,7 +305,7 @@ $IF GIFPLAY_BAS = UNDEFINED THEN
END SUB
SUB SkipGIFBlocks (file AS INTEGER)
SUB __GIF_SkipBlocks (file AS INTEGER)
DIM byte~%%
DO
GET file, , byte~%% ' Block Size
@ -312,7 +314,7 @@ $IF GIFPLAY_BAS = UNDEFINED THEN
END SUB
FUNCTION GetGifFrame& (Index AS LONG)
FUNCTION __GIF_GetFrame& (Index AS LONG)
SHARED __GIFData() AS __GIFDataType
SHARED __GIFFrameData() AS __GIFFrameDataType
@ -345,7 +347,7 @@ $IF GIFPLAY_BAS = UNDEFINED THEN
actualFrame& = _NEWIMAGE(__GIFData(Index).width, __GIFData(Index).height, 256)
_DEST img&
DecodeFrame __GIFData(Index), __GIFFrameData(frame)
__GIF_DecodeFrame __GIFData(Index), __GIFFrameData(frame)
_DEST actualFrame&
IF __GIFFrameData(frame).localColorTableFlag THEN
@ -380,11 +382,11 @@ $IF GIFPLAY_BAS = UNDEFINED THEN
_DEST prevDest
END IF
GetGifFrame& = __GIFFrameData(frame).addr
__GIF_GetFrame = __GIFFrameData(frame).addr
END FUNCTION
SUB DecodeFrame (gifdata AS __GIFDataType, __GIfFRAMEDATA AS __GIFFrameDataType)
SUB __GIF_DecodeFrame (gifdata AS __GIFDataType, __GIfFRAMEDATA AS __GIFFrameDataType)
DIM byte AS _UNSIGNED _BYTE
DIM prefix(4095), suffix(4095), colorStack(4095)
DIM startCodeSize AS INTEGER, clearCode AS INTEGER
@ -523,7 +525,7 @@ $IF GIFPLAY_BAS = UNDEFINED THEN
END SUB
FUNCTION LoadGIFOverlayImage&
FUNCTION __GIF_LoadOverlayImage&
CONST SIZE_GIFOVERLAYIMAGE_BMP_16506 = 16506
CONST COMP_GIFOVERLAYIMAGE_BMP_16506 = -1
CONST DATA_GIFOVERLAYIMAGE_BMP_16506 = _
@ -540,7 +542,7 @@ $IF GIFPLAY_BAS = UNDEFINED THEN
"HQu2IAVDJrIlq8uKd/8TmfxqrMT3v2ndBsm526v7X6v7n6v736vnH6rnX6rnnzI+HmYCeP5tBqeW8PnH63A8wOdfX4L0yUvm+ddQq4a78QokpVdw" + _
"N2rIY+nz70tYxZN431x3/g7v40msYmlQz7//BcxY2A4="
LoadGIFOverlayImage = _LOADIMAGE(Base64_LoadResourceString(DATA_GIFOVERLAYIMAGE_BMP_16506, SIZE_GIFOVERLAYIMAGE_BMP_16506, COMP_GIFOVERLAYIMAGE_BMP_16506), 32, "memory")
__GIF_LoadOverlayImage = _LOADIMAGE(Base64_LoadResourceString(DATA_GIFOVERLAYIMAGE_BMP_16506, SIZE_GIFOVERLAYIMAGE_BMP_16506, COMP_GIFOVERLAYIMAGE_BMP_16506), 32, "memory")
END FUNCTION
'$INCLUDE:'Base64.bas'

View file

@ -2,9 +2,12 @@
'# Animated GIF decoder v1.0 #
'# By Zom-B #
'# #
'# http://www.qb64.org/wiki/GIF_Images #
'# https://qb64phoenix.com/qb64wiki/index.php/GIF_Images #
'#######################################################################################
'Adapted for use with InForm's PictureBox controls by @FellippeHeitor
'
' Adapted for use with InForm's PictureBox controls by @FellippeHeitor
'
' Refactored and enhanced by a740g to use include guards, conditional compiles and cleaner API
$IF GIFPLAY_BI = UNDEFINED THEN
$LET GIFPLAY_BI = TRUE
@ -30,7 +33,7 @@ $IF GIFPLAY_BI = UNDEFINED THEN
numColors AS _UNSIGNED INTEGER
palette AS STRING * 768
firstFrame AS LONG
totalFrames AS LONG
totalFrames AS _UNSIGNED LONG
IsPlaying AS _BYTE
Frame AS LONG
LoadedFrames AS LONG

View file

@ -2,11 +2,11 @@
' These basically emulate the legacy InForm MessageBox routines
' All it does is calls the new QB64-PE _MESSAGEBOX$ function
'$INCLUDE:'MessageBox.bi'
$IF MESSAGEBOX_BAS = UNDEFINED THEN
$LET MESSAGEBOX_BAS = TRUE
'$INCLUDE:'MessageBox.bi'
FUNCTION MessageBox& (message AS STRING, caption AS STRING, setup AS LONG)
DIM dialogType AS STRING
@ -69,9 +69,9 @@ $IF MESSAGEBOX_BAS = UNDEFINED THEN
END SELECT
END IF
DIM __caption AS STRING
DIM __caption AS STRING: __caption = caption
IF caption = "" THEN
$IF INFORM_BI = DEFINED THEN
IF __UI_CurrentTitle <> "" THEN
__caption = __UI_CurrentTitle
ELSEIF _TITLE$ <> "" THEN
@ -79,9 +79,13 @@ $IF MESSAGEBOX_BAS = UNDEFINED THEN
ELSE
__caption = COMMAND$(0)
END IF
ELSE
__caption = caption
END IF
$ELSE
IF _TITLE$ <> "" THEN
__caption = _TITLE$
ELSE
__caption = COMMAND$(0)
END IF
$END IF
_DELAY 0.2 ' delay a bit so that the interface can redraw before the messagebox kicks in
DIM returnValue AS LONG: returnValue = _MESSAGEBOX(__caption, message, dialogType, iconType, defaultButton)

View file

@ -4,6 +4,9 @@
': https://github.com/FellippeHeitor/InForm
'-----------------------------------------------------------
DEFLNG A-Z
OPTION _EXPLICIT
': Controls' IDs: ------------------------------------------------------------------
DIM SHARED gifplaySample AS LONG
DIM SHARED PictureBox1 AS LONG
@ -13,11 +16,11 @@ DIM SHARED PlayBT AS LONG
': External modules: ---------------------------------------------------------------
'$INCLUDE:'../../InForm/InForm.bi'
'$INCLUDE:'../../InForm/extensions/GIFPlay.bi'
'$INCLUDE:'../../InForm/extensions/MessageBox.bi'
'$INCLUDE:'GIFPlaySample.frm'
': Event procedures: ---------------------------------------------------------------
SUB __UI_BeforeInit
END SUB
SUB __UI_OnLoad
@ -25,7 +28,7 @@ SUB __UI_OnLoad
END SUB
SUB __UI_BeforeUpdateDisplay
UpdateGif PictureBox1
GIF_Update PictureBox1
END SUB
SUB __UI_BeforeUnload
@ -38,9 +41,9 @@ SUB __UI_Click (id AS LONG)
CASE LoadBT
'file 'globe.gif' comes from:
'https://en.wikipedia.org/wiki/GIF#/media/File:Rotating_earth_(large).gif
IF OpenGif(PictureBox1, "globe.gif") THEN
IF GIF_Open(PictureBox1, "globe.gif") THEN
Control(PlayBT).Disabled = False
IF TotalFrames(PictureBox1) > 1 THEN
IF GIF_GetTotalFrames(PictureBox1) > 1 THEN
Caption(PlayBT) = "Play"
ELSE
Caption(PlayBT) = "Static gif"
@ -49,18 +52,18 @@ SUB __UI_Click (id AS LONG)
Caption(LoadBT) = "globe.gif loaded"
Control(LoadBT).Disabled = True
ELSE
_DELAY 0.2: _MESSAGEBOX "GIFPlay Sample", "File 'globe.gif' could not be found.", "error"
MessageBox "File 'globe.gif' could not be found.", "", MsgBox_Exclamation
END IF
CASE PlayBT
IF GifIsPlaying(PictureBox1) THEN
PauseGif PictureBox1
IF GIF_IsPlaying(PictureBox1) THEN
GIF_Pause PictureBox1
Caption(PlayBT) = "Play"
ELSE
PlayGif PictureBox1
GIF_Play PictureBox1
Caption(PlayBT) = "Pause"
END IF
CASE PictureBox1
HideGifOverlay PictureBox1
GIF_HideOverlay PictureBox1
END SELECT
END SUB
@ -97,3 +100,4 @@ END SUB
'$INCLUDE:'../../InForm/InForm.ui'
'$INCLUDE:'../../InForm/xp.uitheme'
'$INCLUDE:'../../InForm/extensions/GIFPlay.bas'
'$INCLUDE:'../../InForm/extensions/MessageBox.bas'