FE 'tkGooie' Utilities

'IMAGEtools' group

A Tk script to
Play Animated-GIF Files
named in a Playlist file

(a 'front end' for reading a 'playlist' file
of animated-GIF filenames and 'playing' the images
with a user-selected animated-GIF viewer program)
(FE = Freedom Environment)

FE Home Page > FE Downloads Page >

FE 'tkGooies' Description Page >

FE 'tkGooies' 'IMAGEtools' Page >

This
'Play Animated-GIF files in a Playlist file'
tkGooie Page

INTRODUCTION to Tcl-Tk script
'tkPlayAniGifFilesInPlaylist'

In 2013 December through 2014 March, at the Tclers' Wiki web site, wiki.tcl.tk, I contributed Tcl-Tk code to 'show' image files --- like JPEG, PNG, GIF, etc. --- code that can be seen on this site, on pages with titles like

and

And I contributed Tcl-Tk code, at the Tclers' Wiki, to 'play' media (video or audio) files --- and that code can be seen on this site, on pages with titles like

and

The two utilities for which 'Directory Hierarchy' is in the title were actually 'front-ends' for the 'find' command as well as for show/play programs.

The two utilities for which 'Playlist' is in the title were for showing/playing files in the order in which they are placed in a 'playlist' file.

    (The playlist file has a simple format that can be created with a text editor).

Soon after those code contributions, I realized that I could have some use for a similar pair of utilities --- 'find' and 'playlist' --- to play batches of animated GIF files.

On my (Linux) computers, I have a couple of 'light-weight' players for animated GIF files:

  • ImageMagick 'animate'

    and

  • the 'gifview' program that usually comes packaged with the 'gifsicle' utility that can be used to make animated GIF files.

I decided to make a 'playlist' utility for animated-GIF files first.

    (I will tackle the 'find' front end for batch-selecting-and-playing animated-GIF files --- in a directory hierarchy --- later.)

---

THE GOALS

My goals for the Tcl-Tk script were:

  • Provide a GUI for selecting a 'playlist' of animated-GIF files.

  • Allow the user to select an animated-GIF 'player' program from among multiple choices.

  • Since animated GIF files are ordinarily rather small in frame size (typically no more than about 300 pixels by 200 pixels), allow the user to play multiple animated-GIFs at a time --- placed in a 'grid' on the monitor screen.

  • provide a 'Launch' button to start showing the animated-GIFs, in the order of the filenames within the playlist file.

  • provide a 'Stop' button for 'interrupting' the display of a (long) sequence of animated-GIFs.

  • like on the four utilties listed above for static-image files and 'media' files, provide 'Count' and 'List' buttons on the GUI --- to allow for quickly counting and displaying the filenames of the 'aniGIF' files in the playlist file.


THE GUI LAYOUT

Like for the 'image-viewer' and 'media-player' utilities, I made a 'text-sketch' for the GUI for this 'play-aniGIF-files-in-a-playlist' utility:



  -------------------------------------------------------------------------------------
  Play *Animated GIF files* Files of a *Playlist* ...  with a choice of players
  [window title]
  -------------------------------------------------------------------------------------
  
  {Exit} {Help} {LaunchPlayerJob} {Next N} {Stop (no more files)}    {CountAniGIFs} {ShowAniGIFfilenames}
  
  Playlist Filename: _____________________________________________________  {Browse...}
  
  Player Program:  O 1 - ImageMagick 'animate'    O 2 - 'gifview'
  
  LayoutOnScreen: O 1x1(1)   O 2x1(2)  O 3x1(3)  O 2x2(4)  O 3x2(6)  O 3x3(9)  O 4x3(12)

  -------------------------------------------------------------------------------------

where

  SQUARE BRACKETS indicate a comment (not to be placed on the GUI).
  BRACES          indicate a Tk 'button' widget.
  UNDERSCORES     indicate a Tk 'entry' widget.
  A COLON         indicates that the text before the colon is on a 'label' widget.
  CAPITAL-O       indicates a Tk 'radiobutton' widget.
  CAPITAL-X       indicates a Tk 'checkbutton' widget (if any).


GUI Components

From the GUI 'sketch' above, it is seen that the GUI consists of about

  • 8 button widgets
  • 3 label widgets
  • 1 entry widget
  • 9 radiobutton widgets in 2 groups
  • 0 checkbutton widgets
  • 0 scale widgets
  • 0 listbox widgets

All but the 'label' widgets provide operating parameters/options in this utility.

Hence there are about 8 + 1 + 9 = 18 user-specifiable options via the GUI of this utility.


THE PLAYLIST FILE FORMAT

The intent of this utility is to allow the user to easily specify 'aniGIF' files to be viewed ... by building a simple 'playlist'.

The playlist file for this utility contains three types of lines:



  1 - Comment lines may be indicated in the file by a # sign
      in column 1.

  2 - Lines that contain a fully-qualified directory name
      or a 'dot' directory name.
      Examples: /data/aniGIFs/smileys or
                $env(HOME)/smileys    or
                /home/fred/smileys
                .                      or
                ./other
      These lines must start with either slash(/) or $ or dot(.).

      The dot can be used to represent the directory in which
      the playlist file lies. This useful when putting the playlist
      file in a directory of animated GIFs and using the dot to
      represent the directory of the aniGIF files. The directory of
      aniGIFs may have sub-directories of aniGIFs, as indicated
      by the last example. The dot allows for moving/copying the
      aniGIFs (with the playlist file) to different directories
      without having to change the internals of the playlist file.

  3 - Lines that contain a relative filename (relative to the
      previous directory name).
      Example: smiley_dancing_15x15_ani.gif

      These lines SHOULD NOT start with either slash(/) or $ or dot(.)
      or # --- although a # could be used to comment out a filename.


The first non-comment line of the playlist file should be a directory name.

There can be more than one directory name in the file.

Each directory-name-line is followed by names of image files that are in the specified directory.

A SAMPLE 'animated-GIFs' playlist file:



 # A description of this file could go here.
 #
 # First directory:  (arrow aniGIFs)
 $env(HOME)/aniGIFs/arrows
 arrow_down_137x120_ani.gif
 arrows3downward_153x205_ani.gif
 #
 # Second directory:  (smiley aniGIFs)
 $env(HOME)/aniGIFs/smileys
 smileyStar_doingToeTouches_100x100_transp_ani.gif
 smiley_blinking_120x120_transp_ani.gif
 smileysThree_jumpingRope_200x70_transp_ani.gif
 smileys_2onSeesaw_161x120_transp_ani.gif
 smileys_doing_the_wave_225x33_transp_ani.gif


FRONT END FOR OPTIONS FOR THE PLAYERS

This 'Front End' Tk script is essentially a 'front end' for the animated-GIF 'player' programs that are offered via radiobuttons on the GUI.

A second set of radiobuttons allow for placing several animated-GIFs on the screen at the same time.

In particular, the second set of radiobuttons allow the user to select a 'grid layout' for the 'player windows'.

Example Layouts (and number of player-windows at a time):

  • 1x1 (1)
  • 2x1 (2)
  • 3x1 (3)
  • 2x2 (4)
  • 3x2 (6)
  • 3x3 (9)
  • 4x3 (12)

In the future, if there are some options (of at least one of the aniGIF 'player' programs) that would seem nice to implement, additional widgets could be added to the GUI to support those choices.


Beautification of the GUI

I should point out here that I was not especially interested in coming up with a 'beautiful utility'.

I just wanted a utility that would make playing animated-GIFs an easy process (a small set of mouse clicks).

I am certainly interested in making pretty GUI's --- as I have indicated in Tk code experiments that I have posted at wiki.tcl.tk in pages titled

and

But at this time, I am satisfied to implement the 'functionality', and let the 'beauty' go for a later date (when I have more beauty tools/code at hand).


SCREENSHOT OF THE GUI

On the basis of the GUI-layout sketch above, I ended up with the GUI seen in the following image.

Note that there are two radiobuttons that allow you to choose the 'player' to use --- and about seven 'layout' radiobuttons.

---

TYPICAL SEQUENCE OF OPERATIONS WITH THE GUI

STEP 1:

You can use the 'Browse...' button to retrieve a full filename to the playlist filename entry field.

STEP 2:

Before clicking on the 'LaunchPlayerJob' button, you can change *radiobutton* settings as needed --- for

  • an 'aniGIF' player program

and

  • layout of player windows on the screen ---
    1x1(1), 2x1(2), 3x1(3), 2x2(4), 3x2(6), 3x3(9), or 4x3(12).

*THEN* click on the 'Launch' button.

STEP 3:

Clicking on the 'Next N' button causes the next N animated GIF files to be played.

The user has the option whether to close the currently running aniGIF 'player' windows before starting the next N windows.

STEP 4:

Keep doing 'Step 3', until all aniGIFs of the playlist are shown --- or until the 'Stop' button or 'Exit' button is used.

I tried to make the operation of the GUI rather general in the sense that the user CAN change the choice of 'player' and/or 'layout' at any point after a display of a set of N animated-GIFs.

---

The other buttons:

Clicking on the 'Stop' button sets a STOP variable to 1 rather than 0 (zero).

The next time the user clicks on the 'Next N' button, the user will be advised that no more of the aniGIF's in the playlist file will be shown.

After a 'Stop', the user can use the 'Launch' button to start another playing sequence via a playlist file.

---

Optionally, if you want to check the number or names of the image files specified in the 'playlist' file, after selecting a playlist file, click on the 'CountAniGIFs' or 'ShowAniGIFfilenames' button.

---

BREADTH AND FLEXIBILITY FEATURES OF THIS UTILITY

Note that this utility has the flexibility of a 'playlist' approach.

The user has the opportunity to SELECT exactly which files are to be shown and has the opportunity to choose the ORDER in which the selected image files are shown.

This utility is oriented toward showing image files which may be scattered throughout various PARENT DIRECTORIES and THEIR SUB-DIRECTORIES --- in a play-back ORDER DETERMINED BY THE USER (that is, determined by the order of directories and files in the playlist file).


DESCRIPTION OF THE CODE

Below, I provide the Tk script code for this 'play-aniGIFs-in-a-playlist' utility.

I follow my usual 'canonical' structure for Tk code for this Tk script:



  0) Set general window & widget parms (win-name, win-position,
     win-color-scheme, fonts-for-widgets, widget-geometry-parms,
     text-array-for-labels-etc, win-size-control).

  1a) Define ALL frames (and sub-frames, if any).
  1b) Pack   ALL frames and sub-frames.

  2) Define & pack all widgets in the frames, frame by frame.
              Within each frame, define ALL the widgets.
              Then pack the widgets.

  3) Define keyboard and mouse/touchpad/touch-sensitive-screen action
     BINDINGS, if needed.

  4) Define PROCS, if needed.

  5) Additional GUI initialization (typically with one or more of
     the procs), if needed.


This Tk coding structure is discussed in more detail on the page A Canonical Structure for Tk Code --- and variations.

This structure makes it easy for me to find code sections --- while generating and testing a Tk script, and when looking for code snippets to include in other scripts (code re-use).

I call your attention to step-zero.

One thing that I started doing in 2013 is use of a text-array --- named 'aRtext' --- for text in labels, buttons, and other widgets in the GUI.

This can make it easier for people to internationalize my scripts.

I will be using a text-array like this in most of my scripts in the future.


Experimenting with the GUI

As in all my scripts that use the 'pack' geometry manager (which is all of my 100-plus scripts, so far), I provide the four main 'pack' parameters --- '-side', '-anchor', '-fill', '-expand' --- on all of the 'pack' commands for the frames and widgets.

That helps me when I am initially testing the behavior of a GUI (the various widgets within it) as I resize the main window.

I think that I have used a pretty nice choice of the 'pack' parameters.

The label and button and radiobutton widgets stay fixed in size and relative-location if the window is re-sized --- while the entry widget expands/contracts horizontally whenever the window is re-sized horizontally.

You can experiment with the '-side', '-anchor', '-fill', and '-expand' parameters on the 'pack' commands for the various frames and widgets --- to get the widget behavior that you want.

---

Additional experimentation with the GUI:

You might want to change the fonts used for the various GUI widgets.

For example, you could change '-weight' from 'bold' to 'normal' --- or '-slant' from 'roman' to 'italic'.

Or change font families.

In fact, you may NEED to change the font families, because the families I used may not be available on your computer --- and the default font that the 'wish' interpreter chooses may not be very pleasing.

I use variables to set geometry parameters of widgets --- parameters such as border-widths and padding.

And I have included the '-relief' parameter on the definitions of frames and widgets.

Feel free to experiment with those 'appearance' parameters as well.

If you find the gray 'palette' of the GUI is not to your liking, you can change the value of the RGB parameter supplied to the 'tk_setPalette' command near the top of the code.

The following image is an example of setting a different 'palette' for the GUI and a different 'variable-width' font for the button and label widgets of the GUI.

Some features in the code

There are plenty of comments in the code to describe what most of the code-sections are doing.

You can look at the top of the PROCS section of the code to see a list of the procs used in this script, along with brief descriptions of how they are called and what they do.

The main procs are :



  'get_playlist_filename'    - called by the 'Browse...' button
                               next to the filename entry field.

  'count_aniGIF_files'       - called by the 'CountAniGIFs' button.

  'show_aniGIF_filenames'    - called by the 'ShowAniGIFfilenames' button.

  'set_player_command'       - called by button1-release bindings on the
                               'player' radiobuttons.

  'start_playing_aniGIF_files' - called by the 'LaunchPlayerJob' button.

  'play_nextN_aniGIF_files'    - called by the 'start_playing_aniGIF_files'
                                 proc and the 'Next N' button.

  'set_window_positions'     - called by 'play_nextN_aniGIF_files' proc
                               to set the window positions according
                               to the *current* user-selected windows-layout.

  'popup_msgVarWithScroll'  - called by 'Help' button to show HELPtext var.
                                    Also called via the 'CountAniGIFs' and
                                    and 'ShowAniGIFfilenames' buttons.


Like for the 'show-images-of-a-playlist' and 'play-media-files-of-a-playlist' Tk GUI utilities, I used the following statement to allow the GUI to be expanded in the x-direction, but NOT the y-direction.

wm resizable . 1 0

---

One of the trickiest things about this GUI involved structuring the procs in such a way as to allow the user a lot of flexibility, such as

  • ability to change the 'player' after any display of N aniGIFs.

  • ability to change the 'layout' after any display of N aniGIFs.

  • ability to stop further display after any display of N aniGIFs --- and start displaying again --- with the same playlist or a different one.

---

In addition, there are some 'cute' features of the GUI.

For example, when the user clicks on a 'layout' radiobutton, the integer in the 'Next N' button changes accordingly.


A fervent hope

It is my hope that the copious comments in the code will help Tcl-Tk coding 'newbies' get started in making GUI's like this.

Without the comments, potential young Tcler's might be tempted to return to their iPhones and iPads and iPods --- to 'binge-watch' the last season of 'Breaking Bad'.


The Tcl-Tk CODE

Here is a link to CODE for the Tk script

'playAniGIFfilesInPlaylist_ FrontEnd.tk'.


INSTALLING THE SCRIPT:

This 'set of ONE script' could be put in a sub-directory of the user's home directory, such as

$HOME/apps/tkPlayAniGIFsInPlaylist

Then the user can use their desktop system (such as MATE or Gnome or KDE) to set up the Tk script as an icon on the desktop (or in a desktop 'panel').

Then, whenever the user wants to start the 'play-aniGIF-files-in-a-playlist' GUI, the user can click on the desktop icon to startup the Tk script.


SOME POSSIBLE ENHANCEMENTS

This Tk script adds another utility to my list of 'done' Tk scripts --- in the 'Front Ends' category.

I plan to work on a 'batch-find' script for animated-GIF files --- similar to the 'front end' scripts that I made for a combination of the 'find' command and a choice of image-viewers/media-players.

Also I plan to work on 'front ends' for 'mplayer', 'xrandr', 'ffmpeg', and several other programs.

But I may return to this 'play-aniGIFs-in-a-playlist' Tk script to provide some enhancements.

Additional options may be added to the GUI, via adding a few widgets, to allow for

  • scaling up/down the size of the playback windows

  • controlling the speed of the playback of animated GIF's

  • controlling the number of loops through the animated GIF's

and other playback options --- if at least one of the aniGIF 'players' supports the option.

I may change the way the 'Stop' button is implemented --- to provide more immediate feedback to the user that the playback has been stopped.

---

FEATURES & IDIOSYNCRACIES OF
THE 'animate' PLAYER

The 'man' page for the 'animate' command is about 120 lines long (about 2 pages).

There are about 70 possible COMMAND-LINE OPTIONS for 'animate', but the main option we use is '-geometry' --- to place the aniGIF-player windows on the screen --- for a user-selected 'layout'.

In the 'man help', there are no documented KEYBOARD CONTROLS that you can use when the 'animate' display window comes up --- for example, to pause-playing or to re-size the image. However ...

If you click on an 'animate' window, an ImageMagick menu GUI appears.

---

FEATURES & IDIOSYNCRACIES OF
THE 'gifview' PLAYER

The 'man' page for the 'gifview' command is about 150 lines long (about 2.5 pages).

Although the 'gifview' command (which is usually packaged with the 'gifsicle' command) does not have nearly as many COMMAND-LINE OPTIONS as the ImageMagick 'animate' command, the 'gifview' command may be handy to try if 'animate' fails to play an animated GIF file.

'gifview' has about a dozen COMMAND-LINE OPTIONS, but the main two that we use are:



   -a         to animate the GIF file -- rather than showing it in a
              default 'slideshow' mode

   --geometry +x+y   to place the various windows -- for a user-selected
                     'layout' of aniGIF-player windows on the screen.


'gifview' does not have any control options in a GUI. But there some KEYBOARD CONTROLS, including:



   q           Quit gifview.
   ESC         Stop the animation.
   Space or n  Go to the next frame.
   b or p      Go to the previous frame.
   r or <      Go to the first frame.
   >           Go to the last frame.
   s or a      Toggle between animation and slideshow mode.
   u           Toggle between normal and unoptimized mode.


IN CONCLUSION

As I have said on several other code-donation pages on this wiki ...

There's a lot to like about a utility that is 'free freedom' --- that is, no-cost and open-source so that you can modify/enhance/fix it without having to wait for someone else to do it for you (which may be never).

A BIG THANK YOU to Ousterhout for starting Tcl-Tk, and a BIG THANK YOU to the Tcl-Tk developers and maintainers who have kept the simply MAH-velous 'wish' interpreter going.


UPDATE 2014apr22

In using this utility, I found a few changes were advisable:

  • File existence check

    Added a 'file exists' check to proc 'play_nextN_aniGIF_files' --- to handle cases when there may be non-existent filenames or filenames with syntax errors in the playlist file.

  • Check return code from player program

    Added a 'RETcode' (return code) check to proc 'play_nextN_aniGIF_files' --- to handle cases where the player program cannot handle a specified file.

  • 'Relative' directory names

    Added the capability to use a dot (.) at the start of any directory name in the playlist file --- to represent the directory in which the playlist file lies.

    This useful when putting the playlist file in a directory of animated GIF files and we want to use the dot to represent the directory of the aniGIFs.

    The dot allows for moving/copying the aniGIF files (with the playlist file) to different directories without having to change the internals of the playlist file.

  • Changed a Key binding

    Changed <KeyPress> to <KeyRelease> in a binding on the playlist filename entry field.

The code above has been replaced with the updated code.

Bottom of this page for a utility to
Play Animated-GIF Files
named in a Playlist file

--- a utility in the FE 'tkGooies' system,
in the 'IMAGEtools' group.

To return to a previously visited web page location, click on the Back button of your web browser a sufficient number of times.

OR, use the History-list option of your web browser.

OR ...

< Go to Top of Page, above. >

Page history:

The code was created in 2014 --- and posted 2014 Mar 12 at http://wiki.tcl.tk/39518.

This FE web page was created 2014 May 13.
(as a backup and alternative to the wiki.tcl.tk page)

This page was changed 2015 Oct 05.
(Small changes.)

Page was changed 2019 Feb 25.
(Added css and javascript to try to handle text-size for smartphones, esp. in portrait orientation.)

Page was changed 2019 Jun 26.
(Specified image widths in percents to size the images according to width of the browser window.)

Page was changed 2024 Sep 04.
(Changed links to other web pages so they load in a separate window or tab so that this page remains available in its window or tab.)


NOTE:
The code here MAY BECOME more 'up-to-date' than the code posted on the Tcler's Wiki --- wiki.tcl-lang.org --- formerly wiki.tcl.tk.